Fix color schemes!
This commit is contained in:
parent
8c1021e1c9
commit
cbd50a811a
@ -2,7 +2,7 @@
|
|||||||
<style name="AppTheme" parent="Theme.EdgeToEdge">
|
<style name="AppTheme" parent="Theme.EdgeToEdge">
|
||||||
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="android:statusBarColor">#ffffff</item>
|
<item name="enforceNavigationBarContrast">false</item>
|
||||||
</style>
|
</style>
|
||||||
<style name="Theme.App.SplashScreen" parent="Theme.SplashScreen">
|
<style name="Theme.App.SplashScreen" parent="Theme.SplashScreen">
|
||||||
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
|
<item name="windowSplashScreenBackground">@color/splashscreen_background</item>
|
||||||
|
|||||||
@ -20,7 +20,10 @@ module.exports = {
|
|||||||
foregroundImage: "./assets/images/adaptive-icon.png",
|
foregroundImage: "./assets/images/adaptive-icon.png",
|
||||||
backgroundColor: "#ffffff"
|
backgroundColor: "#ffffff"
|
||||||
},
|
},
|
||||||
edgeToEdgeEnabled: true
|
edgeToEdgeEnabled: true,
|
||||||
|
"navigationBar": {
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
}
|
||||||
},
|
},
|
||||||
web: {
|
web: {
|
||||||
bundler: "metro",
|
bundler: "metro",
|
||||||
@ -29,6 +32,14 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
"expo-router",
|
"expo-router",
|
||||||
|
[
|
||||||
|
"react-native-edge-to-edge",
|
||||||
|
{
|
||||||
|
"android": {
|
||||||
|
"enforceNavigationBarContrast": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"expo-splash-screen",
|
"expo-splash-screen",
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,67 +1,101 @@
|
|||||||
import { Tabs } from 'expo-router';
|
import { Tabs } from 'expo-router';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Platform } from 'react-native';
|
import { Platform, useColorScheme, View } from 'react-native';
|
||||||
|
|
||||||
import { HapticTab } from '@/components/HapticTab';
|
import { HapticTab } from '@/components/HapticTab';
|
||||||
import { IconSymbol } from '@/components/ui/IconSymbol';
|
import { IconSymbol } from '@/components/ui/IconSymbol';
|
||||||
import TabBarBackground from '@/components/ui/TabBarBackground';
|
import TabBarBackground from '@/components/ui/TabBarBackground';
|
||||||
import { Colors } from '@/constants/Colors';
|
import { lightTheme, darkTheme } from '@/constants/Colors';
|
||||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
|
import { ThemedView } from '@/components/ThemedView';
|
||||||
|
|
||||||
export default function TabLayout() {
|
export default function TabLayout() {
|
||||||
const colorScheme = useColorScheme();
|
const colorScheme = useColorScheme();
|
||||||
|
const theme = colorScheme === 'dark' ? darkTheme : lightTheme;
|
||||||
|
const insets = useSafeAreaInsets();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<View style={{ flex: 1 }}>
|
||||||
screenOptions={{
|
<View
|
||||||
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
// Top status bar background
|
||||||
headerShown: false,
|
style={{
|
||||||
tabBarLabelPosition: 'below-icon',
|
position: 'absolute',
|
||||||
tabBarButton: HapticTab,
|
top: 0,
|
||||||
tabBarBackground: TabBarBackground,
|
left: 0,
|
||||||
tabBarStyle: Platform.select({
|
right: 0,
|
||||||
ios: {
|
height: insets.top,
|
||||||
// Use a transparent background on iOS to show the blur effect
|
backgroundColor: theme.colors.primary, // Or any custom color
|
||||||
position: 'absolute',
|
zIndex: 1000,
|
||||||
},
|
|
||||||
default: {},
|
|
||||||
}),
|
|
||||||
}}>
|
|
||||||
<Tabs.Screen
|
|
||||||
name="index"
|
|
||||||
options={{
|
|
||||||
title: 'Journey',
|
|
||||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="book" color={color} />,
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tabs.Screen
|
<View
|
||||||
name="calendar"
|
// Bottom navigation bar background
|
||||||
options={{
|
style={{
|
||||||
title: 'Calendar',
|
position: 'absolute',
|
||||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="calendar-today" color={color} />,
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
height: insets.bottom,
|
||||||
|
backgroundColor: theme.colors.primary, // Or any custom color
|
||||||
|
zIndex: 1000,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tabs.Screen
|
|
||||||
name="media"
|
<SafeAreaView style={{ flex: 1, paddingBottom: 5 }} edges={['top', 'left', 'right']}>
|
||||||
options={{
|
<ThemedView style={{ flex: 1 }}>
|
||||||
title: 'Media',
|
<Tabs
|
||||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="photo" color={color} />,
|
screenOptions={{
|
||||||
}}
|
tabBarActiveTintColor: theme.colors.primary,
|
||||||
/>
|
headerShown: false,
|
||||||
<Tabs.Screen
|
tabBarLabelPosition: 'below-icon',
|
||||||
name="atlas"
|
tabBarButton: HapticTab,
|
||||||
options={{
|
tabBarBackground: TabBarBackground,
|
||||||
title: 'Atlas',
|
tabBarStyle: Platform.select({
|
||||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="map" color={color} />,
|
ios: {
|
||||||
}}
|
// Use a transparent background on iOS to show the blur effect
|
||||||
/>
|
position: 'absolute',
|
||||||
<Tabs.Screen
|
},
|
||||||
name="today"
|
default: {},
|
||||||
options={{
|
}),
|
||||||
title: 'Today',
|
}}>
|
||||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="inbox" color={color} />,
|
<Tabs.Screen
|
||||||
}}
|
name="index"
|
||||||
/>
|
options={{
|
||||||
</Tabs>
|
title: 'Journey',
|
||||||
|
tabBarIcon: ({ color }) => <IconSymbol size={28} name="book" color={color} />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="calendar"
|
||||||
|
options={{
|
||||||
|
title: 'Calendar',
|
||||||
|
tabBarIcon: ({ color }) => <IconSymbol size={28} name="calendar-today" color={color} />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="media"
|
||||||
|
options={{
|
||||||
|
title: 'Media',
|
||||||
|
tabBarIcon: ({ color }) => <IconSymbol size={28} name="photo" color={color} />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="atlas"
|
||||||
|
options={{
|
||||||
|
title: 'Atlas',
|
||||||
|
tabBarIcon: ({ color }) => <IconSymbol size={28} name="map" color={color} />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="today"
|
||||||
|
options={{
|
||||||
|
title: 'Today',
|
||||||
|
tabBarIcon: ({ color }) => <IconSymbol size={28} name="inbox" color={color} />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tabs>
|
||||||
|
</ThemedView>
|
||||||
|
</SafeAreaView>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,35 +1,46 @@
|
|||||||
import { Image } from 'expo-image';
|
import { Image } from 'expo-image';
|
||||||
import { Platform, StyleSheet } from 'react-native';
|
import { Platform, StyleSheet, useColorScheme, View } from 'react-native';
|
||||||
|
|
||||||
import { HelloWave } from '@/components/HelloWave';
|
import { HelloWave } from '@/components/HelloWave';
|
||||||
import ParallaxScrollView from '@/components/ParallaxScrollView';
|
import ParallaxScrollView from '@/components/ParallaxScrollView';
|
||||||
import { ThemedText } from '@/components/ThemedText';
|
import { ThemedText } from '@/components/ThemedText';
|
||||||
import { ThemedView } from '@/components/ThemedView';
|
import { ThemedView } from '@/components/ThemedView';
|
||||||
import { Text } from 'react-native-paper';
|
import { List, Text, useTheme } from 'react-native-paper';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
|
import { DATA_DIRECTORY_URI_KEY } from '@/constants/Settings';
|
||||||
|
|
||||||
export default function HomeScreen() {
|
export default function HomeScreen() {
|
||||||
|
const [dataDirectoryUri, setDirectoryUri] = useState<string | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadDirectoryUri = async () => {
|
||||||
|
try {
|
||||||
|
const savedUri = await AsyncStorage.getItem(DATA_DIRECTORY_URI_KEY);
|
||||||
|
if (savedUri) {
|
||||||
|
setDirectoryUri(savedUri);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading directory URI:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loadDirectoryUri();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ParallaxScrollView
|
<ThemedView style={{ flex: 1, padding: 16 }}>
|
||||||
headerBackgroundColor={{ light: '#35C4E5', dark: '#35C4E5' }}
|
<ThemedText type="title">
|
||||||
headerImage={
|
|
||||||
<Image
|
|
||||||
source={require('@/assets/images/main-screen.png')}
|
|
||||||
style={styles.headerImage}
|
|
||||||
/>
|
|
||||||
}>
|
|
||||||
<Text variant="headlineLarge" style={styles.titleContainer}>
|
|
||||||
My Journey
|
My Journey
|
||||||
</Text>
|
</ThemedText>
|
||||||
</ParallaxScrollView>
|
<ThemedText>{theme.colors.primary}</ThemedText>
|
||||||
|
</ThemedView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
titleContainer: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 8,
|
|
||||||
},
|
|
||||||
stepContainer: {
|
stepContainer: {
|
||||||
gap: 8,
|
gap: 8,
|
||||||
marginBottom: 8,
|
marginBottom: 8,
|
||||||
|
|||||||
@ -5,8 +5,8 @@ import { List, Text } from 'react-native-paper';
|
|||||||
import { Directory, Paths } from 'expo-file-system/next';
|
import { Directory, Paths } from 'expo-file-system/next';
|
||||||
import { StorageAccessFramework } from 'expo-file-system';
|
import { StorageAccessFramework } from 'expo-file-system';
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
|
import { DATA_DIRECTORY_URI_KEY } from '@/constants/Settings';
|
||||||
|
|
||||||
const DATA_DIRECTORY_URI_KEY = 'dataDirectoryUri';
|
|
||||||
|
|
||||||
const prettyName = (uri: string | null) => {
|
const prettyName = (uri: string | null) => {
|
||||||
if (!uri) return null;
|
if (!uri) return null;
|
||||||
|
|||||||
@ -1,17 +1,19 @@
|
|||||||
import { DarkTheme, ThemeProvider } from '@react-navigation/native';
|
|
||||||
import { createDrawerNavigator } from '@react-navigation/drawer';
|
import { createDrawerNavigator } from '@react-navigation/drawer';
|
||||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||||
import { useFonts } from 'expo-font';
|
import { useFonts } from 'expo-font';
|
||||||
import { Stack } from 'expo-router';
|
import { Stack } from 'expo-router';
|
||||||
import { StatusBar } from 'expo-status-bar';
|
import { StatusBar } from 'expo-status-bar';
|
||||||
import 'react-native-reanimated';
|
import 'react-native-reanimated';
|
||||||
import { MD3LightTheme as DefaultTheme, PaperProvider } from 'react-native-paper';
|
import { PaperProvider } from 'react-native-paper';
|
||||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
import * as NavigationBar from 'expo-navigation-bar';
|
||||||
|
|
||||||
|
import { Platform, useColorScheme } from 'react-native';
|
||||||
|
import { lightTheme, darkTheme } from '@/constants/Colors';
|
||||||
import SettingsScreen from './SettingsScreen';
|
import SettingsScreen from './SettingsScreen';
|
||||||
import { IconSymbol } from '@/components/ui/IconSymbol';
|
import { IconSymbol } from '@/components/ui/IconSymbol';
|
||||||
import { TouchableOpacity } from 'react-native';
|
import { TouchableOpacity, View } from 'react-native';
|
||||||
import { Colors } from '@/constants/Colors';
|
|
||||||
import NullComponent from '@/components/NullComponent';
|
import NullComponent from '@/components/NullComponent';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
const Drawer = createDrawerNavigator();
|
const Drawer = createDrawerNavigator();
|
||||||
const RootStack = createNativeStackNavigator();
|
const RootStack = createNativeStackNavigator();
|
||||||
@ -26,6 +28,8 @@ function TabsNavigator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function DrawerNavigator() {
|
function DrawerNavigator() {
|
||||||
|
const colorScheme = useColorScheme();
|
||||||
|
const theme = colorScheme === 'dark' ? darkTheme : lightTheme;
|
||||||
return (
|
return (
|
||||||
<Drawer.Navigator>
|
<Drawer.Navigator>
|
||||||
<Drawer.Screen
|
<Drawer.Screen
|
||||||
@ -39,10 +43,10 @@ function DrawerNavigator() {
|
|||||||
<Drawer.Group
|
<Drawer.Group
|
||||||
screenOptions={{
|
screenOptions={{
|
||||||
headerShown: false,
|
headerShown: false,
|
||||||
drawerActiveTintColor: Colors.light.tint,
|
drawerActiveTintColor: theme.colors.primary,
|
||||||
drawerInactiveTintColor: Colors.light.text,
|
drawerInactiveTintColor: theme.colors.onSurfaceVariant,
|
||||||
drawerStyle: {
|
drawerStyle: {
|
||||||
backgroundColor: Colors.light.background,
|
backgroundColor: theme.colors.background,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -70,23 +74,22 @@ function DrawerNavigator() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const theme = {
|
|
||||||
...DefaultTheme,
|
|
||||||
colors: {
|
|
||||||
...DefaultTheme.colors,
|
|
||||||
primary: Colors.light.tint,
|
|
||||||
background: Colors.light.background,
|
|
||||||
text: Colors.light.text,
|
|
||||||
placeholder: Colors.light.tabIconDefault,
|
|
||||||
icon: Colors.light.icon,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function RootLayout() {
|
export default function RootLayout() {
|
||||||
const colorScheme = useColorScheme();
|
|
||||||
const [loaded] = useFonts({
|
const [loaded] = useFonts({
|
||||||
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
||||||
});
|
});
|
||||||
|
const colorScheme = useColorScheme();
|
||||||
|
const theme = colorScheme === 'dark' ? darkTheme : lightTheme;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (Platform.OS === 'android') {
|
||||||
|
const backgroundColor = theme.colors.primary;
|
||||||
|
const foregroundColor = colorScheme === 'dark' ? 'light' : 'dark';
|
||||||
|
|
||||||
|
NavigationBar.setStyle('light');
|
||||||
|
}
|
||||||
|
}, [colorScheme]);
|
||||||
|
|
||||||
|
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
return null;
|
return null;
|
||||||
@ -117,13 +120,13 @@ export default function RootLayout() {
|
|||||||
marginRight: 15,
|
marginRight: 15,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconSymbol name="close" size={24} color={Colors[colorScheme ?? 'light'].icon} />
|
<IconSymbol name="close" size={24} color={theme.colors.primary} />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
),
|
),
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</RootStack.Navigator>
|
</RootStack.Navigator>
|
||||||
<StatusBar style="auto" />
|
<StatusBar style={theme.dark ? 'light' : 'dark'} />
|
||||||
</PaperProvider>
|
</PaperProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
import { StyleSheet, Text, type TextProps } from 'react-native';
|
import { StyleSheet, Text, type TextProps } from 'react-native';
|
||||||
|
import { useTheme } from 'react-native-paper';
|
||||||
import { useThemeColor } from '@/hooks/useThemeColor';
|
|
||||||
|
|
||||||
export type ThemedTextProps = TextProps & {
|
export type ThemedTextProps = TextProps & {
|
||||||
lightColor?: string;
|
lightColor?: string;
|
||||||
@ -15,17 +14,24 @@ export function ThemedText({
|
|||||||
type = 'default',
|
type = 'default',
|
||||||
...rest
|
...rest
|
||||||
}: ThemedTextProps) {
|
}: ThemedTextProps) {
|
||||||
const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
|
const theme = useTheme();
|
||||||
|
|
||||||
|
// Only use override colors if provided
|
||||||
|
let color = theme.colors.onSurface; // default
|
||||||
|
if (lightColor || darkColor) {
|
||||||
|
color = theme.dark ? (darkColor || lightColor || color) : (lightColor || darkColor || color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case for link type
|
||||||
|
if (type === 'link') {
|
||||||
|
color = lightColor || darkColor || theme.colors.primary;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
style={[
|
style={[
|
||||||
{ color },
|
{ color },
|
||||||
type === 'default' ? styles.default : undefined,
|
styles[type],
|
||||||
type === 'title' ? styles.title : undefined,
|
|
||||||
type === 'defaultSemiBold' ? styles.defaultSemiBold : undefined,
|
|
||||||
type === 'subtitle' ? styles.subtitle : undefined,
|
|
||||||
type === 'link' ? styles.link : undefined,
|
|
||||||
style,
|
style,
|
||||||
]}
|
]}
|
||||||
{...rest}
|
{...rest}
|
||||||
@ -46,7 +52,7 @@ const styles = StyleSheet.create({
|
|||||||
title: {
|
title: {
|
||||||
fontSize: 32,
|
fontSize: 32,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
lineHeight: 32,
|
lineHeight: 40,
|
||||||
},
|
},
|
||||||
subtitle: {
|
subtitle: {
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { View, type ViewProps } from 'react-native';
|
import { View, type ViewProps } from 'react-native';
|
||||||
|
|
||||||
import { useThemeColor } from '@/hooks/useThemeColor';
|
import { useTheme } from 'react-native-paper';
|
||||||
|
|
||||||
export type ThemedViewProps = ViewProps & {
|
export type ThemedViewProps = ViewProps & {
|
||||||
lightColor?: string;
|
lightColor?: string;
|
||||||
@ -8,7 +8,8 @@ export type ThemedViewProps = ViewProps & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) {
|
export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) {
|
||||||
const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
|
const theme = useTheme();
|
||||||
|
const backgroundColor = theme.colors.background;
|
||||||
|
|
||||||
return <View style={[{ backgroundColor }, style]} {...otherProps} />;
|
return <View style={[{ backgroundColor }, style]} {...otherProps} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +1,74 @@
|
|||||||
/**
|
import { MD3LightTheme, MD3DarkTheme } from 'react-native-paper';
|
||||||
* Below are the colors that are used in the app. The colors are defined in the light and dark mode.
|
|
||||||
* There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const tintColorLight = '#0a7ea4';
|
// Your brand colors
|
||||||
const tintColorDark = '#fff';
|
const brandColors = {
|
||||||
|
primary: '#35C4E5',
|
||||||
|
primaryVariant: '#0051D5',
|
||||||
|
secondary: '#34C759',
|
||||||
|
secondaryVariant: '#248A3D',
|
||||||
|
background: '#F2F2F7',
|
||||||
|
surface: '#FFFFFF',
|
||||||
|
error: '#FF3B30',
|
||||||
|
onPrimary: '#FFFFFF',
|
||||||
|
onSecondary: '#FFFFFF',
|
||||||
|
onBackground: '#000000',
|
||||||
|
onSurface: '#000000',
|
||||||
|
onError: '#FFFFFF',
|
||||||
|
};
|
||||||
|
|
||||||
export const Colors = {
|
export const lightTheme = {
|
||||||
light: {
|
...MD3LightTheme,
|
||||||
text: '#11181C',
|
colors: {
|
||||||
background: '#fff',
|
...MD3LightTheme.colors,
|
||||||
tint: tintColorLight,
|
...brandColors,
|
||||||
icon: '#687076',
|
// Additional custom colors
|
||||||
tabIconDefault: '#687076',
|
accent: '#5856D6',
|
||||||
tabIconSelected: tintColorLight,
|
warning: '#FF9500',
|
||||||
},
|
success: '#34C759',
|
||||||
dark: {
|
info: '#007AFF',
|
||||||
text: '#ECEDEE',
|
textSecondary: '#666666',
|
||||||
background: '#151718',
|
border: '#E5E5EA',
|
||||||
tint: tintColorDark,
|
disabled: '#C7C7CC',
|
||||||
icon: '#9BA1A6',
|
|
||||||
tabIconDefault: '#9BA1A6',
|
|
||||||
tabIconSelected: tintColorDark,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const darkTheme = {
|
||||||
|
...MD3DarkTheme,
|
||||||
|
colors: {
|
||||||
|
...MD3DarkTheme.colors,
|
||||||
|
primary: '#0A84FF',
|
||||||
|
primaryVariant: '#0051D5',
|
||||||
|
secondary: '#30D158',
|
||||||
|
secondaryVariant: '#248A3D',
|
||||||
|
background: '#000000',
|
||||||
|
surface: '#1C1C1E',
|
||||||
|
error: '#FF453A',
|
||||||
|
onPrimary: '#FFFFFF',
|
||||||
|
onSecondary: '#000000',
|
||||||
|
onBackground: '#FFFFFF',
|
||||||
|
onSurface: '#FFFFFF',
|
||||||
|
onError: '#000000',
|
||||||
|
// Additional custom colors
|
||||||
|
accent: '#5E5CE6',
|
||||||
|
warning: '#FF9F0A',
|
||||||
|
success: '#30D158',
|
||||||
|
info: '#0A84FF',
|
||||||
|
textSecondary: '#AEAEB2',
|
||||||
|
border: '#38383A',
|
||||||
|
disabled: '#48484A',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
namespace ReactNativePaper {
|
||||||
|
interface ThemeColors {
|
||||||
|
accent: string;
|
||||||
|
warning: string;
|
||||||
|
success: string;
|
||||||
|
info: string;
|
||||||
|
textSecondary: string;
|
||||||
|
border: string;
|
||||||
|
disabled: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
export const DATA_DIRECTORY_URI_KEY = 'dataDirectoryUri';
|
||||||
@ -1,21 +1,19 @@
|
|||||||
/**
|
import { useTheme } from 'react-native-paper';
|
||||||
* Learn more about light and dark modes:
|
import { lightTheme, darkTheme } from '@/constants/Colors';
|
||||||
* https://docs.expo.dev/guides/color-schemes/
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Colors } from '@/constants/Colors';
|
|
||||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
|
||||||
|
|
||||||
export function useThemeColor(
|
export function useThemeColor(
|
||||||
props: { light?: string; dark?: string },
|
props: { light?: string; dark?: string },
|
||||||
colorName: keyof typeof Colors.light & keyof typeof Colors.dark
|
colorName?: keyof typeof lightTheme & keyof typeof darkTheme
|
||||||
) {
|
) {
|
||||||
const theme = useColorScheme() ?? 'light';
|
const theme = useTheme();
|
||||||
const colorFromProps = props[theme];
|
const colorScheme = theme.dark ? 'dark' : 'light';
|
||||||
|
const colorFromProps = props[colorScheme];
|
||||||
|
|
||||||
if (colorFromProps) {
|
if (colorFromProps) {
|
||||||
return colorFromProps;
|
return colorFromProps;
|
||||||
|
} else if (colorName) {
|
||||||
|
return theme[colorName];
|
||||||
} else {
|
} else {
|
||||||
return Colors[theme][colorName];
|
return theme.colors.onSurface; // fallback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
25
package-lock.json
generated
25
package-lock.json
generated
@ -27,6 +27,7 @@
|
|||||||
"expo-haptics": "~14.1.4",
|
"expo-haptics": "~14.1.4",
|
||||||
"expo-image": "~2.3.0",
|
"expo-image": "~2.3.0",
|
||||||
"expo-linking": "~7.1.5",
|
"expo-linking": "~7.1.5",
|
||||||
|
"expo-navigation-bar": "~4.2.6",
|
||||||
"expo-router": "~5.1.0",
|
"expo-router": "~5.1.0",
|
||||||
"expo-splash-screen": "~0.30.9",
|
"expo-splash-screen": "~0.30.9",
|
||||||
"expo-status-bar": "~2.2.3",
|
"expo-status-bar": "~2.2.3",
|
||||||
@ -36,6 +37,7 @@
|
|||||||
"react": "19.0.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "19.0.0",
|
"react-dom": "19.0.0",
|
||||||
"react-native": "0.79.3",
|
"react-native": "0.79.3",
|
||||||
|
"react-native-edge-to-edge": "1.6.0",
|
||||||
"react-native-gesture-handler": "~2.24.0",
|
"react-native-gesture-handler": "~2.24.0",
|
||||||
"react-native-paper": "^5.14.5",
|
"react-native-paper": "^5.14.5",
|
||||||
"react-native-reanimated": "~3.17.4",
|
"react-native-reanimated": "~3.17.4",
|
||||||
@ -9141,6 +9143,29 @@
|
|||||||
"invariant": "^2.2.4"
|
"invariant": "^2.2.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/expo-navigation-bar": {
|
||||||
|
"version": "4.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/expo-navigation-bar/-/expo-navigation-bar-4.2.6.tgz",
|
||||||
|
"integrity": "sha512-6phN9WXAAoEBWNhSLEnKuY+upQ9gV5CSCm8W66GOA47moglU5Ab3UDZ89hYZcfuIfsZR88/jx2KaF4VFCWGijg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-native/normalize-colors": "0.79.4",
|
||||||
|
"debug": "^4.3.2",
|
||||||
|
"react-native-edge-to-edge": "1.6.0",
|
||||||
|
"react-native-is-edge-to-edge": "^1.1.6"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"expo": "*",
|
||||||
|
"react": "*",
|
||||||
|
"react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/expo-navigation-bar/node_modules/@react-native/normalize-colors": {
|
||||||
|
"version": "0.79.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.79.4.tgz",
|
||||||
|
"integrity": "sha512-247/8pHghbYY2wKjJpUsY6ZNbWcdUa5j5517LZMn6pXrbSSgWuj3JA4OYibNnocCHBaVrt+3R8XC3VEJqLlHFg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/expo-router": {
|
"node_modules/expo-router": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/expo-router/-/expo-router-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/expo-router/-/expo-router-5.1.0.tgz",
|
||||||
|
|||||||
@ -46,7 +46,9 @@
|
|||||||
"react-native-web": "~0.20.0",
|
"react-native-web": "~0.20.0",
|
||||||
"react-native-webview": "13.13.5",
|
"react-native-webview": "13.13.5",
|
||||||
"expo-file-system": "~18.1.10",
|
"expo-file-system": "~18.1.10",
|
||||||
"@react-native-async-storage/async-storage": "2.1.2"
|
"@react-native-async-storage/async-storage": "2.1.2",
|
||||||
|
"expo-navigation-bar": "~4.2.6",
|
||||||
|
"react-native-edge-to-edge": "1.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.25.2",
|
"@babel/core": "^7.25.2",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user