feat: update

This commit is contained in:
2025-11-06 16:37:01 +08:00
parent c0d54b8513
commit 855f289579
59 changed files with 3398 additions and 572 deletions

View File

@@ -4,8 +4,7 @@ import { Link, Tabs } from 'expo-router';
import { Pressable } from 'react-native';
import Colors from '@/constants/Colors';
import { useColorScheme } from '@/components/useColorScheme';
import { useClientOnlyValue } from '@/components/useClientOnlyValue';
import { useColorScheme, useClientOnlyValue } from '@/hooks';
// You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
function TabBarIcon(props: {

View File

@@ -18,17 +18,23 @@ import {
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Image } from 'expo-image';
import { useRouter } from 'expo-router';
// 导入所有工具
// ✅ 扁平化导入:从根目录的各个模块导入
// 工具函数
import {
// 工具函数
Storage,
STORAGE_KEYS,
SessionStorage,
SESSION_KEYS,
formatDate,
formatRelativeTime,
formatChatTime,
formatChatTime
} from '@/utils';
// 状态管理
// 状态管理
import {
useUserStore,
useUser,
useIsLoggedIn,
@@ -36,24 +42,28 @@ import {
useTheme,
useLanguage,
useHapticsEnabled,
useSettingsActions,
useTenantStates,
useTenantInfo,
} from '@/stores';
// 验证规则
loginSchema,
type LoginFormData,
// 验证规则
import { loginSchema } from '@/schemas';
import type { LoginFormData } from '@/schemas';
// API 服务
authService,
appService,
// API 服务
import { authService } from '@/services';
// 自定义 Hooks
useDebounce,
useThrottle,
useHaptics,
} from '@/src';
// 自定义 Hooks
import { useDebounce, useThrottle, useHaptics } from '@/hooks';
// 主题组件
import { ThemeDemo } from '@/components/ThemeDemo';
export default function DemoScreen() {
console.log('=== DemoScreen 组件已渲染 ===');
const haptics = useHaptics();
const router = useRouter();
// 状态管理示例
const user = useUser();
@@ -61,13 +71,17 @@ export default function DemoScreen() {
const login = useUserStore((state) => state.login);
const logout = useUserStore((state) => state.logout);
const { tenantLoad } = useTenantStates();
const tenantInfo = useTenantInfo();
// 设置状态
const theme = useTheme();
const language = useLanguage();
const hapticsEnabled = useHapticsEnabled();
const setTheme = useSettingsStore((state) => state.setTheme);
const setLanguage = useSettingsStore((state) => state.setLanguage);
const setHapticsEnabled = useSettingsStore((state) => state.setHapticsEnabled);
const { setTheme, setLanguage, setHapticsEnabled } = useSettingsActions();
// const setTheme = useSettingsStore((state) => state.setTheme);
// const setLanguage = useSettingsStore((state) => state.setLanguage);
// const setHapticsEnabled = useSettingsStore((state) => state.setHapticsEnabled);
// 本地状态
const [searchText, setSearchText] = useState('');
@@ -75,6 +89,7 @@ export default function DemoScreen() {
const [loading, setLoading] = useState(false);
const [counter, setCounter] = useState(0);
const [storageValue, setStorageValue] = useState('');
const [sessionValue, setSessionValue] = useState('');
// 表单配置
const {
@@ -103,21 +118,6 @@ export default function DemoScreen() {
setSearchResults([`结果 1: ${text}`, `结果 2: ${text}`, `结果 3: ${text}`]);
}, 500);
useEffect(() => {
console.log('=== useEffect 开始执行 ===');
console.log('appService:', appService);
console.log('getPlatformData 方法:', appService.getPlatformData);
appService
.getPlatformData()
.then((res: any) => {
console.log('getPlatformData 成功:', res);
})
.catch((err: any) => {
console.error('getPlatformData 失败:', err);
});
}, []);
// 监听搜索文本变化
useEffect(() => {
debouncedSearch(searchText);
@@ -216,6 +216,59 @@ export default function DemoScreen() {
}
};
// SessionStorage 处理函数
const handleSaveToSession = () => {
try {
haptics.light();
const testData = {
formDraft: {
title: '草稿标题',
content: '这是一个表单草稿示例',
},
timestamp: new Date().toISOString(),
counter: Math.floor(Math.random() * 100),
};
SessionStorage.setObject(SESSION_KEYS.FORM_DRAFT, testData);
haptics.success();
Alert.alert('成功', '数据已保存到会话存储(应用重启后会丢失)');
} catch (error) {
haptics.error();
Alert.alert('失败', '保存失败');
}
};
const handleLoadFromSession = () => {
try {
haptics.light();
const data = SessionStorage.getObject<any>(SESSION_KEYS.FORM_DRAFT);
if (data) {
setSessionValue(JSON.stringify(data, null, 2));
haptics.success();
} else {
setSessionValue('暂无数据(会话存储为空)');
haptics.warning();
}
} catch (error) {
haptics.error();
Alert.alert('失败', '读取失败');
}
};
const handleClearSession = () => {
try {
haptics.light();
SessionStorage.clear();
setSessionValue('');
haptics.success();
Alert.alert('成功', '会话存储已清空');
} catch (error) {
haptics.error();
Alert.alert('失败', '清空失败');
}
};
// 主题切换
const handleThemeChange = () => {
haptics.selection();
@@ -238,6 +291,68 @@ export default function DemoScreen() {
<Text style={styles.title}>🎯 </Text>
<Text style={styles.subtitle}>使</Text>
{/* 页面导航 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>📱 </Text>
<TouchableOpacity
style={[styles.button, styles.primaryButton]}
onPress={() => {
haptics.light();
router.push('/test-page');
}}
>
<Text style={styles.buttonText}> </Text>
</TouchableOpacity>
<Text style={styles.infoText}>
tabs
</Text>
<TouchableOpacity
style={[styles.button, { backgroundColor: '#9333ea', marginTop: 12 }]}
onPress={() => {
haptics.light();
router.push('/theme-test');
}}
>
<Text style={styles.buttonText}>🎨 </Text>
</TouchableOpacity>
<Text style={styles.infoText}>
</Text>
<TouchableOpacity
style={[styles.button, { backgroundColor: '#06b6d4', marginTop: 12 }]}
onPress={() => {
haptics.light();
router.push('/theme-example');
}}
>
<Text style={styles.buttonText}>📚 </Text>
</TouchableOpacity>
<Text style={styles.infoText}>
使 CSS
</Text>
</View>
{/* 租户信息显示 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>🏢 </Text>
<Text style={styles.infoText}>
: {tenantLoad ? '✅ 已加载' : '❌ 未加载'}
</Text>
{tenantInfo && (
<>
<Text style={styles.infoText}>TID: {tenantInfo.tid || '无'}</Text>
<Text style={styles.infoText}>
: {tenantInfo.create_time || '无'}
</Text>
<Text style={styles.infoText}>
: {tenantInfo.domain_addr || '无'}
</Text>
</>
)}
</View>
{/* 用户状态显示 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>👤 (Zustand)</Text>
@@ -373,6 +488,39 @@ export default function DemoScreen() {
)}
</View>
{/* 会话存储示例 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>🔄 (SessionStorage)</Text>
<Text style={styles.infoText}>
</Text>
<View style={styles.buttonRow}>
<TouchableOpacity
style={[styles.button, styles.primaryButton, styles.thirdButton]}
onPress={handleSaveToSession}
>
<Text style={styles.buttonText}></Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.secondaryButton, styles.thirdButton]}
onPress={handleLoadFromSession}
>
<Text style={styles.buttonText}></Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.errorButton, styles.thirdButton]}
onPress={handleClearSession}
>
<Text style={styles.buttonText}></Text>
</TouchableOpacity>
</View>
{sessionValue && (
<View style={styles.codeBlock}>
<Text style={styles.codeText}>{sessionValue}</Text>
</View>
)}
</View>
{/* 日期格式化示例 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>📅 (Day.js)</Text>
@@ -383,6 +531,12 @@ export default function DemoScreen() {
<Text style={styles.infoText}>: {formatChatTime(Date.now())}</Text>
</View>
{/* 主题演示 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>🎨 </Text>
<ThemeDemo />
</View>
{/* 设置示例 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}> </Text>
@@ -598,6 +752,10 @@ const styles = StyleSheet.create({
halfButton: {
flex: 1,
},
thirdButton: {
flex: 1,
marginHorizontal: 4,
},
searchResults: {
marginTop: 12,
},

View File

@@ -9,7 +9,10 @@ import { Alert, Platform } from 'react-native';
import 'react-native-reanimated';
import { PaperProvider, MD3DarkTheme, MD3LightTheme } from 'react-native-paper';
import { useColorScheme } from '@/components/useColorScheme';
// ✅ 从 hooks 目录导入
import { useColorScheme } from '@/hooks';
// ✅ 从 stores 目录导入
import { restoreUserState, restoreSettingsState, useTenantActions } from '@/stores';
export {
// Catch any errors thrown by the Layout component.
@@ -29,6 +32,7 @@ export default function RootLayout() {
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
...FontAwesome.font,
});
const { requestTenantInfo } = useTenantActions();
// Expo Router uses Error Boundaries to catch errors in the navigation tree.
useEffect(() => {
@@ -41,6 +45,31 @@ export default function RootLayout() {
}
}, [loaded]);
// 恢复持久化状态并初始化应用数据
useEffect(() => {
async function initializeApp() {
try {
// 1. 恢复本地存储的状态
await Promise.all([restoreUserState(), restoreSettingsState()]);
// 2. 调用初始化接口(获取平台数据等)
if (__DEV__) {
console.log('🚀 Initializing app data...');
}
await requestTenantInfo();
if (__DEV__) {
console.log('✅ Platform data loaded:');
}
} catch (error) {
console.error('Failed to initialize app:', error);
// 初始化失败不应该阻止应用启动,只记录错误
}
}
initializeApp();
}, []);
// 检查热更新
useEffect(() => {
async function checkForUpdates() {

119
app/test-page.tsx Normal file
View File

@@ -0,0 +1,119 @@
import { StyleSheet, ScrollView } from 'react-native';
import { Stack, useRouter } from 'expo-router';
import { ThemedText, ThemedView } from '@/components';
/**
* 测试页面
*
* 这是一个独立的业务页面示例,不包含底部 tabs
*
* 特点:
* - 带有返回按钮的 header
* - 不包含底部导航栏
* - 可以作为业务页面的模板
*/
export default function TestPage() {
const router = useRouter();
return (
<>
{/* 配置页面 header */}
<Stack.Screen
options={{
title: '测试页面',
headerShown: true,
headerBackTitle: '返回',
}}
/>
<ThemedView style={styles.container}>
<ScrollView style={styles.scrollView}>
<ThemedView style={styles.content}>
<ThemedText type="title" style={styles.title}>
</ThemedText>
<ThemedText style={styles.description}>
tabs
</ThemedText>
<ThemedView style={styles.section}>
<ThemedText type="subtitle"></ThemedText>
<ThemedText style={styles.item}> header</ThemedText>
<ThemedText style={styles.item}> </ThemedText>
<ThemedText style={styles.item}> </ThemedText>
<ThemedText style={styles.item}> </ThemedText>
</ThemedView>
<ThemedView style={styles.section}>
<ThemedText type="subtitle">使</ThemedText>
<ThemedText style={styles.item}> </ThemedText>
<ThemedText style={styles.item}> </ThemedText>
<ThemedText style={styles.item}> </ThemedText>
<ThemedText style={styles.item}> </ThemedText>
</ThemedView>
<ThemedView style={styles.section}>
<ThemedText type="subtitle"></ThemedText>
<ThemedText style={styles.item}>
文件路径: app/test-page.tsx
</ThemedText>
<ThemedText style={styles.item}>
访: /test-page
</ThemedText>
<ThemedText style={styles.item}>
跳转方式: router.push('/test-page')
</ThemedText>
</ThemedView>
<ThemedView style={styles.infoBox}>
<ThemedText type="defaultSemiBold">💡 </ThemedText>
<ThemedText style={styles.infoText}>
screens/
app/
</ThemedText>
</ThemedView>
</ThemedView>
</ScrollView>
</ThemedView>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollView: {
flex: 1,
},
content: {
padding: 20,
},
title: {
marginBottom: 16,
},
description: {
marginBottom: 24,
lineHeight: 24,
},
section: {
marginBottom: 24,
},
item: {
marginTop: 8,
marginLeft: 8,
lineHeight: 24,
},
infoBox: {
padding: 16,
borderRadius: 8,
backgroundColor: 'rgba(0, 122, 255, 0.1)',
marginTop: 8,
},
infoText: {
marginTop: 8,
lineHeight: 22,
},
});

259
app/theme-example.tsx Normal file
View File

@@ -0,0 +1,259 @@
/**
* 主题系统使用示例
*
* 展示四种不同的主题样式使用方式
*/
import { ScrollView, View, Text, TouchableOpacity } from 'react-native';
import { Stack } from 'expo-router';
import {
useColorScheme,
useThemeColors,
useThemeInfo,
commonStyles,
createThemeStyles,
ThemedText,
ThemedView,
} from '@/theme';
// 方式 3: 创建自定义主题样式(推荐用于复杂组件)
const customStyles = createThemeStyles((colors) => ({
header: {
backgroundColor: colors.primary,
padding: 20,
borderRadius: 12,
marginBottom: 16,
},
headerText: {
color: '#FFFFFF',
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
},
section: {
backgroundColor: colors.card,
padding: 16,
borderRadius: 8,
marginBottom: 16,
borderWidth: 1,
borderColor: colors.border,
},
sectionTitle: {
color: colors.text,
fontSize: 18,
fontWeight: '600',
marginBottom: 12,
},
codeBlock: {
backgroundColor: colors.backgroundTertiary,
padding: 12,
borderRadius: 6,
marginTop: 8,
},
codeText: {
color: colors.textSecondary,
fontSize: 12,
fontFamily: 'monospace',
},
}));
export default function ThemeExampleScreen() {
const theme = useColorScheme();
const colors = useThemeColors();
const { isDark } = useThemeInfo();
const s = commonStyles[theme]; // 通用样式类
const custom = customStyles[theme]; // 自定义样式
return (
<>
<Stack.Screen
options={{
title: '主题系统示例',
headerStyle: {
backgroundColor: colors.background,
},
headerTintColor: colors.text,
}}
/>
<ScrollView style={s.containerPadded}>
{/* 自定义样式示例 */}
<View style={custom.header}>
<Text style={custom.headerText}>
使
</Text>
<Text style={[custom.headerText, { fontSize: 14, marginTop: 8 }]}>
: {theme} {isDark ? '🌙' : '☀️'}
</Text>
</View>
{/* 方式 1: 使用主题组件 */}
<View style={custom.section}>
<Text style={custom.sectionTitle}>
1: 使用主题组件
</Text>
<ThemedView style={{ padding: 12, borderRadius: 6 }}>
<ThemedText type="title"></ThemedText>
<ThemedText type="subtitle"></ThemedText>
<ThemedText></ThemedText>
</ThemedView>
<View style={custom.codeBlock}>
<Text style={custom.codeText}>
{`import { ThemedText, ThemedView } from '@/theme';
<ThemedView>
<ThemedText type="title">标题</ThemedText>
</ThemedView>`}
</Text>
</View>
</View>
{/* 方式 2: 使用通用样式类 */}
<View style={custom.section}>
<Text style={custom.sectionTitle}>
2: 使用通用样式类 CSS
</Text>
<View style={s.card}>
<Text style={s.textTitle}></Text>
<Text style={s.textSecondary}></Text>
<View style={s.spacingMd} />
<TouchableOpacity style={s.button}>
<Text style={s.buttonText}></Text>
</TouchableOpacity>
<View style={s.spacingSm} />
<TouchableOpacity style={s.buttonOutline}>
<Text style={s.buttonTextOutline}></Text>
</TouchableOpacity>
</View>
<View style={custom.codeBlock}>
<Text style={custom.codeText}>
{`import { useColorScheme, commonStyles } from '@/theme';
const theme = useColorScheme();
const s = commonStyles[theme];
<View style={s.card}>
<Text style={s.textTitle}>标题</Text>
<TouchableOpacity style={s.button}>
<Text style={s.buttonText}>按钮</Text>
</TouchableOpacity>
</View>`}
</Text>
</View>
</View>
{/* 方式 3: 使用自定义主题样式 */}
<View style={custom.section}>
<Text style={custom.sectionTitle}>
3: 使用自定义主题样式
</Text>
<View style={{ padding: 12 }}>
<Text style={{ color: colors.text }}>
header section 使
</Text>
</View>
<View style={custom.codeBlock}>
<Text style={custom.codeText}>
{`import { createThemeStyles } from '@/theme';
const styles = createThemeStyles((colors) => ({
header: {
backgroundColor: colors.primary,
padding: 20,
},
headerText: {
color: '#FFFFFF',
fontSize: 24,
},
}));
const theme = useColorScheme();
<View style={styles[theme].header}>
<Text style={styles[theme].headerText}>标题</Text>
</View>`}
</Text>
</View>
</View>
{/* 方式 4: 使用 Hooks + 内联样式 */}
<View style={custom.section}>
<Text style={custom.sectionTitle}>
4: 使用 Hooks +
</Text>
<View style={{
backgroundColor: colors.backgroundSecondary,
padding: 16,
borderRadius: 8,
}}>
<Text style={{ color: colors.text, fontSize: 16 }}>
使 useThemeColors()
</Text>
<View style={{ height: 12 }} />
<Text style={{ color: colors.textSecondary, fontSize: 14 }}>
</Text>
</View>
<View style={custom.codeBlock}>
<Text style={custom.codeText}>
{`import { useThemeColors } from '@/theme';
const colors = useThemeColors();
<View style={{
backgroundColor: colors.background,
padding: 16,
}}>
<Text style={{ color: colors.text }}>
动态文本
</Text>
</View>`}
</Text>
</View>
</View>
{/* 颜色展示 */}
<View style={custom.section}>
<Text style={custom.sectionTitle}>
</Text>
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 8 }}>
{Object.entries(colors).map(([key, value]) => (
<View
key={key}
style={{
backgroundColor: value as string,
padding: 8,
borderRadius: 6,
minWidth: 100,
borderWidth: 1,
borderColor: colors.border,
}}
>
<Text style={{
color: key.includes('background') || key.includes('card') || key.includes('input')
? colors.text
: '#FFFFFF',
fontSize: 10,
fontWeight: '600',
}}>
{key}
</Text>
<Text style={{
color: key.includes('background') || key.includes('card') || key.includes('input')
? colors.textSecondary
: '#FFFFFF',
fontSize: 8,
}}>
{value}
</Text>
</View>
))}
</View>
</View>
{/* 底部间距 */}
<View style={s.spacingXl} />
</ScrollView>
</>
);
}

317
app/theme-test.tsx Normal file
View File

@@ -0,0 +1,317 @@
import { StyleSheet, ScrollView, TouchableOpacity, View, Text, useColorScheme as useSystemColorScheme } from 'react-native';
import { Stack } from 'expo-router';
import { useState, useEffect, useMemo } from 'react';
import { useTheme, useSettingsActions } from '@/stores';
import { useHaptics } from '@/hooks';
import Colors from '@/constants/Colors';
export default function ThemeTestScreen() {
const currentTheme = useTheme();
const { setTheme } = useSettingsActions();
const haptics = useHaptics();
const systemColorScheme = useSystemColorScheme();
// 强制重新渲染的状态
const [renderKey, setRenderKey] = useState(0);
// 直接计算实际应用的主题 - 不使用 useColorScheme hook
const actualTheme: 'light' | 'dark' = useMemo(() => {
return currentTheme === 'auto'
? (systemColorScheme === 'dark' ? 'dark' : 'light')
: currentTheme;
}, [currentTheme, systemColorScheme]);
// 使用 useMemo 确保颜色对象在主题改变时重新计算
const colors = useMemo(() => {
console.log('🎨 Recalculating colors for theme:', actualTheme);
return Colors[actualTheme] as Record<string, any>;
}, [actualTheme]);
// 监听主题变化
useEffect(() => {
console.log('🎨 Theme changed:', { currentTheme, systemColorScheme, actualTheme, renderKey });
setRenderKey(prev => prev + 1);
}, [currentTheme, systemColorScheme, actualTheme]);
const handleThemeChange = (newTheme: 'light' | 'dark' | 'auto') => {
haptics.selection();
console.log('🎨 Changing theme to:', newTheme);
setTheme(newTheme);
};
return (
<>
<Stack.Screen
options={{
title: '主题测试',
headerStyle: {
backgroundColor: colors.background,
},
headerTintColor: colors.text,
}}
/>
<ScrollView
style={[styles.container, { backgroundColor: colors.background }]}
>
{/* 主题信息 */}
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}>
<Text style={[styles.title, { color: colors.text }]}>
</Text>
<Text style={[styles.infoText, { color: colors.textSecondary }]}>
: {currentTheme}
</Text>
<Text style={[styles.infoText, { color: colors.textSecondary }]}>
: {systemColorScheme || 'light'}
</Text>
<Text style={[styles.infoText, { color: colors.textSecondary }]}>
: {actualTheme}
</Text>
<Text style={[styles.infoText, { color: colors.textSecondary }]}>
: {renderKey}
</Text>
</View>
{/* 主题切换按钮 */}
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}>
<Text style={[styles.title, { color: colors.text }]}>
</Text>
<View style={styles.buttonRow}>
<TouchableOpacity
style={[
styles.themeButton,
{
backgroundColor: currentTheme === 'light' ? colors.primary : colors.backgroundTertiary,
borderColor: colors.border,
}
]}
onPress={() => handleThemeChange('light')}
>
<Text style={[
styles.buttonText,
{ color: currentTheme === 'light' ? '#fff' : colors.text }
]}>
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.themeButton,
{
backgroundColor: currentTheme === 'dark' ? colors.primary : colors.backgroundTertiary,
borderColor: colors.border,
}
]}
onPress={() => handleThemeChange('dark')}
>
<Text style={[
styles.buttonText,
{ color: currentTheme === 'dark' ? '#fff' : colors.text }
]}>
🌙
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.themeButton,
{
backgroundColor: currentTheme === 'auto' ? colors.primary : colors.backgroundTertiary,
borderColor: colors.border,
}
]}
onPress={() => handleThemeChange('auto')}
>
<Text style={[
styles.buttonText,
{ color: currentTheme === 'auto' ? '#fff' : colors.text }
]}>
🔄
</Text>
</TouchableOpacity>
</View>
</View>
{/* 文本颜色展示 */}
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}>
<Text style={[styles.title, { color: colors.text }]}>
</Text>
<Text style={[styles.colorText, { color: colors.text }]}>
Primary Text - {colors.text}
</Text>
<Text style={[styles.colorText, { color: colors.textSecondary }]}>
Secondary Text - {colors.textSecondary}
</Text>
<Text style={[styles.colorText, { color: colors.textTertiary }]}>
Tertiary Text - {colors.textTertiary}
</Text>
</View>
{/* 背景颜色展示 */}
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}>
<Text style={[styles.title, { color: colors.text }]}>
</Text>
<View style={[styles.colorBox, { backgroundColor: colors.background }]}>
<Text style={[styles.colorText, { color: colors.text }]}>
Primary Background - {colors.background}
</Text>
</View>
<View style={[styles.colorBox, { backgroundColor: colors.backgroundSecondary, borderWidth: 1, borderColor: colors.border }]}>
<Text style={[styles.colorText, { color: colors.text }]}>
Secondary Background - {colors.backgroundSecondary}
</Text>
</View>
<View style={[styles.colorBox, { backgroundColor: colors.backgroundTertiary }]}>
<Text style={[styles.colorText, { color: colors.text }]}>
Tertiary Background - {colors.backgroundTertiary}
</Text>
</View>
</View>
{/* 主题颜色展示 */}
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}>
<Text style={[styles.title, { color: colors.text }]}>
</Text>
<View style={styles.colorGrid}>
<View style={[styles.colorBox, { backgroundColor: colors.primary }]}>
<Text style={[styles.colorText, { color: '#fff' }]}>Primary - {colors.primary}</Text>
</View>
<View style={[styles.colorBox, { backgroundColor: colors.secondary }]}>
<Text style={[styles.colorText, { color: '#fff' }]}>Secondary - {colors.secondary}</Text>
</View>
<View style={[styles.colorBox, { backgroundColor: colors.success }]}>
<Text style={[styles.colorText, { color: '#fff' }]}>Success - {colors.success}</Text>
</View>
<View style={[styles.colorBox, { backgroundColor: colors.warning }]}>
<Text style={[styles.colorText, { color: '#fff' }]}>Warning - {colors.warning}</Text>
</View>
<View style={[styles.colorBox, { backgroundColor: colors.error }]}>
<Text style={[styles.colorText, { color: '#fff' }]}>Error - {colors.error}</Text>
</View>
<View style={[styles.colorBox, { backgroundColor: colors.info }]}>
<Text style={[styles.colorText, { color: '#fff' }]}>Info - {colors.info}</Text>
</View>
</View>
</View>
{/* UI 元素展示 */}
<View style={[styles.section, { backgroundColor: colors.backgroundSecondary }]}>
<Text style={[styles.title, { color: colors.text }]}>
UI
</Text>
<View style={[styles.card, { backgroundColor: colors.card, borderColor: colors.border }]}>
<Text style={[styles.cardText, { color: colors.text }]}>
</Text>
<Text style={[styles.cardSubtext, { color: colors.textSecondary }]}>
: {colors.card}
</Text>
</View>
<View style={[styles.input, { backgroundColor: colors.inputBackground, borderColor: colors.inputBorder }]}>
<Text style={[styles.inputText, { color: colors.textSecondary }]}>
</Text>
</View>
<View style={[styles.separator, { backgroundColor: colors.separator }]} />
<TouchableOpacity style={[styles.button, { backgroundColor: colors.buttonPrimary }]}>
<Text style={[styles.buttonText, { color: '#fff' }]}>
</Text>
</TouchableOpacity>
</View>
</ScrollView>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
section: {
margin: 16,
padding: 16,
borderRadius: 12,
},
title: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 16,
},
infoText: {
fontSize: 16,
marginBottom: 8,
},
buttonRow: {
flexDirection: 'row',
gap: 12,
},
themeButton: {
flex: 1,
paddingVertical: 12,
paddingHorizontal: 16,
borderRadius: 8,
borderWidth: 2,
alignItems: 'center',
},
buttonText: {
fontSize: 16,
fontWeight: '600',
},
colorText: {
fontSize: 14,
marginBottom: 8,
fontFamily: 'monospace',
},
colorBox: {
padding: 16,
borderRadius: 8,
marginBottom: 8,
alignItems: 'center',
},
colorGrid: {
gap: 8,
},
card: {
padding: 16,
borderRadius: 8,
borderWidth: 1,
marginBottom: 12,
},
cardText: {
fontSize: 16,
fontWeight: '600',
marginBottom: 4,
},
cardSubtext: {
fontSize: 12,
fontFamily: 'monospace',
},
input: {
padding: 12,
borderRadius: 8,
borderWidth: 1,
marginBottom: 12,
},
inputText: {
fontSize: 14,
},
separator: {
height: 1,
marginVertical: 12,
},
button: {
padding: 16,
borderRadius: 8,
alignItems: 'center',
},
});