主题系统
配置 Web 应用的主题预设、亮暗模式与默认主题
主题系统
Web 端基于 shadcn/ui 的 CSS 变量体系,支持亮色 / 暗色模式切换,以及多套预设主题(Preset)。
主题预设(Preset)
所有预设定义在:
apps/web/src/configs/theme-presets.ts每个预设包含亮色和暗色两套完整的 CSS 变量:
export const themePresets = {
"modern-minimal": {
label: "Modern Minimal",
styles: {
light: {
background: "#ffffff",
foreground: "#333333",
primary: "#3b82f6",
// ... 其他变量
},
dark: {
background: "#171717",
foreground: "#e5e5e5",
primary: "#3b82f6",
// ... 其他变量
},
},
},
// 更多预设...
};内置预设共 25 套,包括:modern-minimal、violet-bloom、t3-chat、mocha-mousse、amethyst-haze、doom-64、kodama-grove、cosmic-night 等。
更改默认主题
默认主题取 themePresets 对象中的第一个键。调整 theme-presets.ts 中预设的顺序,将期望的主题移到最前面即可:
export const themePresets = {
"violet-bloom": { /* ... */ }, // ← 移到第一位,成为默认主题
"modern-minimal": { /* ... */ },
// ...
};如果所有预设都不存在,则回退到
"modern-minimal"(在web-config.ts中定义的fallbackThemePresetKey)。
新增自定义主题
在 themePresets 对象中追加新的键值对,填入亮色和暗色两套变量:
export const themePresets = {
// 现有预设...
"my-brand": {
label: "My Brand",
styles: {
light: {
background: "#fafafa",
foreground: "#111111",
primary: "#e11d48",
// ... 完整变量列表参考现有预设
},
dark: {
background: "#0f0f0f",
foreground: "#f5f5f5",
primary: "#fb7185",
// ...
},
},
},
};新增后,该主题会自动出现在用户可选的主题列表中。
用户偏好存储
用户在应用内选择的主题偏好会持久化到 localStorage:
| 键 | 内容 |
|---|---|
{AppName}-ui-theme | 外观模式:light / dark / system |
{AppName}-ui-preset | 当前预设键名,如 "modern-minimal" |
{AppName}-ui-preset-styles | 当前预设的 CSS 变量(用于避免 FOUC) |
其中 AppName 来自 packages/app-config 中配置的应用名称。
防闪烁脚本(FOUC)
theme-config.ts 导出了一段内联脚本 themeScript,在页面 HTML <head> 中最早执行,在 React 水合之前就将正确的主题 class 和 CSS 变量应用到 <html> 元素上,避免初次加载时的主题闪烁。