iter(g157): 补配方 10 暗色主题切换
说清三件事:只切 data-theme 不改令牌名、初值先读 localStorage、 同步 color-scheme 让原生控件跟色。MCP get_recipe 10 可取骨架。
This commit is contained in:
@@ -1612,6 +1612,14 @@
|
|||||||
"acceptance": "ua tokens <子串> 只列匹配项并在末尾标注匹配词,--json 同步过滤;无匹配时给出总数并以 1 退出。",
|
"acceptance": "ua tokens <子串> 只列匹配项并在末尾标注匹配词,--json 同步过滤;无匹配时给出总数并以 1 退出。",
|
||||||
"notes": "",
|
"notes": "",
|
||||||
"status": "done"
|
"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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2286,6 +2286,24 @@ grid({ columns: 2, gutter: 'lg' },
|
|||||||
- 标题一律 `typography({ variant: 'title', level })` 出语义 `h1-h5`;正文长文本用 `ellipsis` 截断并自动挂 `title` 看全文。
|
- 标题一律 `typography({ variant: 'title', level })` 出语义 `h1-h5`;正文长文本用 `ellipsis` 截断并自动挂 `title` 看全文。
|
||||||
- 只读字段用 `descriptions`(不要用 `form`):`form` 承载输入与校验,`descriptions` 只负责 label:value 对齐。
|
- 只读字段用 `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`),组件只读写信号,不持有业务数据副本。
|
- 状态一律放信号(`signal` / `computed`),组件只读写信号,不持有业务数据副本。
|
||||||
|
|||||||
@@ -153,3 +153,4 @@
|
|||||||
- 配方 7:筛选栏(层级归属 + 日期区间)(3 条要点)
|
- 配方 7:筛选栏(层级归属 + 日期区间)(3 条要点)
|
||||||
- 配方 8:评论输入(@ 提及 + 参与人头像组)(3 条要点)
|
- 配方 8:评论输入(@ 提及 + 参与人头像组)(3 条要点)
|
||||||
- 配方 9:详情页排版(栅格 + 排版文本 + 描述列表)(3 条要点)
|
- 配方 9:详情页排版(栅格 + 排版文本 + 描述列表)(3 条要点)
|
||||||
|
- 配方 10:暗色主题切换(只切 data-theme,不改令牌名)(3 条要点)
|
||||||
|
|||||||
@@ -184,6 +184,24 @@ grid({ columns: 2, gutter: 'lg' },
|
|||||||
- 标题一律 `typography({ variant: 'title', level })` 出语义 `h1-h5`;正文长文本用 `ellipsis` 截断并自动挂 `title` 看全文。
|
- 标题一律 `typography({ variant: 'title', level })` 出语义 `h1-h5`;正文长文本用 `ellipsis` 截断并自动挂 `title` 看全文。
|
||||||
- 只读字段用 `descriptions`(不要用 `form`):`form` 承载输入与校验,`descriptions` 只负责 label:value 对齐。
|
- 只读字段用 `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`),组件只读写信号,不持有业务数据副本。
|
- 状态一律放信号(`signal` / `computed`),组件只读写信号,不持有业务数据副本。
|
||||||
|
|||||||
Reference in New Issue
Block a user