1
0

feat: Dashboard 主题模式切换 — 系统跟随/明亮/黑暗,localStorage 持久化,TDesign theme-mode 驱动

新增 useThemePreference hook 和纯工具函数,支持系统/明亮/黑暗三态主题选择、
matchMedia 系统主题跟随、localStorage 持久化和启动期主题预应用,通过 <html
theme-mode> 驱动 TDesign 主题变量切换。

Header 右侧控件重新组织为 .dashboard-header-controls 单行桌面布局,主题
RadioGroup 位于刷新频率 RadioGroup 前。

附带:build.ts import specifier 改为跨平台 sep 转换;config-loader 测试适配
Windows PATH 和 YAML 路径转义;test-utils 类型窄化修复。
This commit is contained in:
2026-05-15 22:18:29 +08:00
parent 8793fbd786
commit c46ab14cce
14 changed files with 419 additions and 66 deletions

View File

@@ -1,5 +1,5 @@
import { readdir, rm, writeFile } from "node:fs/promises";
import { join, relative } from "node:path";
import { join, relative, sep } from "node:path";
import { fileURLToPath } from "node:url";
const projectRoot = fileURLToPath(new URL("..", import.meta.url));
@@ -68,7 +68,7 @@ async function codeGeneration() {
for (let i = 0; i < allFiles.length; i++) {
const urlPath = allFiles[i]!;
const varName = `f${i}`;
const filePath = relative(buildDir, join(distWebDir, urlPath.slice(1)));
const filePath = toImportSpecifier(buildDir, join(distWebDir, urlPath.slice(1)));
importLines.push(`import ${varName} from "./${filePath}" with { type: "file" };`);
if (urlPath === "/index.html") {
@@ -134,6 +134,10 @@ async function scanDir(dir: string, prefix: string): Promise<string[]> {
return paths;
}
function toImportSpecifier(fromDir: string, targetPath: string) {
return relative(fromDir, targetPath).split(sep).join("/");
}
async function viteBuild() {
console.log("Step 1/3: Vite build...");
const proc = Bun.spawn(["bunx", "--bun", "vite", "build"], {