iter(g157): 补配方 10 暗色主题切换

说清三件事:只切 data-theme 不改令牌名、初值先读 localStorage、
同步 color-scheme 让原生控件跟色。MCP get_recipe 10 可取骨架。
This commit is contained in:
HIsheR
2026-10-26 15:56:56 +08:00
parent 1831aecab6
commit c2412fb360
4 changed files with 45 additions and 0 deletions
+8
View File
@@ -1612,6 +1612,14 @@
"acceptance": "ua tokens <子串> 只列匹配项并在末尾标注匹配词,--json 同步过滤;无匹配时给出总数并以 1 退出。",
"notes": "",
"status": "done"
},
{
"id": "g157",
"title": "补配方 10:暗色主题切换",
"motivation": "令牌层早就支持 [data-theme=dark],但配方里没有任何一条说清「怎么切、初值怎么定、原生控件为何仍是白底」,实践只能靠翻令牌表猜。",
"acceptance": "recipes.md 新增配方 10(切 data-theme + 同步 color-scheme + 初值先读 localStorage),verify 的配方结构校验通过,llms-full 与 MCP get_recipe 10 可取到骨架。",
"notes": "",
"status": "open"
}
]
}
+18
View File
@@ -2286,6 +2286,24 @@ grid({ columns: 2, gutter: 'lg' },
- 标题一律 `typography({ variant: 'title', level })` 出语义 `h1-h5`;正文长文本用 `ellipsis` 截断并自动挂 `title` 看全文。
- 只读字段用 `descriptions`(不要用 `form`):`form` 承载输入与校验,`descriptions` 只负责 label:value 对齐。
## 配方 10:暗色主题切换(只切 data-theme,不改令牌名)
```ts
const saved = localStorage.getItem('ua-theme');
const dark = signal(saved ? saved === 'dark' : matchMedia('(prefers-color-scheme: dark)').matches);
effect(() => {
document.documentElement.dataset.theme = dark() ? 'dark' : 'light';
document.documentElement.style.colorScheme = dark() ? 'dark' : 'light'; // 原生控件(date/滚动条)跟着变
localStorage.setItem('ua-theme', dark() ? 'dark' : 'light');
});
floatButton({ icon: '🌗', label: '切换主题', onClick: () => dark(!dark()) });
```
要点:
- 只改 `[data-theme]` 的取值:暗色是令牌**值**的另一套,名字永远不变,组件样式一律不写主题判断。
- 初值顺序是「先 localStorage、再 prefers-color-scheme」;反过来会让用户的手动选择被系统偏好覆盖。
- 同步设置 `color-scheme`,否则原生控件(日期选择、滚动条)在暗色下仍是白底。
## 通用约定
- 状态一律放信号(`signal` / `computed`),组件只读写信号,不持有业务数据副本。
+1
View File
@@ -153,3 +153,4 @@
- 配方 7:筛选栏(层级归属 + 日期区间)(3 条要点)
- 配方 8:评论输入(@ 提及 + 参与人头像组)(3 条要点)
- 配方 9:详情页排版(栅格 + 排版文本 + 描述列表)(3 条要点)
- 配方 10:暗色主题切换(只切 data-theme,不改令牌名)(3 条要点)
+18
View File
@@ -184,6 +184,24 @@ grid({ columns: 2, gutter: 'lg' },
- 标题一律 `typography({ variant: 'title', level })` 出语义 `h1-h5`;正文长文本用 `ellipsis` 截断并自动挂 `title` 看全文。
- 只读字段用 `descriptions`(不要用 `form`):`form` 承载输入与校验,`descriptions` 只负责 label:value 对齐。
## 配方 10:暗色主题切换(只切 data-theme,不改令牌名)
```ts
const saved = localStorage.getItem('ua-theme');
const dark = signal(saved ? saved === 'dark' : matchMedia('(prefers-color-scheme: dark)').matches);
effect(() => {
document.documentElement.dataset.theme = dark() ? 'dark' : 'light';
document.documentElement.style.colorScheme = dark() ? 'dark' : 'light'; // 原生控件(date/滚动条)跟着变
localStorage.setItem('ua-theme', dark() ? 'dark' : 'light');
});
floatButton({ icon: '🌗', label: '切换主题', onClick: () => dark(!dark()) });
```
要点:
- 只改 `[data-theme]` 的取值:暗色是令牌**值**的另一套,名字永远不变,组件样式一律不写主题判断。
- 初值顺序是「先 localStorage、再 prefers-color-scheme」;反过来会让用户的手动选择被系统偏好覆盖。
- 同步设置 `color-scheme`,否则原生控件(日期选择、滚动条)在暗色下仍是白底。
## 通用约定
- 状态一律放信号(`signal` / `computed`),组件只读写信号,不持有业务数据副本。