Files
rn-app/components/ThemeDemo.tsx
2025-11-06 16:37:01 +08:00

233 lines
7.5 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 主题演示组件
*
* 展示所有主题颜色和组件在不同主题下的效果
*/
import React from 'react';
import { StyleSheet, View, Text, TouchableOpacity, ScrollView } from 'react-native';
import { ThemedText, ThemedView, useThemeColor } from './Themed';
import { useTheme, useSettingsActions } from '@/stores';
import { useHaptics } from '@/hooks';
export function ThemeDemo() {
const theme = useTheme();
const { setTheme } = useSettingsActions();
const haptics = useHaptics();
// 获取主题颜色
const primary = useThemeColor({}, 'primary');
const secondary = useThemeColor({}, 'secondary');
const success = useThemeColor({}, 'success');
const warning = useThemeColor({}, 'warning');
const error = useThemeColor({}, 'error');
const info = useThemeColor({}, 'info');
const border = useThemeColor({}, 'border');
const card = useThemeColor({}, 'card');
const textSecondary = useThemeColor({}, 'textSecondary');
const handleThemeChange = (newTheme: 'light' | 'dark' | 'auto') => {
haptics.selection();
console.log('🎨 Changing theme to:', newTheme);
setTheme(newTheme);
console.log('🎨 Theme colors after change:', { primary, secondary, background: card });
};
return (
<ThemedView style={styles.container}>
<ScrollView>
{/* 主题切换器 */}
<View style={styles.section}>
<ThemedText type="subtitle"></ThemedText>
<View style={styles.themeButtons}>
<TouchableOpacity
style={[
styles.themeButton,
{ borderColor: border },
theme === 'light' && { backgroundColor: primary },
]}
onPress={() => handleThemeChange('light')}
>
<Text style={[styles.themeButtonText, theme === 'light' && styles.activeButtonText]}>
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.themeButton,
{ borderColor: border },
theme === 'dark' && { backgroundColor: primary },
]}
onPress={() => handleThemeChange('dark')}
>
<Text style={[styles.themeButtonText, theme === 'dark' && styles.activeButtonText]}>
🌙
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.themeButton,
{ borderColor: border },
theme === 'auto' && { backgroundColor: primary },
]}
onPress={() => handleThemeChange('auto')}
>
<Text style={[styles.themeButtonText, theme === 'auto' && styles.activeButtonText]}>
🔄
</Text>
</TouchableOpacity>
</View>
<ThemedText style={styles.hint}>
: {theme === 'light' ? '浅色' : theme === 'dark' ? '深色' : '自动'}
</ThemedText>
</View>
{/* 文本样式 */}
<View style={styles.section}>
<ThemedText type="subtitle"></ThemedText>
<ThemedText type="title"> (Title)</ThemedText>
<ThemedText type="subtitle"> (Subtitle)</ThemedText>
<ThemedText type="defaultSemiBold"> (SemiBold)</ThemedText>
<ThemedText type="default"> (Default)</ThemedText>
<ThemedText type="link"> (Link)</ThemedText>
</View>
{/* 颜色展示 */}
<View style={styles.section}>
<ThemedText type="subtitle"></ThemedText>
<View style={styles.colorGrid}>
<View style={styles.colorItem}>
<View style={[styles.colorBox, { backgroundColor: primary }]} />
<ThemedText style={styles.colorLabel}>Primary</ThemedText>
</View>
<View style={styles.colorItem}>
<View style={[styles.colorBox, { backgroundColor: secondary }]} />
<ThemedText style={styles.colorLabel}>Secondary</ThemedText>
</View>
<View style={styles.colorItem}>
<View style={[styles.colorBox, { backgroundColor: success }]} />
<ThemedText style={styles.colorLabel}>Success</ThemedText>
</View>
<View style={styles.colorItem}>
<View style={[styles.colorBox, { backgroundColor: warning }]} />
<ThemedText style={styles.colorLabel}>Warning</ThemedText>
</View>
<View style={styles.colorItem}>
<View style={[styles.colorBox, { backgroundColor: error }]} />
<ThemedText style={styles.colorLabel}>Error</ThemedText>
</View>
<View style={styles.colorItem}>
<View style={[styles.colorBox, { backgroundColor: info }]} />
<ThemedText style={styles.colorLabel}>Info</ThemedText>
</View>
</View>
</View>
{/* 卡片示例 */}
<View style={styles.section}>
<ThemedText type="subtitle"></ThemedText>
<View style={[styles.card, { backgroundColor: card, borderColor: border }]}>
<ThemedText type="defaultSemiBold"></ThemedText>
<ThemedText style={{ color: textSecondary }}>
</ThemedText>
</View>
</View>
{/* 按钮示例 */}
<View style={styles.section}>
<ThemedText type="subtitle"></ThemedText>
<TouchableOpacity style={[styles.button, { backgroundColor: primary }]}>
<Text style={styles.buttonText}>Primary Button</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.button, { backgroundColor: secondary }]}>
<Text style={styles.buttonText}>Secondary Button</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.button, { backgroundColor: success }]}>
<Text style={styles.buttonText}>Success Button</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.button, { backgroundColor: error }]}>
<Text style={styles.buttonText}>Error Button</Text>
</TouchableOpacity>
</View>
</ScrollView>
</ThemedView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
},
section: {
marginBottom: 24,
},
themeButtons: {
flexDirection: 'row',
gap: 12,
marginTop: 12,
},
themeButton: {
flex: 1,
paddingVertical: 12,
paddingHorizontal: 16,
borderRadius: 8,
borderWidth: 1,
alignItems: 'center',
},
themeButtonText: {
fontSize: 14,
fontWeight: '600',
},
activeButtonText: {
color: '#FFFFFF',
},
hint: {
marginTop: 8,
fontSize: 12,
opacity: 0.7,
},
colorGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 16,
marginTop: 12,
},
colorItem: {
alignItems: 'center',
width: 80,
},
colorBox: {
width: 60,
height: 60,
borderRadius: 8,
marginBottom: 8,
},
colorLabel: {
fontSize: 12,
textAlign: 'center',
},
card: {
padding: 16,
borderRadius: 12,
borderWidth: 1,
marginTop: 12,
},
button: {
paddingVertical: 12,
paddingHorizontal: 24,
borderRadius: 8,
alignItems: 'center',
marginTop: 12,
},
buttonText: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: '600',
},
});