标题建议:设计标记被字面量覆写绕过 —— settings.css 等 7 个文件仍有不可主题化的表面
标签:bug、area: ui-ux
目标仓库:vastsa/PI-Desktop
关联:#339(本 issue 是它在全仓的延续)
以下正文可直接粘贴。
1. 场景
我在验证插件主题 ui.theme 的能力边界时发现右侧工作面板不可主题化,已在 #339 修复(work-panel.css 的 6 处字面量覆写改为 --ds-bg-dock / --ds-bg-dock-raised)。
修完后我用同一条判据把整个 apps/desktop/src/styles/ 过了一遍 —— 判据是「被 :root[data-theme] 覆写、且不读变量的字面量表面色」 —— 结果同类洞还在 7 个文件里。
这类覆写的失效机制都一样:基础规则读 token,覆写规则
:root[data-theme="light"] .settings-search { background: #ffffff; } /* settings.css:114 */
既把特异度从 (0,1,0) 抬到 (0,2,0),又完全不引用变量,所以主题把 --ds-* 改成什么都会被它盖掉。
一个额外的坏味道:settings.css 的覆写是成对出现的(浅色 + 深色两条),也就是说这两个表面在两个调色板下都被钉死,比 #339 里的单边覆写更彻底。
2. 基于场景提炼需要的能力
| 能力 |
来自哪个场景 |
具体含义 |
| 外壳表面色只能来自标记 |
基础规则用 token、覆写用字面量,同一份文件里两种写法并存 |
任何「主题应能改的表面」都由 --ds-* 表达;禁止在 :root[data-theme] 覆写里写字面量 |
| 缺口可被自动发现 |
这轮靠人工逐个文件读才找全 |
有一条机械规则能在 CI 里挡住新增的字面量表面色,不依赖评审记忆 |
| 覆盖范围有文档 |
主题作者不知道哪些表面可改 |
设计系统的表面层级表登记全部可达 token |
3. 现有能力与期待能力的差异
| 期待能力 |
现状 |
差距 |
| 外壳表面色只能来自标记 |
settings.css::54 / :58(设置页导航轨)、:114 / :118(导航轨搜索框)、:185 / :189(选中导航胶囊)、:706(开关旋钮)、:1241 / :1246(能力页搜索井) |
8 处确认缺陷,浅深两套均不可主题化 |
| 同上 |
composer-menus.css:11(输入框壳 #212121f5,覆盖了 var(--ds-bg-elevated-primary))、plugins.css:248 / :252 / :1755、ui-kit.css:140 / :147、overlays.css:18、theme-overrides.css:81 |
又 9 处确认缺陷 |
| 同上 |
prose.css::110、:176、:229、:274-280、:304-305、:320-322、:364-365、:438-440、:454-455、:458-469、:615-616、:734-741(含 Mermaid 块底色) |
十余处,正文区同样不可主题化 |
| 缺口可被自动发现 |
scripts/check-style-tokens.mjs:21 只守 font-size / font-weight / line-height / letter-spacing / border-radius,颜色完全没守 |
新增字面量表面色无任何 CI 阻力 |
| 覆盖范围有文档 |
docs/spec/04-ux/07-ui-design-system.md §6.4 的表面层级表只登记 --ds-bg-primary / --ds-tile / --ds-raised 与新增的 --ds-bg-dock / --ds-bg-dock-raised |
上述表面的 token 一个都没有 |
需要一并注意的 CI 断言(改这些规则会挂):
apps/desktop/test/surface-polish.test.mjs:74-77 断言开关旋钮的浅色字面量,:106-109 禁止在 :root[data-theme] .settings-toggle 上写 background,:126-134 要求四个 switch token 各定义两次
apps/desktop/test/agent-capability-settings.test.mjs:180 断言 :root[data-theme="dark"] .agent-capability-menu 规则存在,:174-177 断言能力分组计数使用 color-mix(var(--ds-text-primary)…)
apps/desktop/test/settings-drag-region.test.mjs:21-45 断言导航轨的 width / flex 与标题栏定位顺序
4. 提案
对应能力 1:为上述每一组表面抽出 token,默认值取现值,保证内置观感逐像素不变。粗算需要 4 组:
| 建议 token |
浅色 |
深色 |
覆盖 |
--ds-settings-rail-bg |
#f4f4f4 |
#000000 |
settings.css:54/58 |
--ds-settings-field-bg |
#ffffff |
#212121 |
settings.css:114/118 |
--ds-settings-nav-active |
color-mix(in oklab, #1a1c1f 12%, #ffffff) |
color-mix(in oklab, var(--gray-0) 10%, transparent) |
settings.css:185/189 |
--ds-field-inset-bg(含 :focus-within 一档) |
#f3f3f3 / #ffffff |
沿用现有 token 混合 |
settings.css:1241/1246、plugins.css:248/252 |
开关旋钮不需要新 token:浅色 --ds-switch-knob-on 已经是 #ffffff,删掉 :704-708 即可。
prose.css 与遮罩类(ui-kit.css:140、overlays.css:18、plugins.css:1755)的字面量涉及正文排版与 scrim 不透明度,建议单独一批处理,逐项确认是否符合既有设计决策。
对应能力 2:把 scripts/check-style-tokens.mjs 的检查面从字号/圆角扩到颜色 —— 属性集 color|background(-color)?|border(-[a-z]+)?-color|fill|stroke|box-shadow,并沿用现有的 -- 行豁免与 allowlist 机制(@font-face、纯 alpha 遮罩、Shiki 调色板)。
需要注意这条规则的能力边界:它能挡住 apps/desktop/src 下新增的裸 hex / rgb,但抓不到「选择器压过令牌」这类级联问题(#339 的成因),也抓不到插件自带 CSS。级联问题只能靠评审,因此建议在 07-ui-design-system.md §6.4 把该约定写成明文。
对应能力 3:surface 层级表补齐上述 token。
标题建议:设计标记被字面量覆写绕过 ——
settings.css等 7 个文件仍有不可主题化的表面标签:
bug、area: ui-ux目标仓库:vastsa/PI-Desktop
关联:#339(本 issue 是它在全仓的延续)
以下正文可直接粘贴。
1. 场景
我在验证插件主题
ui.theme的能力边界时发现右侧工作面板不可主题化,已在 #339 修复(work-panel.css的 6 处字面量覆写改为--ds-bg-dock/--ds-bg-dock-raised)。修完后我用同一条判据把整个
apps/desktop/src/styles/过了一遍 —— 判据是「被:root[data-theme]覆写、且不读变量的字面量表面色」 —— 结果同类洞还在 7 个文件里。这类覆写的失效机制都一样:基础规则读 token,覆写规则
既把特异度从
(0,1,0)抬到(0,2,0),又完全不引用变量,所以主题把--ds-*改成什么都会被它盖掉。一个额外的坏味道:
settings.css的覆写是成对出现的(浅色 + 深色两条),也就是说这两个表面在两个调色板下都被钉死,比 #339 里的单边覆写更彻底。2. 基于场景提炼需要的能力
--ds-*表达;禁止在:root[data-theme]覆写里写字面量3. 现有能力与期待能力的差异
settings.css::54/:58(设置页导航轨)、:114/:118(导航轨搜索框)、:185/:189(选中导航胶囊)、:706(开关旋钮)、:1241/:1246(能力页搜索井)composer-menus.css:11(输入框壳#212121f5,覆盖了var(--ds-bg-elevated-primary))、plugins.css:248/:252/:1755、ui-kit.css:140/:147、overlays.css:18、theme-overrides.css:81prose.css::110、:176、:229、:274-280、:304-305、:320-322、:364-365、:438-440、:454-455、:458-469、:615-616、:734-741(含 Mermaid 块底色)scripts/check-style-tokens.mjs:21只守font-size/font-weight/line-height/letter-spacing/border-radius,颜色完全没守docs/spec/04-ux/07-ui-design-system.md§6.4 的表面层级表只登记--ds-bg-primary/--ds-tile/--ds-raised与新增的--ds-bg-dock/--ds-bg-dock-raised需要一并注意的 CI 断言(改这些规则会挂):
apps/desktop/test/surface-polish.test.mjs:74-77断言开关旋钮的浅色字面量,:106-109禁止在:root[data-theme] .settings-toggle上写background,:126-134要求四个 switch token 各定义两次apps/desktop/test/agent-capability-settings.test.mjs:180断言:root[data-theme="dark"] .agent-capability-menu规则存在,:174-177断言能力分组计数使用color-mix(var(--ds-text-primary)…)apps/desktop/test/settings-drag-region.test.mjs:21-45断言导航轨的width/flex与标题栏定位顺序4. 提案
对应能力 1:为上述每一组表面抽出 token,默认值取现值,保证内置观感逐像素不变。粗算需要 4 组:
--ds-settings-rail-bg#f4f4f4#000000settings.css:54/58--ds-settings-field-bg#ffffff#212121settings.css:114/118--ds-settings-nav-activecolor-mix(in oklab, #1a1c1f 12%, #ffffff)color-mix(in oklab, var(--gray-0) 10%, transparent)settings.css:185/189--ds-field-inset-bg(含:focus-within一档)#f3f3f3/#ffffffsettings.css:1241/1246、plugins.css:248/252开关旋钮不需要新 token:浅色
--ds-switch-knob-on已经是#ffffff,删掉:704-708即可。prose.css与遮罩类(ui-kit.css:140、overlays.css:18、plugins.css:1755)的字面量涉及正文排版与 scrim 不透明度,建议单独一批处理,逐项确认是否符合既有设计决策。对应能力 2:把
scripts/check-style-tokens.mjs的检查面从字号/圆角扩到颜色 —— 属性集color|background(-color)?|border(-[a-z]+)?-color|fill|stroke|box-shadow,并沿用现有的--行豁免与 allowlist 机制(@font-face、纯 alpha 遮罩、Shiki 调色板)。需要注意这条规则的能力边界:它能挡住
apps/desktop/src下新增的裸 hex / rgb,但抓不到「选择器压过令牌」这类级联问题(#339 的成因),也抓不到插件自带 CSS。级联问题只能靠评审,因此建议在07-ui-design-system.md§6.4 把该约定写成明文。对应能力 3:surface 层级表补齐上述 token。