- 导出 TranslationKey 类型,翻译 key 拼写错误编译期即报错 - zh.ts 使用 TranslationKey 约束,确保中英文 key 同步 - useMemo 包装 context value,避免不必要的全局重渲染 - ConfirmDialog confirmText 默认值改用 t() 而非硬编码英文 - SchemaProperties 递归组件改为 prop 传递 t,减少 useContext 调用 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 lines
1.6 KiB
TypeScript
47 lines
1.6 KiB
TypeScript
import { useTheme } from '../lib/theme';
|
|
import { useI18n, type TranslationKey } from '../lib/i18n';
|
|
|
|
const icons = {
|
|
light: (
|
|
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
<circle cx="12" cy="12" r="5" /><path d="M12 1v2m0 18v2M4.22 4.22l1.42 1.42m12.72 12.72l1.42 1.42M1 12h2m18 0h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" />
|
|
</svg>
|
|
),
|
|
dark: (
|
|
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
|
|
</svg>
|
|
),
|
|
system: (
|
|
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
<rect x="2" y="3" width="20" height="14" rx="2" /><path d="M8 21h8m-4-4v4" />
|
|
</svg>
|
|
),
|
|
};
|
|
|
|
const order: Array<'light' | 'dark' | 'system'> = ['light', 'dark', 'system'];
|
|
|
|
export default function ThemeToggle() {
|
|
const { theme, setTheme } = useTheme();
|
|
const { t } = useI18n();
|
|
|
|
return (
|
|
<div className="flex items-center gap-1 p-1 rounded-lg bg-bg-tertiary">
|
|
{order.map((key) => (
|
|
<button
|
|
key={key}
|
|
onClick={() => setTheme(key)}
|
|
title={t(`theme.${key}` as TranslationKey)}
|
|
className={`flex items-center justify-center w-8 h-7 rounded-md transition-all duration-150 ${
|
|
theme === key
|
|
? 'bg-bg-elevated text-text-primary shadow-sm'
|
|
: 'text-text-muted hover:text-text-secondary'
|
|
}`}
|
|
>
|
|
{icons[key]}
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|