refactor(frontend): 主题精简为双主题

- 移除与深海蓝视觉重复的 4 个开发者暗色主题(One Dark/Dracula/Tokyo Night/Catppuccin)
- 仅保留 跟随系统/深海蓝/明亮白;删除 5 段主题 CSS 与下架文案
- 旧主题存量值统一迁移到深海蓝,ThemePicker 改为扁平列表
This commit is contained in:
Logan.Li committed 2026-09-14 15:28:15 +08:00
1 parent 0563a29de1
commit 6c82ca9031
3 files changed
+48 -413

No files matched your search

+33 -47
View File
@@ -1,12 +1,8 @@
// 全局主题选择器 — Header / Login 共用,分组展示主流与开发者主题 // Logan.Li // 全局主题选择器 — Header / Login 共用,双主题 + 跟随系统 // Logan.Li
import { Check } from 'lucide-react'; import { Check } from 'lucide-react';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { import { DropdownMenuItem } from '@/components/ui/dropdown-menu';
DropdownMenuItem, import { THEME_OPTIONS, type ThemePreference } from '@/utils/theme';
DropdownMenuLabel,
DropdownMenuSeparator,
} from '@/components/ui/dropdown-menu';
import { THEME_GROUPS, type ThemePreference } from '@/utils/theme';
interface ThemePickerProps { interface ThemePickerProps {
value: ThemePreference; value: ThemePreference;
@@ -16,46 +12,36 @@ interface ThemePickerProps {
export function ThemePicker({ value, onChange }: ThemePickerProps) { export function ThemePicker({ value, onChange }: ThemePickerProps) {
return ( return (
<> <>
{THEME_GROUPS.map((group, gi) => ( {THEME_OPTIONS.map((option) => (
<div key={group.label}> <DropdownMenuItem
{gi > 0 && <DropdownMenuSeparator className="bg-[var(--border-default)]" />} key={option.id}
<DropdownMenuLabel className="text-xs dg-text-muted font-normal py-1"> className={cn(
{group.label} 'flex items-center gap-2.5 cursor-pointer transition-colors',
</DropdownMenuLabel> 'focus:bg-[var(--surface-hover)] focus:text-[var(--text-primary)]',
{group.options.map((option) => ( value === option.id
<DropdownMenuItem ? 'text-[var(--text-primary)]'
key={option.id} : 'dg-text-secondary',
className={cn( )}
'flex items-center gap-2.5 cursor-pointer transition-colors', onClick={() => onChange(option.id)}
'focus:bg-[var(--surface-hover)] focus:text-[var(--text-primary)]', >
value === option.id <span
? 'text-[var(--text-primary)]' className="w-3.5 h-3.5 rounded-full shrink-0"
: 'dg-text-secondary', style={{
)} background: option.primaryColor,
onClick={() => onChange(option.id)} boxShadow: '0 0 0 2px var(--surface-canvas)',
> }}
<span />
className="w-3.5 h-3.5 rounded-full shrink-0" <div className="flex-1 min-w-0">
style={{ <span className="text-sm font-medium">{option.name}</span>
background: option.primaryColor.startsWith('linear') <span className="block text-xs dg-text-muted truncate">
? option.primaryColor {option.description}
: option.primaryColor, </span>
boxShadow: '0 0 0 2px var(--surface-canvas)', </div>
}} {value === option.id && (
/> <Check className="h-4 w-4 text-[var(--brand)] shrink-0" />
<div className="flex-1 min-w-0"> )}
<span className="text-sm font-medium">{option.name}</span> </DropdownMenuItem>
<span className="block text-xs dg-text-muted truncate">
{option.description}
</span>
</div>
{value === option.id && (
<Check className="h-4 w-4 text-[var(--brand)] shrink-0" />
)}
</DropdownMenuItem>
))}
</div>
))} ))}
</> </>
); );
} }
+1 -335
View File
@@ -136,339 +136,6 @@
--skeleton-base: #f0f1f5; --skeleton-base: #f0f1f5;
--skeleton-highlight: #e8eaef; --skeleton-highlight: #e8eaef;
} }
/* ===== Theme 3: One Dark — Atom 暖灰 IDE(刻意与深海蓝蓝黑区分) // Logan.Li ===== */
[data-theme="one-dark"] {
--background: 220 9% 22%;
--foreground: 220 8% 82%;
--card: 220 8% 26%;
--card-foreground: 220 8% 82%;
--popover: 220 8% 24%;
--popover-foreground: 220 8% 82%;
--primary: 207 82% 66%;
--primary-foreground: 220 9% 18%;
--secondary: 220 8% 30%;
--secondary-foreground: 220 8% 82%;
--muted: 220 8% 30%;
--muted-foreground: 220 6% 52%;
--accent: 220 8% 30%;
--accent-foreground: 220 8% 82%;
--destructive: 355 65% 65%;
--destructive-foreground: 220 9% 18%;
--border: 220 7% 34%;
--input: 220 8% 28%;
--ring: 286 60% 67%;
--radius: 0.625rem;
--sidebar-background: 220 9% 17%;
--sidebar-foreground: 220 8% 78%;
--sidebar-primary: 207 82% 66%;
--sidebar-primary-foreground: 220 9% 18%;
--sidebar-accent: 220 8% 26%;
--sidebar-accent-foreground: 220 8% 82%;
--sidebar-border: 220 7% 28%;
--sidebar-ring: 286 60% 67%;
/* 更亮暖灰底 + 侧栏压暗,贴近 Atom 编辑器层次 */
--dg-bg-primary: #282c34;
--dg-bg-secondary: #2f343e;
--dg-bg-tertiary: #383e4a;
--dg-bg-hover: #3e4451;
--dg-bg-active: #4b5263;
--dg-border: #4b5263;
--dg-border-light: #353b45;
--dg-border-hover: #5c6370;
--dg-text-primary: #d7dae0;
--dg-text-secondary: #9da5b4;
--dg-text-muted: #6b7285;
/* Atom 语法高亮色 — 品牌渐变用紫→绿,非深海蓝 */
--dg-blue: #61afef;
--dg-green: #98c379;
--dg-red: #e06c75;
--dg-orange: #d19a66;
--dg-purple: #c678dd;
--dg-cyan: #56b6c2;
--dg-yellow: #e5c07b;
--dg-card-hover-border: rgba(198, 120, 221, 0.42);
--dg-gradient-start: #c678dd;
--dg-gradient-end: #98c379;
--dg-gradient-text-start: #c678dd;
--dg-gradient-text-end: #61afef;
--dg-input-focus-ring: rgba(198, 120, 221, 0.22);
--chart-grid: #4b5263;
--chart-axis: #6b7285;
--chart-tooltip-bg: #2f343e;
--chart-tooltip-border: #4b5263;
--shadow-card: 0 1px 3px rgba(0, 0, 0, 0.22), 0 0 0 1px rgba(198, 120, 221, 0.06);
--shadow-card-hover: 0 8px 28px rgba(0, 0, 0, 0.32), 0 0 0 1px rgba(152, 195, 121, 0.18);
--shadow-dropdown: 0 10px 36px rgba(0, 0, 0, 0.45);
--skeleton-base: #383e4a;
--skeleton-highlight: #4b5263;
--dg-overlay: color-mix(in srgb, #21252b 52%, transparent);
}
/* ===== Theme 4: Catppuccin Mocha ===== */
[data-theme="catppuccin"] {
--background: 240 21% 15%;
--foreground: 226 64% 88%;
--card: 240 21% 12%;
--card-foreground: 226 64% 88%;
--popover: 240 21% 12%;
--popover-foreground: 226 64% 88%;
--primary: 217 92% 76%;
--primary-foreground: 240 21% 15%;
--secondary: 237 16% 23%;
--secondary-foreground: 226 64% 88%;
--muted: 237 16% 23%;
--muted-foreground: 228 24% 72%;
--accent: 237 16% 23%;
--accent-foreground: 226 64% 88%;
--destructive: 343 81% 75%;
--destructive-foreground: 240 21% 15%;
--border: 237 16% 23%;
--input: 237 16% 23%;
--ring: 217 92% 76%;
--radius: 0.625rem;
--sidebar-background: 240 23% 9%;
--sidebar-foreground: 226 64% 85%;
--sidebar-primary: 217 92% 76%;
--sidebar-primary-foreground: 240 21% 15%;
--sidebar-accent: 237 16% 23%;
--sidebar-accent-foreground: 226 64% 88%;
--sidebar-border: 237 16% 23%;
--sidebar-ring: 217 92% 76%;
--dg-bg-primary: #1e1e2e;
--dg-bg-secondary: #181825;
--dg-bg-tertiary: #313244;
--dg-bg-hover: #45475a;
--dg-bg-active: #585b70;
--dg-border: #45475a;
--dg-border-light: #313244;
--dg-border-hover: #585b70;
--dg-text-primary: #cdd6f4;
--dg-text-secondary: #a6adc8;
--dg-text-muted: #7f849c;
--dg-blue: #89b4fa;
--dg-green: #a6e3a1;
--dg-red: #f38ba8;
--dg-orange: #fab387;
--dg-purple: #cba6f7;
--dg-cyan: #89dceb;
--dg-yellow: #f9e2af;
--dg-card-hover-border: rgba(137, 180, 250, 0.45);
--dg-gradient-start: #74c7ec;
--dg-gradient-end: #cba6f7;
--dg-gradient-text-start: #89b4fa;
--dg-gradient-text-end: #cba6f7;
--dg-input-focus-ring: rgba(137, 180, 250, 0.2);
--chart-grid: #45475a;
--chart-axis: #7f849c;
--chart-tooltip-bg: #181825;
--chart-tooltip-border: #45475a;
--shadow-card: 0 1px 3px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(137, 180, 250, 0.05);
--shadow-card-hover: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(137, 180, 250, 0.15);
--shadow-dropdown: 0 10px 40px rgba(0, 0, 0, 0.5);
--skeleton-base: #313244;
--skeleton-highlight: #45475a;
--dg-overlay: color-mix(in srgb, #11111b 55%, transparent);
}
/* ===== Theme 5: Dracula — 紫粉经典(高辨识度) // Logan.Li ===== */
[data-theme="dracula"] {
--background: 231 15% 18%;
--foreground: 60 30% 96%;
--card: 231 15% 20%;
--card-foreground: 60 30% 96%;
--popover: 231 15% 20%;
--popover-foreground: 60 30% 96%;
--primary: 265 89% 78%;
--primary-foreground: 231 15% 18%;
--secondary: 232 14% 31%;
--secondary-foreground: 60 30% 96%;
--muted: 232 14% 31%;
--muted-foreground: 231 8% 68%;
--accent: 232 14% 31%;
--accent-foreground: 60 30% 96%;
--destructive: 0 100% 67%;
--destructive-foreground: 231 15% 18%;
--border: 232 14% 31%;
--input: 232 14% 31%;
--ring: 265 89% 78%;
--radius: 0.625rem;
--sidebar-background: 231 16% 16%;
--sidebar-foreground: 60 25% 92%;
--sidebar-primary: 265 89% 78%;
--sidebar-primary-foreground: 231 15% 18%;
--sidebar-accent: 232 14% 28%;
--sidebar-accent-foreground: 60 30% 96%;
--sidebar-border: 232 14% 28%;
--sidebar-ring: 265 89% 78%;
--dg-bg-primary: #282a36;
--dg-bg-secondary: #313341;
--dg-bg-tertiary: #44475a;
--dg-bg-hover: #4d5066;
--dg-bg-active: #5a5d78;
--dg-border: #44475a;
--dg-border-light: #383a4a;
--dg-border-hover: #6272a4;
--dg-text-primary: #f8f8f2;
--dg-text-secondary: #bfbfb5;
--dg-text-muted: #8b8b80;
--dg-blue: #8be9fd;
--dg-green: #50fa7b;
--dg-red: #ff5555;
--dg-orange: #ffb86c;
--dg-purple: #bd93f9;
--dg-cyan: #8be9fd;
--dg-yellow: #f1fa8c;
--dg-card-hover-border: rgba(189, 147, 249, 0.5);
--dg-gradient-start: #bd93f9;
--dg-gradient-end: #ff79c6;
--dg-gradient-text-start: #bd93f9;
--dg-gradient-text-end: #ff79c6;
--dg-input-focus-ring: rgba(189, 147, 249, 0.25);
--chart-grid: #44475a;
--chart-axis: #8b8b80;
--chart-tooltip-bg: #313341;
--chart-tooltip-border: #44475a;
--shadow-card: 0 1px 3px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(189, 147, 249, 0.08);
--shadow-card-hover: 0 8px 32px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 121, 198, 0.2);
--shadow-dropdown: 0 10px 40px rgba(0, 0, 0, 0.55);
--skeleton-base: #44475a;
--skeleton-highlight: #4d5066;
--dg-overlay: color-mix(in srgb, #191a21 58%, transparent);
}
/* ===== Theme 6: Tokyo Night — 深蓝紫霓虹 // Logan.Li ===== */
[data-theme="tokyo-night"] {
--background: 235 25% 12%;
--foreground: 226 48% 86%;
--card: 234 26% 16%;
--card-foreground: 226 48% 86%;
--popover: 234 26% 16%;
--popover-foreground: 226 48% 86%;
--primary: 221 70% 72%;
--primary-foreground: 235 25% 12%;
--secondary: 233 23% 22%;
--secondary-foreground: 226 48% 86%;
--muted: 233 23% 22%;
--muted-foreground: 225 15% 58%;
--accent: 233 23% 22%;
--accent-foreground: 226 48% 86%;
--destructive: 350 65% 72%;
--destructive-foreground: 235 25% 12%;
--border: 233 20% 26%;
--input: 233 23% 22%;
--ring: 221 70% 72%;
--radius: 0.625rem;
--sidebar-background: 235 28% 10%;
--sidebar-foreground: 226 45% 84%;
--sidebar-primary: 221 70% 72%;
--sidebar-primary-foreground: 235 25% 12%;
--sidebar-accent: 233 23% 20%;
--sidebar-accent-foreground: 226 48% 86%;
--sidebar-border: 233 20% 24%;
--sidebar-ring: 221 70% 72%;
--dg-bg-primary: #1a1b26;
--dg-bg-secondary: #24283b;
--dg-bg-tertiary: #2f3549;
--dg-bg-hover: #3b4261;
--dg-bg-active: #414868;
--dg-border: #3b4261;
--dg-border-light: #292e42;
--dg-border-hover: #565f89;
--dg-text-primary: #c0caf5;
--dg-text-secondary: #9aa5ce;
--dg-text-muted: #737aa2;
--dg-blue: #7aa2f7;
--dg-green: #9ece6a;
--dg-red: #f7768e;
--dg-orange: #ff9e64;
--dg-purple: #bb9af7;
--dg-cyan: #7dcfff;
--dg-yellow: #e0af68;
--dg-card-hover-border: rgba(122, 162, 247, 0.45);
--dg-gradient-start: #7aa2f7;
--dg-gradient-end: #bb9af7;
--dg-gradient-text-start: #7aa2f7;
--dg-gradient-text-end: #7dcfff;
--dg-input-focus-ring: rgba(122, 162, 247, 0.22);
--chart-grid: #3b4261;
--chart-axis: #737aa2;
--chart-tooltip-bg: #24283b;
--chart-tooltip-border: #3b4261;
--shadow-card: 0 1px 3px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(122, 162, 247, 0.06);
--shadow-card-hover: 0 8px 32px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(187, 154, 247, 0.18);
--shadow-dropdown: 0 10px 40px rgba(0, 0, 0, 0.55);
--skeleton-base: #2f3549;
--skeleton-highlight: #3b4261;
--dg-overlay: color-mix(in srgb, #15161e 58%, transparent);
}
/* ===== Theme 7: Nord(保留兼容,已从选择器下架) // Logan.Li ===== */
[data-theme="nord"] {
--background: 220 16% 22%;
--foreground: 218 27% 92%;
--card: 220 16% 19%;
--card-foreground: 218 27% 92%;
--popover: 220 16% 19%;
--popover-foreground: 218 27% 92%;
--primary: 193 43% 67%;
--primary-foreground: 220 16% 22%;
--secondary: 220 16% 28%;
--secondary-foreground: 218 27% 92%;
--muted: 220 16% 28%;
--muted-foreground: 220 16% 56%;
--accent: 220 16% 28%;
--accent-foreground: 218 27% 92%;
--destructive: 354 42% 56%;
--destructive-foreground: 218 27% 92%;
--border: 220 16% 28%;
--input: 220 16% 28%;
--ring: 193 43% 67%;
--radius: 0.625rem;
--sidebar-background: 220 16% 18%;
--sidebar-foreground: 218 27% 88%;
--sidebar-primary: 193 43% 67%;
--sidebar-primary-foreground: 220 16% 22%;
--sidebar-accent: 220 16% 28%;
--sidebar-accent-foreground: 218 27% 92%;
--sidebar-border: 220 16% 28%;
--sidebar-ring: 193 43% 67%;
--dg-bg-primary: #2e3440;
--dg-bg-secondary: #3b4252;
--dg-bg-tertiary: #434c5e;
--dg-bg-hover: #4c566a;
--dg-bg-active: #5e6a7e;
--dg-border: #4c566a;
--dg-border-light: #434c5e;
--dg-border-hover: #5e6a7e;
--dg-text-primary: #eceff4;
--dg-text-secondary: #d8dee9;
--dg-text-muted: #a0a8b8;
--dg-blue: #81a1c1;
--dg-green: #a3be8c;
--dg-red: #bf616a;
--dg-orange: #d08770;
--dg-purple: #b48ead;
--dg-cyan: #88c0d0;
--dg-yellow: #ebcb8b;
--dg-card-hover-border: rgba(136, 192, 208, 0.45);
--dg-gradient-start: #5e81ac;
--dg-gradient-end: #88c0d0;
--dg-gradient-text-start: #88c0d0;
--dg-gradient-text-end: #81a1c1;
--dg-input-focus-ring: rgba(136, 192, 208, 0.2);
--chart-grid: #4c566a;
--chart-axis: #a0a8b8;
--chart-tooltip-bg: #3b4252;
--chart-tooltip-border: #4c566a;
--shadow-card: 0 1px 3px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(136, 192, 208, 0.05);
--shadow-card-hover: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(136, 192, 208, 0.15);
--shadow-dropdown: 0 10px 40px rgba(0, 0, 0, 0.5);
--skeleton-base: #434c5e;
--skeleton-highlight: #4c566a;
--dg-overlay: color-mix(in srgb, #2e3440 55%, transparent);
}
/* /*
* ===== AIOps 设计令牌(Design Tokens)// Logan.Li ===== * ===== AIOps 设计令牌(Design Tokens)// Logan.Li =====
* *
@@ -482,8 +149,7 @@
* 布局:--space-page 页面区块 | --layout-* 应用壳(侧栏/顶栏/内边距) * 布局:--space-page 页面区块 | --layout-* 应用壳(侧栏/顶栏/内边距)
* 告警:--alert-warning-* / --alert-error-* 横幅语义色 * 告警:--alert-warning-* / --alert-error-* 横幅语义色
* 主题:data-theme-preference 用户选择 | data-theme 实际生效主题 * 主题:data-theme-preference 用户选择 | data-theme 实际生效主题
* 主流:system / ocean-deep(蓝黑) / light-professional * 仅保留 双主题:ocean-deep(深海蓝暗色) / light-professional(明亮白浅色) + system 跟随系统
* 开发者:one-dark(暖灰) / dracula(紫粉) / tokyo-night(霓虹) / catppuccin
* *
* 布局层级:dg-app-shell → dg-app-content → PageShell(.dg-page) → ContentPanel * 布局层级:dg-app-shell → dg-app-content → PageShell(.dg-page) → ContentPanel
*/ */
+14 -31
View File
@@ -1,4 +1,4 @@
// 主题常量与持久化 — 主流主题 + 开发者主题 + 跟随系统 // Logan.Li // 主题常量与持久化 — 双主题(深海蓝暗色 / 明亮白浅色)+ 跟随系统 // Logan.Li
import { getItem, setItem, STORAGE_KEYS } from './storage'; import { getItem, setItem, STORAGE_KEYS } from './storage';
import i18n from '@/i18n'; import i18n from '@/i18n';
@@ -7,12 +7,7 @@ import i18n from '@/i18n';
export type ThemePreference = export type ThemePreference =
| 'system' | 'system'
| 'ocean-deep' | 'ocean-deep'
| 'light-professional' | 'light-professional';
| 'one-dark'
| 'catppuccin'
| 'dracula'
| 'tokyo-night'
| 'nord';
/** 实际应用到 data-theme 的具体主题 */ /** 实际应用到 data-theme 的具体主题 */
export type ResolvedTheme = Exclude<ThemePreference, 'system'>; export type ResolvedTheme = Exclude<ThemePreference, 'system'>;
@@ -30,30 +25,18 @@ export interface ThemeGroup {
options: ThemeOption[]; options: ThemeOption[];
} }
/** 主流主题 — 默认推荐 */ /** 主题清单 — 仅保留一暗一亮,避免多个暗色主题视觉重复 // Logan.Li */
const MAINSTREAM_THEMES: ThemeOption[] = [ const MAINSTREAM_THEMES: ThemeOption[] = [
{ id: 'system', name: i18n.t('common.lightDark'), description: i18n.t('common.themets.s17d84295'), isDark: false, primaryColor: 'linear-gradient(135deg, #2563eb 50%, #0d1117 50%)' }, { id: 'system', name: i18n.t('common.lightDark'), description: i18n.t('common.themets.s17d84295'), isDark: false, primaryColor: 'linear-gradient(135deg, #2563eb 50%, #0d1117 50%)' },
{ id: 'ocean-deep', name: i18n.t('common.themets.s2f82cbb2'), description: i18n.t('common.themets.s29ee972b'), isDark: true, primaryColor: '#0d1117' }, { id: 'ocean-deep', name: i18n.t('common.themets.s2f82cbb2'), description: i18n.t('common.themets.s29ee972b'), isDark: true, primaryColor: '#0d1117' },
{ id: 'light-professional', name: i18n.t('common.themets.s2d43cc04'), description: i18n.t('common.themets.s37e76182'), isDark: false, primaryColor: '#2563eb' }, { id: 'light-professional', name: i18n.t('common.themets.s2d43cc04'), description: i18n.t('common.themets.s37e76182'), isDark: false, primaryColor: '#2563eb' },
]; ];
/** 开发者主题 — 高辨识度扩展 */
const DEVELOPER_THEMES: ThemeOption[] = [
{ id: 'one-dark', name: 'One Dark', description: i18n.t('common.themets.s02b08e05'), isDark: true, primaryColor: '#c678dd' },
{ id: 'dracula', name: 'Dracula', description: i18n.t('common.themets.s525ce260'), isDark: true, primaryColor: '#bd93f9' },
{ id: 'tokyo-night', name: 'Tokyo Night', description: i18n.t('common.themets.s6f40fb5e'), isDark: true, primaryColor: '#7aa2f7' },
{ id: 'catppuccin', name: 'Catppuccin', description: i18n.t('common.themets.s571aa09d'), isDark: true, primaryColor: '#89b4fa' },
];
export const THEME_GROUPS: ThemeGroup[] = [ export const THEME_GROUPS: ThemeGroup[] = [
{ label: i18n.t('common.themets.s8392cae7'), options: MAINSTREAM_THEMES }, { label: i18n.t('common.themets.s8392cae7'), options: MAINSTREAM_THEMES },
{ label: i18n.t('common.themets.sc2e48855'), options: DEVELOPER_THEMES },
]; ];
export const THEME_OPTIONS: ThemeOption[] = [ export const THEME_OPTIONS: ThemeOption[] = [...MAINSTREAM_THEMES];
...MAINSTREAM_THEMES,
...DEVELOPER_THEMES,
];
export const THEME_ORDER: ThemePreference[] = THEME_OPTIONS.map((o) => o.id); export const THEME_ORDER: ThemePreference[] = THEME_OPTIONS.map((o) => o.id);
export const DEFAULT_THEME: ThemePreference = 'system'; export const DEFAULT_THEME: ThemePreference = 'system';
@@ -61,10 +44,15 @@ export const DEFAULT_THEME: ThemePreference = 'system';
const LEGACY_THEME_MAP: Record<string, ThemePreference> = { const LEGACY_THEME_MAP: Record<string, ThemePreference> = {
dark: 'ocean-deep', dark: 'ocean-deep',
light: 'light-professional', light: 'light-professional',
'midnight-purple': 'one-dark', // 已下架的旧主题与开发者主题统一迁移到深海蓝,保证存量用户不掉样式。 // Logan.Li
'pine-green': 'catppuccin', 'midnight-purple': 'ocean-deep',
'orange-vitality': 'tokyo-night', 'pine-green': 'ocean-deep',
nord: 'tokyo-night', 'orange-vitality': 'ocean-deep',
nord: 'ocean-deep',
'one-dark': 'ocean-deep',
dracula: 'ocean-deep',
'tokyo-night': 'ocean-deep',
catppuccin: 'ocean-deep',
}; };
export function migrateLegacyTheme(value: string | null): ThemePreference | null { export function migrateLegacyTheme(value: string | null): ThemePreference | null {
@@ -103,11 +91,6 @@ export function getInitialTheme(): ThemePreference {
if (stored && THEME_ORDER.includes(stored as ThemePreference)) { if (stored && THEME_ORDER.includes(stored as ThemePreference)) {
return stored as ThemePreference; return stored as ThemePreference;
} }
/* nord 已下架,自动迁移到 Tokyo Night // Logan.Li */
if (stored === 'nord') {
setItem(STORAGE_KEYS.theme, 'tokyo-night');
return 'tokyo-night';
}
return DEFAULT_THEME; return DEFAULT_THEME;
} }
@@ -126,4 +109,4 @@ export function applyThemeToDocument(pref: ThemePreference): void {
export function getNextTheme(current: ThemePreference): ThemePreference { export function getNextTheme(current: ThemePreference): ThemePreference {
const idx = THEME_ORDER.indexOf(current); const idx = THEME_ORDER.indexOf(current);
return THEME_ORDER[(idx + 1) % THEME_ORDER.length]; return THEME_ORDER[(idx + 1) % THEME_ORDER.length];
} }