ca7ce4c26f
把高频硬编码色(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>
89 lines
4.0 KiB
TypeScript
89 lines
4.0 KiB
TypeScript
import type { CSSProperties } from "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 变量(浏览器忽略,桌面端生效)。
|
|
const DRAG = { "--wails-draggable": "drag" } as CSSProperties;
|
|
const NODRAG = { "--wails-draggable": "no-drag" } as CSSProperties;
|
|
|
|
function Light({ on, label }: { on: boolean; label: string }) {
|
|
const dot = on ? "bg-success shadow-[0_0_8px_rgba(52,211,153,0.7)]" : "bg-danger";
|
|
return (
|
|
<span className="flex items-center gap-1.5 text-[11px] text-slate-500" title={`${label} ${on ? "在线" : "离线"}`}>
|
|
<span className={cn("h-1.5 w-1.5 rounded-full", dot)} />
|
|
{label}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
// 顶栏:品牌 · 垂直切换 · 健康灯 · 登录用户 + 登出(深色 + 毛玻璃)。
|
|
export function TopBar({ user, onLogout, onCommand }: { user: AuthUser; onLogout: () => void; onCommand?: () => void }) {
|
|
const h = useHealth();
|
|
const { theme, toggle } = useTheme();
|
|
return (
|
|
<header
|
|
style={DRAG}
|
|
className={cn("flex h-12 shrink-0 items-center gap-3 border-b border-line bg-ink-900/80 pr-3 backdrop-blur", isMacDesktop() ? "pl-20" : "pl-3")}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<div className="flex h-6 w-6 items-center justify-center rounded-md bg-gradient-to-br from-brand to-accent text-xs font-bold text-white">
|
|
S
|
|
</div>
|
|
<span className="brand-gradient text-sm font-semibold">sundynix-agentix</span>
|
|
</div>
|
|
<div className="relative" style={NODRAG}>
|
|
<select
|
|
className="appearance-none rounded-md border border-line bg-ink-800 py-1 pl-2.5 pr-7 text-xs text-slate-300 focus:border-brand focus:outline-none"
|
|
defaultValue="通用版"
|
|
>
|
|
<option>通用版</option>
|
|
<option>法律版</option>
|
|
<option>医疗版</option>
|
|
</select>
|
|
<ChevronDown className="pointer-events-none absolute right-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-slate-500" />
|
|
</div>
|
|
<button
|
|
onClick={onCommand}
|
|
style={NODRAG}
|
|
className="flex items-center gap-2 rounded-md border border-line bg-ink-800 px-2.5 py-1 text-xs text-slate-400 transition hover:border-ink-600 hover:text-slate-200"
|
|
title="命令面板"
|
|
>
|
|
<SearchIcon className="h-3.5 w-3.5" />
|
|
搜索与命令
|
|
<kbd className="rounded border border-line px-1 font-mono text-[10px] text-slate-500">⌘K</kbd>
|
|
</button>
|
|
<div className="ml-2 flex items-center gap-3">
|
|
<Light on={h.gateway} label="Gateway" />
|
|
<Light on={h.db} label="DB" />
|
|
<Light on={h.nats} label="NATS" />
|
|
<Light on={h.milvus} label="Milvus" />
|
|
<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}
|
|
</span>
|
|
<button
|
|
onClick={onLogout}
|
|
className="flex items-center gap-1 rounded-md border border-line bg-ink-800 px-2 py-1 text-xs text-slate-400 transition hover:border-danger/50 hover:text-danger"
|
|
title="退出登录"
|
|
>
|
|
<LogOut className="h-3.5 w-3.5" />
|
|
</button>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|