Merge branch 'development' into 'main'
Merge development See merge request thschleicher/interaktive-systeme!6
This commit is contained in:
commit
0c07dcc714
12 changed files with 422 additions and 42 deletions
|
|
@ -3,33 +3,32 @@ import {StyleSheet, View} from "react-native"
|
||||||
|
|
||||||
import { FontAwesome } from "@expo/vector-icons";
|
import { FontAwesome } from "@expo/vector-icons";
|
||||||
import {useThemeColor} from "../hooks/hooks";
|
import {useThemeColor} from "../hooks/hooks";
|
||||||
import {color} from "ansi-fragments";
|
import React from "react";
|
||||||
|
|
||||||
export default function Layout() {
|
export default function Layout() {
|
||||||
const selectedColor: string = useThemeColor( "tabIconSelected");
|
// const selectedColor: string = useThemeColor( "tabIconSelected");
|
||||||
const defaultColor: string = useThemeColor("tabIconDefault");
|
// const defaultColor: string = useThemeColor("tabIconDefault");
|
||||||
const backgroundColor: string = useThemeColor("backgroundColor");
|
// const backgroundColor: string = useThemeColor("backgroundColor");
|
||||||
|
// const tabBarColor: string = useThemeColor("tabBarColor");
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
sceneContainer: {
|
sceneContainer: {
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: useThemeColor("backgroundColor"),
|
||||||
position: "absolute",
|
|
||||||
},
|
},
|
||||||
view: {
|
tabBar: {
|
||||||
backgroundColor: "red",
|
backgroundColor: useThemeColor("backgroundColor"),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const screenOptions = {
|
const screenOptions = {
|
||||||
tabBarActiveTintColor: selectedColor,
|
tabBarActiveTintColor: useThemeColor( "tabIconSelected"),
|
||||||
tabBarInactiveTintColor: defaultColor,
|
tabBarInactiveTintColor: useThemeColor("tabIconDefault"),
|
||||||
headerShown: false,
|
headerShown: false,
|
||||||
|
tabBarStyle: styles.tabBar,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs sceneContainerStyle={styles.sceneContainer} initialRouteName={"index"} screenOptions={{tabBarBackground: () => {
|
<Tabs sceneContainerStyle={styles.sceneContainer} initialRouteName={"index"} screenOptions={screenOptions}>
|
||||||
return <View style={styles.view}/>;
|
|
||||||
}}}>
|
|
||||||
<Tabs.Screen name="budget" options={
|
<Tabs.Screen name="budget" options={
|
||||||
{
|
{
|
||||||
tabBarLabel: "Budget",
|
tabBarLabel: "Budget",
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,75 @@
|
||||||
import { StyleSheet, View, Text } from 'react-native';
|
import { StyleSheet, View, Text, NativeSyntheticEvent, NativeScrollEvent } from 'react-native';
|
||||||
|
import { useThemeColor } from "../hooks/hooks";
|
||||||
|
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||||
|
import { ExpenseItem, Plus, Welcome, SearchBar } from '../components';
|
||||||
|
import { FlatList, TextInput } from 'react-native-gesture-handler';
|
||||||
|
import { useRef, useState } from 'react';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
|
||||||
<View style={styles.container}>
|
|
||||||
<Text style={styles.text}>Home</Text>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const [plusShow, setPlusShow] = useState(true);
|
||||||
|
const prevOffset = useRef(0);
|
||||||
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
|
color: useThemeColor("color"),
|
||||||
fontSize: 70,
|
fontSize: 70,
|
||||||
fontWeight: "bold"
|
fontWeight: "bold"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const profile = require("../assets/images/profile.jpg")
|
||||||
|
|
||||||
|
const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>)=>{
|
||||||
|
const currentOffset = event.nativeEvent.contentOffset.y >= 0 ? event.nativeEvent.contentOffset.y : 0
|
||||||
|
const isScrollingUp : boolean = currentOffset <= prevOffset.current;
|
||||||
|
const isTop : boolean = currentOffset === 0
|
||||||
|
prevOffset.current = currentOffset
|
||||||
|
setPlusShow(isScrollingUp || isTop)
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{id:"1",category: "Category 1", color: "blue", date:"01.01.2023 18:00", title:"1 Super fancy spending with long name that will not display", value: "€ 30,00"},
|
||||||
|
{id:"2",category: "Category 2", color: "red", date:"01.01.2023 18:00", title:"2 Super fancy spending", value: "€ 30,00"},
|
||||||
|
{id:"3",category: "Category 3", color: "green", date:"01.01.2023 18:00", title:"3 Super fancy spending", value: "€ 30,00"},
|
||||||
|
{id:"4",category: "Category 4", color: "orange", date:"01.01.2023 18:00", title:"4 Super fancy spending", value: "€ 30,00"},
|
||||||
|
{id:"5",category: "Category 1", color: "blue", date:"01.01.2023 18:00", title:"5 Super fancy spending", value: "€ 30,00"},
|
||||||
|
{id:"6",category: "Category 2", color: "red", date:"01.01.2023 18:00", title:"6 Super fancy spending with long name that will not display", value: "€ 30,00"},
|
||||||
|
{id:"7",category: "Category 3", color: "green", date:"01.01.2023 18:00", title:"7 Super fancy spending", value: "€ 30,00"},
|
||||||
|
{id:"8",category: "Category 4", color: "orange", date:"01.01.2023 18:00", title:"8 Super fancy spending", value: "€ 30,00"},
|
||||||
|
{id:"9",category: "Category 1", color: "blue", date:"01.01.2023 18:00", title:"9 Super fancy spending", value: "€ 30,00"},
|
||||||
|
{id:"10" ,category: "Category 2", color: "red", date:"01.01.2023 18:00", title:"10 Super fancy spending", value: "€ 30,00"},
|
||||||
|
{id:"11" ,category: "Category 3", color: "green", date:"01.01.2023 18:00", title:"11 Super fancy spending", value: "€ 30,00"},
|
||||||
|
{id:"12" ,category: "Category 4", color: "orange", date:"01.01.2023 18:00", title:"12 Super fancy spending", value: "€ 30,00"},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={{flex: 1}}>
|
||||||
|
{plusShow && <Plus/>}
|
||||||
|
{/* <Welcome name="My User" image={profile} onPress={()=>console.log("hello")}></Welcome> */}
|
||||||
|
|
||||||
|
<FlatList
|
||||||
|
data={data}
|
||||||
|
ListHeaderComponent={
|
||||||
|
<>
|
||||||
|
<Welcome name="My Dude" image={profile} onPress={()=>console.log("hello")}></Welcome>
|
||||||
|
<SearchBar placeholder='Type to Search...'></SearchBar>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
renderItem = {({item}) => <ExpenseItem category={item.category} color={item.color} date={item.date} title={item.title} value={item.value}/>}
|
||||||
|
keyExtractor={item => item.id}
|
||||||
|
ItemSeparatorComponent={()=><View style={{marginVertical: 5}}></View>}
|
||||||
|
onScroll={handleScroll}
|
||||||
|
scrollEventThrottle={20}
|
||||||
|
>
|
||||||
|
</FlatList>
|
||||||
|
</SafeAreaView>
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
BIN
assets/images/profile.jpg
Normal file
BIN
assets/images/profile.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 873 KiB |
50
components/common/customCard/CustomCard.tsx
Normal file
50
components/common/customCard/CustomCard.tsx
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { View, Text, StyleSheet, Platform } from 'react-native'
|
||||||
|
import React from 'react'
|
||||||
|
import { ViewProps } from 'react-native/Libraries/Components/View/ViewPropTypes'
|
||||||
|
import { useThemeColor } from '../../../hooks/hooks'
|
||||||
|
import { SHADOWS } from '../../../constants/theme'
|
||||||
|
|
||||||
|
function generateBoxShadowStyle(
|
||||||
|
xOffset: number,
|
||||||
|
yOffset: number,
|
||||||
|
shadowColorIos: string,
|
||||||
|
shadowOpacity: number,
|
||||||
|
shadowRadius: number,
|
||||||
|
elevation: number,
|
||||||
|
shadowColorAndroid: string
|
||||||
|
):void {
|
||||||
|
if(Platform.OS === 'ios'){
|
||||||
|
styles.boxShadow = {
|
||||||
|
shadowColor: shadowColorIos,
|
||||||
|
shadowOffset : {width: xOffset, height: yOffset},
|
||||||
|
shadowOpacity,
|
||||||
|
shadowRadius,
|
||||||
|
backgroundColor: useThemeColor("backgroundColor")
|
||||||
|
}
|
||||||
|
}else if (Platform.OS === 'android'){
|
||||||
|
styles.boxShadow = {
|
||||||
|
elevation: elevation,
|
||||||
|
shadowColor: shadowColorAndroid,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CustomCard(props : ViewProps) {
|
||||||
|
generateBoxShadowStyle(1, 1, '#171717', 0.2, 20, 10, '#171717')
|
||||||
|
return (
|
||||||
|
<View style={[styles.container, styles.boxShadow, props.style]}>
|
||||||
|
{props.children}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container:{
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "stretch",
|
||||||
|
alignContent: "space-between",
|
||||||
|
borderRadius: 20,
|
||||||
|
marginHorizontal: 10,
|
||||||
|
},
|
||||||
|
boxShadow: {},
|
||||||
|
})
|
||||||
28
components/common/plus/plus.tsx
Normal file
28
components/common/plus/plus.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { View, Text, ViewProps, StyleSheet } from 'react-native'
|
||||||
|
import { AntDesign } from '@expo/vector-icons'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const Plus = (props : ViewProps) => {
|
||||||
|
return (
|
||||||
|
<View style={[style.plus, props.style]}>
|
||||||
|
{props.children}
|
||||||
|
<AntDesign name='plus' color={"white"} size={20}></AntDesign>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const style = StyleSheet.create({
|
||||||
|
plus:{
|
||||||
|
position: "absolute",
|
||||||
|
right: 20,
|
||||||
|
bottom: 20,
|
||||||
|
zIndex: 1,
|
||||||
|
backgroundColor: "orange",
|
||||||
|
padding: 20,
|
||||||
|
borderRadius: 500,
|
||||||
|
height: 60,
|
||||||
|
width: 60,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: "center"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
export default Plus
|
||||||
68
components/common/searchBar/SearchBar.tsx
Normal file
68
components/common/searchBar/SearchBar.tsx
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
import { View, Text, ViewProps, StyleSheet, Button } from 'react-native'
|
||||||
|
import React from 'react'
|
||||||
|
import { TextInput, TouchableOpacity } from 'react-native-gesture-handler'
|
||||||
|
import { AntDesign } from '@expo/vector-icons';
|
||||||
|
import { useThemeColor } from '../../../hooks/hooks';
|
||||||
|
import { SIZES } from '../../../constants/theme';
|
||||||
|
|
||||||
|
type SearchBarProps = {placeholder: string} & ViewProps
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function SearchBar(props: SearchBarProps) {
|
||||||
|
const [isActive, setIsactive] = React.useState(false);
|
||||||
|
|
||||||
|
const backgroundColor = useThemeColor("backgroundColor");
|
||||||
|
const handleChange = (text:string) : void => {
|
||||||
|
if(text !== ""){
|
||||||
|
if(!isActive){
|
||||||
|
setIsactive(true)
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if(isActive){
|
||||||
|
setIsactive(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Handle textCancel
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<TextInput onChangeText = {handleChange} style={[{fontSize: SIZES.normal, height: "100%"}, styles.TextInput]} autoCorrect={false} keyboardType='web-search' placeholder={props.placeholder}></TextInput>
|
||||||
|
|
||||||
|
{isActive &&
|
||||||
|
<TouchableOpacity style={styles.cancel}>
|
||||||
|
<AntDesign size={15} name='closecircle'></AntDesign>
|
||||||
|
</TouchableOpacity>
|
||||||
|
}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
marginHorizontal: 10,
|
||||||
|
marginBottom: 20,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
height: 40,
|
||||||
|
backgroundColor: "red", //tochange
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 10
|
||||||
|
},
|
||||||
|
TextInput: {
|
||||||
|
flex: 1,
|
||||||
|
height: "100%",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
cancel:{
|
||||||
|
height: "100%",
|
||||||
|
width: 30,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems:"center",
|
||||||
|
}
|
||||||
|
})
|
||||||
71
components/home/Welcome/Welcome.tsx
Normal file
71
components/home/Welcome/Welcome.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { View, Text, ViewProps, Image, GestureResponderEvent } from 'react-native'
|
||||||
|
import React from 'react'
|
||||||
|
import { MARGINS, SIZES, SHADOWS } from '../../../constants/theme'
|
||||||
|
import { TouchableOpacity } from 'react-native-gesture-handler'
|
||||||
|
import { useThemeColor } from '../../../hooks/hooks'
|
||||||
|
|
||||||
|
type WelcomeProps = ViewProps & {name: string, image : any, onPress: () => void | undefined}
|
||||||
|
|
||||||
|
function formatDate(date: Date) : string {
|
||||||
|
const day = String(date.getDate()).padStart(2, '0')
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||||
|
const year = String(date.getFullYear())
|
||||||
|
return `${day}.${month}.${year}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimeOfDay(date: Date) : string {
|
||||||
|
const hour = date.getHours()
|
||||||
|
if(hour < 12){
|
||||||
|
return "morning"
|
||||||
|
} else if(hour >= 12 && hour < 18){
|
||||||
|
return "afternoon"
|
||||||
|
} else if(hour >= 18){
|
||||||
|
return "evening"
|
||||||
|
}
|
||||||
|
return "day"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function Welcome(props: WelcomeProps) {
|
||||||
|
const date = new Date()
|
||||||
|
const dateString = formatDate(date)
|
||||||
|
const timeOfDay = getTimeOfDay(date)
|
||||||
|
const onpress = props.onPress
|
||||||
|
|
||||||
|
const textcolor = useThemeColor("primaryText")
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{
|
||||||
|
marginVertical: 20,
|
||||||
|
marginHorizontal: MARGINS.normal,
|
||||||
|
}}>
|
||||||
|
<View style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between"
|
||||||
|
}}>
|
||||||
|
<TouchableOpacity onPress={onpress}>
|
||||||
|
<Image style={{
|
||||||
|
height: 60,
|
||||||
|
width: 60,
|
||||||
|
borderRadius: 200,
|
||||||
|
|
||||||
|
}} source={props.image} height={60} width={60} resizeMode='cover'></Image>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={{
|
||||||
|
fontSize: SIZES.xlarge,
|
||||||
|
color: textcolor
|
||||||
|
}}>{dateString}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{
|
||||||
|
paddingTop: 10,
|
||||||
|
}}>
|
||||||
|
<Text style={{
|
||||||
|
fontSize: SIZES.xlarge,
|
||||||
|
color: textcolor
|
||||||
|
}}>Good {timeOfDay}, {props.name}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
61
components/home/expenseItem/expenseItem.tsx
Normal file
61
components/home/expenseItem/expenseItem.tsx
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
import { View, Text, StyleSheet, ColorValue } from 'react-native'
|
||||||
|
import React from 'react'
|
||||||
|
import { useThemeColor } from '../../../hooks/hooks';
|
||||||
|
import CustomCard from "../../common/customCard/CustomCard";
|
||||||
|
import { SIZES } from '../../../constants/theme';
|
||||||
|
|
||||||
|
export type ExpenseItemProps = {color: ColorValue, category: string, title: string, date: string, value : string}
|
||||||
|
export default function ExpenseItem(itemProps : ExpenseItemProps) {
|
||||||
|
const textColor = useThemeColor("primaryText");
|
||||||
|
const backgroundColor = useThemeColor("backgroundColor")
|
||||||
|
return (
|
||||||
|
<CustomCard>
|
||||||
|
<View style={[styles.colorTip, {backgroundColor: itemProps.color}]}></View>
|
||||||
|
<View style={[styles.textSection, {backgroundColor: backgroundColor}]}>
|
||||||
|
<Text style={{
|
||||||
|
fontSize: SIZES.normal,
|
||||||
|
color: textColor
|
||||||
|
}} numberOfLines={1}>{itemProps.category}</Text>
|
||||||
|
<Text style={{
|
||||||
|
fontSize: SIZES.large,
|
||||||
|
color: textColor
|
||||||
|
}} numberOfLines={1}>{itemProps.title}</Text>
|
||||||
|
<Text style={{
|
||||||
|
fontSize: SIZES.small,
|
||||||
|
color: textColor
|
||||||
|
}} numberOfLines={1}>{itemProps.date}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[styles.valueSection, {backgroundColor: backgroundColor}]}>
|
||||||
|
<Text style={{
|
||||||
|
fontSize: SIZES.xxLarge,
|
||||||
|
color: textColor
|
||||||
|
}} numberOfLines={1}>{itemProps.value}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</CustomCard>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
colorTip: {
|
||||||
|
width: 20,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderBottomLeftRadius: 20,
|
||||||
|
},
|
||||||
|
|
||||||
|
textSection: {
|
||||||
|
flexDirection: "column",
|
||||||
|
alignContent: "space-between",
|
||||||
|
alignItems:"flex-start",
|
||||||
|
paddingLeft: 10,
|
||||||
|
flex:1,
|
||||||
|
alignSelf: "stretch",
|
||||||
|
paddingVertical: 5
|
||||||
|
},
|
||||||
|
valueSection: {
|
||||||
|
justifyContent:"center",
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
borderBottomRightRadius: 20,
|
||||||
|
}
|
||||||
|
})
|
||||||
15
components/index.jsx
Normal file
15
components/index.jsx
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
//home
|
||||||
|
import ExpenseItem from "./home/expenseItem/expenseItem"
|
||||||
|
import Welcome from "./home/Welcome/Welcome"
|
||||||
|
|
||||||
|
//common
|
||||||
|
import Plus from "./common/plus/plus"
|
||||||
|
import SearchBar from "./common/searchBar/SearchBar"
|
||||||
|
|
||||||
|
export {
|
||||||
|
ExpenseItem,
|
||||||
|
Welcome,
|
||||||
|
Plus,
|
||||||
|
SearchBar
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,20 +1,32 @@
|
||||||
export default {
|
export default {
|
||||||
light: {
|
light: {
|
||||||
|
primaryText: "#000000",
|
||||||
|
secondaryText: "#404040",
|
||||||
|
interactiveText: "#0645AD",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tabIconDefault: "gray",
|
tabIconDefault: "gray",
|
||||||
tabIconSelected: "orange",
|
tabIconSelected: "#ED7D31",
|
||||||
color: "orange",
|
color: "#000000",
|
||||||
contrastColor: "",
|
accentColor: "#ED7D31",
|
||||||
accentColor: "",
|
|
||||||
backgroundColor: "#ffffff",
|
backgroundColor: "#ffffff",
|
||||||
tabBarColor: "gray",
|
tabBarColor: "gray",
|
||||||
},
|
},
|
||||||
dark: {
|
dark: {
|
||||||
tabIconDefault: "gray",
|
// Text
|
||||||
tabIconSelected: "orange",
|
primaryText: "#FFFFFF",
|
||||||
color: "#1B9AAA",
|
secondaryText: "#B3B3B3",
|
||||||
contrastColor: "",
|
interactiveText: "#0645AD",
|
||||||
accentColor: "",
|
|
||||||
backgroundColor: "lightgray",
|
// Tabs
|
||||||
tabBarColor: "gray",
|
tabIconDefault: "#FFFFFF",
|
||||||
|
tabIconSelected: "#ED7D31",
|
||||||
|
|
||||||
|
//
|
||||||
|
color: "#FFFFFF",
|
||||||
|
accentColor: "#ED7D31",
|
||||||
|
backgroundColor: "#181818",
|
||||||
|
tabBarColor: "#121212",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
23
constants/theme.ts
Normal file
23
constants/theme.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
const SIZES = {
|
||||||
|
small: 12,
|
||||||
|
normal: 17,
|
||||||
|
large: 20,
|
||||||
|
xlarge: 25,
|
||||||
|
xxLarge: 30
|
||||||
|
}
|
||||||
|
|
||||||
|
const MARGINS = {
|
||||||
|
normal: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHADOWS = {
|
||||||
|
light: {
|
||||||
|
shadowColor: "#ADB7C3",
|
||||||
|
shadowRadius: 20,
|
||||||
|
elevation: 10,
|
||||||
|
shadowOpacity: 0.6,
|
||||||
|
shadowOffset: { width: 1, height: 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {SIZES, SHADOWS, MARGINS}
|
||||||
1
index.js
1
index.js
|
|
@ -1 +0,0 @@
|
||||||
import "expo-router/entry";
|
|
||||||
Reference in a new issue