1
0
Files
DiAL/openspec/specs/theme-mode-preference/spec.md
lanyuanxiaoyao c46ab14cce 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 类型窄化修复。
2026-05-15 22:18:29 +08:00

74 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Purpose
定义 Dashboard 主题模式选择、系统主题跟随、浏览器本地持久化和 TDesign 主题变量应用行为。
## Requirements
### Requirement: 主题模式选择器
Dashboard SHALL 在 Header 右侧提供主题模式 RadioGroup允许用户选择"系统""明亮""黑暗"三种模式。
#### Scenario: 主题模式选项渲染
- **WHEN** Dashboard 页面渲染
- **THEN** HeadMenu operations 区域 SHALL 在刷新频率选择器前显示 RadioGrouptheme="button", variant="default-filled"),选项为:系统、明亮、黑暗
#### Scenario: 默认选择系统
- **WHEN** 当前浏览器没有已保存的有效主题偏好
- **THEN** 主题模式 RadioGroup SHALL 默认选中"系统"
#### Scenario: 用户切换主题模式
- **WHEN** 用户点击"系统""明亮"或"黑暗"任一主题模式选项
- **THEN** RadioGroup SHALL 选中该选项,并触发对应主题模式生效
### Requirement: 主题模式生效
系统 SHALL 根据用户主题偏好计算有效主题,并通过 `<html>` 元素的 `theme-mode` 属性应用 TDesign 主题变量。
#### Scenario: 系统模式跟随暗色系统
- **WHEN** 用户主题偏好为"系统"且 `prefers-color-scheme: dark` 匹配
- **THEN** 系统 SHALL 设置 `document.documentElement``theme-mode` 属性为 `dark`
#### Scenario: 系统模式跟随亮色系统
- **WHEN** 用户主题偏好为"系统"且 `prefers-color-scheme: dark` 不匹配
- **THEN** 系统 SHALL 设置 `document.documentElement``theme-mode` 属性为 `light`
#### Scenario: 系统主题变化自动更新
- **WHEN** 用户主题偏好为"系统"且浏览器系统主题在明亮和黑暗之间变化
- **THEN** 系统 SHALL 自动更新 `theme-mode` 属性为新的有效主题
#### Scenario: 明亮模式固定主题
- **WHEN** 用户主题偏好为"明亮"
- **THEN** 系统 SHALL 设置 `theme-mode` 属性为 `light`,且系统主题变化 SHALL NOT 改变该属性
#### Scenario: 黑暗模式固定主题
- **WHEN** 用户主题偏好为"黑暗"
- **THEN** 系统 SHALL 设置 `theme-mode` 属性为 `dark`,且系统主题变化 SHALL NOT 改变该属性
### Requirement: 主题偏好本地持久化
系统 SHALL 将用户选择的主题偏好保存到当前浏览器本地存储,并在后续页面加载时恢复。
#### Scenario: 保存用户选择
- **WHEN** 用户切换主题模式
- **THEN** 系统 SHALL 将对应偏好值写入 `localStorage``dial.theme.preference`
#### Scenario: 恢复已保存偏好
- **WHEN** 页面加载且 `localStorage``dial.theme.preference` 键保存了有效偏好值
- **THEN** 系统 SHALL 使用该偏好初始化主题模式 RadioGroup 和有效主题
#### Scenario: 非法本地偏好回退
- **WHEN** 页面加载且 `dial.theme.preference` 保存了非 `system``light``dark` 的值
- **THEN** 系统 SHALL 忽略该值并按"系统"模式初始化
#### Scenario: 本地存储不可用
- **WHEN** 浏览器读取或写入 `localStorage` 抛出异常
- **THEN** Dashboard SHALL 继续正常渲染,并按内存中的主题偏好应用主题
### Requirement: 启动期主题恢复
系统 SHALL 在 React App 首次渲染前尽早应用一次有效主题,降低暗色环境下的亮色闪烁。
#### Scenario: 渲染前应用已保存偏好
- **WHEN** 前端入口初始化且浏览器已保存有效主题偏好
- **THEN** 系统 SHALL 在创建 React root 前根据该偏好设置 `<html>``theme-mode` 属性
#### Scenario: 渲染前应用系统偏好
- **WHEN** 前端入口初始化且浏览器没有有效主题偏好
- **THEN** 系统 SHALL 在创建 React root 前根据 `prefers-color-scheme: dark` 设置 `<html>``theme-mode` 属性