Files
rn-app/hooks/useTheme.ts
2025-11-06 16:37:01 +08:00

101 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
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.
/**
* 主题 Hooks
*
* 提供统一的主题访问接口
*/
import { useMemo } from 'react';
import { useColorScheme as useSystemColorScheme } from 'react-native';
import { useTheme as useThemeStore } from '@/stores';
import Colors from '@/constants/Colors';
/**
* 获取当前颜色方案light | dark
*
* 从 settingsStore 读取用户设置的主题
* 支持 'light' | 'dark' | 'auto' 三种模式
*/
export function useColorScheme(): 'light' | 'dark' {
const userTheme = useThemeStore();
const systemTheme = useSystemColorScheme();
// 如果用户选择了 'auto',则使用系统主题
if (userTheme === 'auto') {
return systemTheme === 'dark' ? 'dark' : 'light';
}
// 否则使用用户选择的主题
return userTheme;
}
/**
* 获取主题颜色
*
* @param props - 可选的自定义颜色 { light?: string; dark?: string }
* @param colorName - Colors 中定义的颜色名称
* @returns 当前主题对应的颜色值
*
* @example
* ```tsx
* const textColor = useThemeColor({}, 'text');
* const customColor = useThemeColor({ light: '#000', dark: '#fff' }, 'text');
* ```
*/
export function useThemeColor(
props: { light?: string; dark?: string },
colorName: keyof typeof Colors.light & keyof typeof Colors.dark
): string {
const theme = useColorScheme();
const colorFromProps = props[theme];
if (colorFromProps) {
return colorFromProps;
} else {
return Colors[theme][colorName];
}
}
/**
* 获取完整的主题颜色对象
*
* @returns 当前主题的所有颜色配置
*
* @example
* ```tsx
* const colors = useThemeColors();
* <View style={{ backgroundColor: colors.background }}>
* <Text style={{ color: colors.text }}>Hello</Text>
* </View>
* ```
*/
export function useThemeColors() {
const theme = useColorScheme();
return useMemo(() => {
return Colors[theme];
}, [theme]);
}
/**
* 获取主题相关的所有信息
*
* @returns 主题信息对象
*
* @example
* ```tsx
* const { theme, colors, isDark } = useThemeInfo();
* ```
*/
export function useThemeInfo() {
const theme = useColorScheme();
const colors = useThemeColors();
return useMemo(() => ({
theme,
colors,
isDark: theme === 'dark',
isLight: theme === 'light',
}), [theme, colors]);
}