Browse Source

fix(switch): 开启态圆点改用 primary-content,修复铂金深色下白底白点

用户从 DOM 定位到:aria-checked=true + background-color: var(--primary)。

根因:铂金曜黑配色在深色模式下 --primary 是 #f1f2f3(近白),
那是配色本意(黑白极简风,强调色即白色)。开关拿它当开启轨道 +
白色圆点 = 白底白点,糊成一团。

修复:
- 开启态圆点改用 --primary-content(压在 primary 上的文字色,天然相反)
  深色 → 近白轨道 + 深色圆点;浅色 → 深蓝轨道 + 白色圆点
- 关闭态圆点永远白色,避免与开启态混淆

已用 Chrome 渲染核对浅色/铂金深色/其它配色深色共 6 种组合。

验证:tsc 0 错误;单测 1089/1089;构建通过;verify:ui 12/12

Co-Authored-By: Claude Code <noreply@anthropic.com>
Huccct 22 hours ago
parent
commit
e4acee201f
2 changed files with 47 additions and 15 deletions
  1. 15 0
      docs/00-tracking/操作追踪.md
  2. 32 15
      src/app/ui/components/switch/switch.ts

+ 15 - 0
docs/00-tracking/操作追踪.md

@@ -3853,3 +3853,18 @@ CSS 模板字符串的注释里用反引号包标识符(如 `` `opacity: 0` ``
 ### 验证
 - tsc 0 错误;单测 1089/1089;构建通过;verify:ui 12/12
 - 已用 Chrome 渲染核对四种组合(浅色/深色 × 开/关)
+
+### 开关开启态颜色修复(2026-11-01 收尾)
+用户从 DOM 里贴出的关键信息:`aria-checked="true"` + `background-color: var(--primary)`。
+
+**根因**:「铂金曜黑」配色在**深色模式**下 `--primary` 就是 `#f1f2f3`(近白)——
+那是配色设计的本意(黑白极简风,强调色即白色)。开关用它当开启态轨道 + 白色圆点,
+就成了「白轨道 + 白圆点」,糊成一团。
+
+**修复**:开启态圆点改用 `--primary-content`(配色里「压在 primary 上的文字色」,
+与 primary 天然相反):
+- 深色主题 → 近白轨道 + 深色圆点
+- 浅色主题 → 深蓝轨道 + 白色圆点
+- 关闭态圆点**永远白色**(否则浅灰轨道 + 深灰圆点会和开启态太像)
+
+已用 Chrome 渲染核对「铂金深色 / 其它配色深色 / 浅色」三组共 6 种组合。

+ 32 - 15
src/app/ui/components/switch/switch.ts

@@ -48,21 +48,33 @@ export class UiSwitch {
   });
 
   /**
-   * 轨道颜色 —— **随主题反转**(2026-11-01 用户要求)。
+   * 轨道颜色 —— 保证「轨道与圆点永远一亮一暗」(2026-11-01)。
    *
-   * | 主题 | 关闭 | 开启 |
-   * |---|---|---|
-   * | 浅色 | 深色轨道(#3a4049) | 品牌蓝 |
-   * | 深色 | 浅色轨道(#9aa3ad) | 品牌蓝 |
+   * 🔴 开启态**不能无脑用 var(--primary)**。
+   *    「铂金曜黑」配色在深色模式下 --primary 就是 #f1f2f3(近白)——
+   *    那是配色设计的本意(黑白极简风,强调色就是白色)。
+   *    但开关用它当轨道 + 白色圆点 = 白底白点,糊成一团(用户实测)。
+   *
+   * 所以轨道颜色按「能压住圆点」来选:
+   *    · 开启 + 深色主题 → 轨道用 --primary(近白),圆点用深色 → 清晰
+   *    · 开启 + 浅色主题 → 轨道用 --primary(深蓝/靛),圆点用白色 → 清晰
+   *    · 关闭 → 轨道与圆点始终反向
    *
-   * 🔴 用**内联样式**而不是组件 SCSS 类:
-   *    模板 [class] 动态拼出的类名,Angular 样式封装配不上 ——
-   *    第一版写成 .ui-switch-track-off 后整条规则被丢弃,
-   *    界面上完全没有效果(用户截图:深色模式里开关仍是纯白)。
-   *    内联样式不受封装影响,优先级也足够。
+   * 圆点的具体颜色由 knobStyle 给出,两者是**成对计算**的。
    */
   private readonly isDark = computed(() => this.theme?.isDark() ?? false);
 
+  /** 圆点颜色:开启时取「与 primary 相反」的一侧 */
+  private readonly knobOnColor = computed(() => {
+    /*
+     * 开启态的圆点颜色取决于 primary 的明暗。
+     * 深色主题下多数配色 primary 是亮色(铂金是近白、其它是亮蓝),圆点用深色;
+     * 浅色主题下 primary 是深色,圆点用白色。
+     * 这样无论哪套配色,轨道与圆点都保持对比。
+     */
+    return this.isDark() ? 'var(--primary-content)' : '#ffffff';
+  });
+
   protected readonly trackStyle = computed<Record<string, string>>(() => {
     const dark = this.isDark();
     if (this.checked()) {
@@ -97,13 +109,18 @@ export class UiSwitch {
    * 开启态轨道是品牌蓝,圆点统一用白色/近白,与蓝色对比足够。
    */
   protected readonly knobStyle = computed<Record<string, string>>(() => {
-    const dark = this.isDark();
     if (this.checked()) {
-      return { 'background-color': '#ffffff' };
+      // 与轨道成对:primary 亮 → 圆点暗,primary 暗 → 圆点亮
+      return { 'background-color': this.knobOnColor() };
     }
-    return {
-      'background-color': dark ? '#1e2128' : '#ffffff',
-    };
+    /*
+     * 关闭态圆点:**永远用亮色**。
+     *
+     * 关闭态轨道在深色主题下是浅灰(#9aa3ad),圆点必须是白才看得见;
+     * 若跟着主题反转让它变深色,会出现「浅灰轨道 + 深灰圆点」——
+     * 与开启态(近白轨道 + 深圆点)太像,用户分不出开关状态(实测)。
+     */
+    return { 'background-color': '#ffffff' };
   });
 
   protected toggle(): void {