Files
aiops/frontend/src/components/layout/ThemePicker.tsx
T
Logan e363ded445 feat: 全站 PageShell 设计系统与专业 UI 统一
- 新增 PageShell/PageTabs/ContentPanel/PageLoading/PageEmpty 页面骨架
- index.css 设计令牌文档化,布局令牌与纯色主按钮(去除渐变粉彩)
- 全站路由页接入 PageShell,云账单三 Tab 为标杆
- 主题体系:跟随系统 + 主流/开发者分组,新增 Dracula/Tokyo Night,One Dark 暖灰差异化
- 登录页/侧栏/顶栏去渐变光球,企业克制风
- 修复 AIAlertAnalyzer JSX 与构建依赖导入问题
2026-07-01 12:45:38 +08:00

61 lines
2.2 KiB
TypeScript

// 全局主题选择器 — Header / Login 共用,分组展示主流与开发者主题 // Logan.Li
import { Check } from 'lucide-react';
import { cn } from '@/lib/utils';
import {
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
} from '@/components/ui/dropdown-menu';
import { THEME_GROUPS, type ThemePreference } from '@/utils/theme';
interface ThemePickerProps {
value: ThemePreference;
onChange: (theme: ThemePreference) => void;
}
export function ThemePicker({ value, onChange }: ThemePickerProps) {
return (
<>
{THEME_GROUPS.map((group, gi) => (
<div key={group.label}>
{gi > 0 && <DropdownMenuSeparator className="bg-[var(--border-default)]" />}
<DropdownMenuLabel className="text-xs dg-text-muted font-normal py-1">
{group.label}
</DropdownMenuLabel>
{group.options.map((option) => (
<DropdownMenuItem
key={option.id}
className={cn(
'flex items-center gap-2.5 cursor-pointer transition-colors',
'focus:bg-[var(--surface-hover)] focus:text-[var(--text-primary)]',
value === option.id
? 'text-[var(--text-primary)]'
: 'dg-text-secondary',
)}
onClick={() => onChange(option.id)}
>
<span
className="w-3.5 h-3.5 rounded-full shrink-0"
style={{
background: option.primaryColor.startsWith('linear')
? option.primaryColor
: option.primaryColor,
boxShadow: '0 0 0 2px var(--surface-canvas)',
}}
/>
<div className="flex-1 min-w-0">
<span className="text-sm font-medium">{option.name}</span>
<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>
))}
</>
);
}