feat(desktop): 亮/暗主题切换 —— 默认亮色,一处令牌驱动全 app 换肤

把高频硬编码色(ink 表面 / line 边框 / slate 文字)重定义为 CSS 变量(RGB 三元组,
保留 /透明度 修饰符),:root(亮) 与 .dark(暗) 两套值切换——改 tailwind.config + index.css
两处即让全 app 换肤,无需逐文件迁移。

- 亮色走 shadcn 中性灰(zinc:zinc-50 底/白卡/zinc-200 边/zinc-900 字);
  暗色精炼为中性 zinc 暗(替代原偏蓝 ink),顺带提质感。
- lib/theme.ts:useTheme + applyInitialTheme(main 启动前设类,避免首屏闪烁)+ localStorage 持久化,默认亮色。
- TopBar 加 Sun/Moon 切换钮;滚动条/输入控件 color-scheme 随主题。
- 修亮色下会失效的 bg-white/5 → bg-ink-800(Tabs/Badge/ExecTrace 的中性微底);
  模态遮罩 bg-black/55 两模式皆宜,保留。

验证:tsc + vitest 48 过 + 生产构建通过(var 色全解析)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-06-25 10:39:36 +08:00
parent aea04e2e8d
commit ca7ce4c26f
10 changed files with 122 additions and 221 deletions
+10 -1
View File
@@ -1,8 +1,9 @@
import type { CSSProperties } from "react";
import { User, ChevronDown, Search as SearchIcon, LogOut } from "lucide-react";
import { User, ChevronDown, Search as SearchIcon, LogOut, Sun, Moon } from "lucide-react";
import type { AuthUser } from "../lib/api";
import { useHealth } from "../lib/health";
import { isMacDesktop } from "../lib/desktop";
import { useTheme } from "../lib/theme";
import { cn } from "../ui";
// Wails 拖拽区/控件 CSS 变量(浏览器忽略,桌面端生效)。
@@ -22,6 +23,7 @@ function Light({ on, label }: { on: boolean; label: string }) {
// 顶栏:品牌 · 垂直切换 · 健康灯 · 登录用户 + 登出(深色 + 毛玻璃)。
export function TopBar({ user, onLogout, onCommand }: { user: AuthUser; onLogout: () => void; onCommand?: () => void }) {
const h = useHealth();
const { theme, toggle } = useTheme();
return (
<header
style={DRAG}
@@ -62,6 +64,13 @@ export function TopBar({ user, onLogout, onCommand }: { user: AuthUser; onLogout
<Light on={h.neo4j} label="Neo4j" />
</div>
<div className="ml-auto flex items-center gap-2" style={NODRAG}>
<button
onClick={toggle}
className="flex items-center rounded-md border border-line bg-ink-800 px-2 py-1 text-slate-400 transition hover:border-ink-600 hover:text-slate-200"
title={theme === "dark" ? "切换到亮色" : "切换到暗色"}
>
{theme === "dark" ? <Sun className="h-3.5 w-3.5" /> : <Moon className="h-3.5 w-3.5" />}
</button>
<span className="flex items-center gap-1.5 rounded-md border border-line bg-ink-800 px-2.5 py-1 text-xs text-slate-300" title={user.email}>
<User className="h-3.5 w-3.5 text-slate-500" />
{user.name || user.email}