Skip to content

fix(design-system): DS-4b 设置输入框旧主题兼容收口 - #4010

Merged
MagicLizi merged 1 commit into
makecindy:mainfrom
kirozeng:ds/4b-input-theme-compat
Sep 6, 2026
Merged

MagicLizi merged 1 commit into
makecindy:mainfrom
kirozeng:ds/4b-input-theme-compat

Conversation

@kirozeng

@kirozeng kirozeng commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

设计系统改造系列 DS-4b,路线图见 docs/design-rules/design-governance.md §12

这次改了什么

摘要

DS-4 将设置输入框改为直接使用通用 Input 后,旧本地主题中的设置域文字、边框和焦点边框覆盖不再被消费。本 PR 恢复既有设置输入的局部主题合同:SettingsTextInput 继续复用标准 Input 的行为和状态,通过薄封装保留旧 alias;通用 Input 仍使用 Tier-1 默认。

变更类型

  • fix 缺陷修复

范围

  • 关联 Issue / 需求:DS-4(feat(design-system): DS-4 Button 与 Input 标准组件 #3920)兼容收口;用户要求旧主题效果继续生效。
  • 本 PR 包含:SettingsTextInput 封装、AgentResource / Collaboration 四个既有数字输入的接入、主题加载到组件消费的回归测试、相关文档及证据索引。
  • 明确不包含:跨域 alias 全族迁移、focus 环与 ivory 的新视觉裁决、用户主题文件写回、聊天区或 Mobile 迁移。
  • 用户可见变化:显式配置过设置域 alias 的本地主题在既有设置输入上恢复局部配色;没有局部覆盖的内置主题逐值不变。
  • 是否存在 breaking change:无接口删除或持久数据变更;不声称零视觉变化,局部覆盖恢复属于有意可见变化。已有 placeholder 加载期归一化保持不变。

UI 变化

  • 引用的设计规范:docs/design-rules/DESIGN.md §4 Input / Textarea 及 §10 双模式要求;docs/design-rules/design-governance.md §4 兼容红线与 §6 两级证据合同。通用组件默认保持 Tier-1,设置封装保留旧作用域,标准错误态优先;Light / Dark 均实现。
  • 风险类别:有意可见变化。09-04 决策日志提出过跨 surface alias 全族向 Tier-1 收敛;本批采用更窄的兼容修复,不改写该历史裁决,也不宣称全族治理完成。
  • macOS arm64 / 实际 Desktop dev 独立沙箱内挂载真实 Input 与 SettingsTextInput,用生产 Tailwind、ThemeService 进行亮暗对照与计算样式测量。采集代码摘要与数值见 文字证据
  • 截图附件仍未上传(此前仅本地目检);本轮以「界面效果证据」HTML 复刻页补足 description 证据——页面由真实组件 utility 与实测色值复刻,
    并在真实 Chromium 内逐项核对 computed style(56/56 通过)。不把受控组件样例称作完整设置页验收。

界面效果证据(改动后界面的 HTML 页面;自包含,保存为 .html 用浏览器打开即可查看。
同一主题下左列通用 Input 跟 Tier-1/全局覆盖、右列兼容封装跟 settings-input-* 局部覆盖;
所有输入框可点击聚焦复现 :focus;页面底部附 token 对照表与来源):

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DS-4b 设置输入框主题兼容 — 界面效果证据页</title>
<style>
  /* ============ 页面文档外壳(仅组织排版,不属于被证据的 App UI) ============ */
  :root {
    font-family: 'Inter Variable', Inter, -apple-system, BlinkMacSystemFont, 'PingFang SC',
      'Hiragino Sans GB', 'HarmonyOS Sans SC', 'Microsoft YaHei UI', 'Microsoft YaHei',
      'Noto Sans CJK SC', 'Source Han Sans SC', 'Segoe UI', Roboto, sans-serif; /* globals.css --app-font-ui-default */
  }
  body { margin: 0; padding: 24px; background: #ffffff; color: #333333; }
  .page { max-width: 1060px; margin: 0 auto; }
  h1 { font-size: 18px; margin: 0 0 4px; }
  .lede { font-size: 13px; line-height: 1.7; color: #525252; margin: 0 0 8px; }
  .lede code, .token-table code { background: #f0f0ee; border-radius: 4px; padding: 0 4px; font-size: 12px; }
  .panel { margin-top: 28px; }
  .panel > h2 { font-size: 15px; margin: 0 0 4px; }
  .panel > .panel-note { font-size: 12.5px; line-height: 1.7; color: #525252; margin: 0 0 12px; }
  .modes { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
  .mode-card {
    /* 设置页真实背景(SettingsView bg-[var(--settings-bg)] → --surface) */
    background: var(--settings-bg);
    padding: 16px;
    border-radius: 14px;
    min-width: 480px;
    flex: 1;
  }
  .mode-title { font-size: 13px; font-weight: 600; margin: 0 0 10px; color: #333333; }
  /* 设置卡片真实外观(CollaborationSection CARD_CLASS:rounded-xl + card-bg + card-border) */
  .app-card {
    background: var(--settings-theme-card-bg);
    border: 1px solid var(--settings-theme-card-border);
    border-radius: 12px;          /* Tailwind rounded-xl */
    padding: 16px;                /* 行级 px-4 py-4 */
  }
  .cols { display: grid; grid-template-columns: 120px 1fr 1fr; gap: 10px 14px; align-items: center; }
  .col-head { font-size: 12.5px; font-weight: 600; color: var(--settings-section-sublabel); }
  .row-label { font-size: 12.5px; color: var(--settings-section-sublabel); line-height: 1.5; }
  .row-label small { display: block; font-size: 11px; color: var(--settings-section-sublabel); opacity: 0.8; }

  /* ============ 组件样式:逐条对应 components/ui/input.tsx(size lg 默认档) ============ */
  .input-shell { position: relative; } /* Input 外层 <div class="relative"> */
  .cindy-input {
    width: 100%;                /* w-full(外层定宽,同设置行内真实布局) */
    height: 40px;               /* h-[40px](lg 档,四个数字输入均未传 size) */
    font-size: 14px;            /* text-14 */
    padding-left: 12px;         /* pl-[12px] */
    padding-right: 12px;        /* pr-[12px](无 trailing) */
    border-radius: 9999px;      /* rounded-full 胶囊(DESIGN.md §4/§5) */
    outline: none;              /* outline-none */
    transition: color 150ms, background-color 150ms, border-color 150ms, box-shadow 150ms; /* transition-colors,--motion-fast=150ms */
    border: 1px solid var(--border-default); /* border border-[var(--border-default)] */
    color: var(--text-primary);             /* text-[var(--text-primary)] */
    background: var(--surface-elevated);    /* bg-[var(--surface-elevated)](surface 默认 elevated) */
    box-sizing: border-box;
    font-family: inherit;
  }
  .cindy-input::placeholder { color: var(--text-placeholder); opacity: 1; } /* placeholder:text-[var(--text-placeholder)] */

  /* FIELD_CHROME 焦点:focus:border-[var(--text-tertiary-stone)] + focus:ring-2 ring-[var(--focus-ring)]
     (ring-2 净效果 = box-shadow 0 0 0 2px) */
  .cindy-input:focus,
  .cindy-input[data-static-focus] {
    border-color: var(--text-tertiary-stone);
    box-shadow: 0 0 0 2px var(--focus-ring);
  }

  /* SettingsTextInput 注入的 LEGACY_INPUT_CHROME(合并顺序在 FIELD_CHROME 之后):
     text/placeholder/border/focus-border 改绑 settings-input-* alias */
  .settings-input { color: var(--settings-input-text); border-color: var(--settings-input-border); }
  .settings-input::placeholder { color: var(--settings-input-placeholder); opacity: 1; }
  .settings-input:focus,
  .settings-input[data-static-focus] {
    border-color: var(--settings-input-border-focus);
    box-shadow: 0 0 0 2px var(--focus-ring);
  }

  /* ERROR_CHROME(合并顺序最后 → 错误态优先于局部兼容样式):
     border-[var(--error-border)] focus:border-[var(--error-fg)] focus:ring-[var(--error-fg)] */
  .cindy-input.is-error,
  .settings-input.is-error { border-color: var(--error-border); }
  .cindy-input.is-error:focus, .cindy-input.is-error[data-static-focus],
  .settings-input.is-error:focus, .settings-input.is-error[data-static-focus] {
    border-color: var(--error-fg);
    box-shadow: 0 0 0 2px var(--error-fg);
  }

  /* disabled && 'cursor-not-allowed opacity-60' */
  .cindy-input:disabled { cursor: not-allowed; opacity: 0.6; }

  /* ============ 主题作用域:变量按真实解析链组织(themes/colors.ts) ============ */
  /* 面板一:内置主题 —— settings-input-* 无覆盖,forward-resolve 到 Tier-1(两列逐值相同) */
  .scope-builtin-light, .scope-builtin-dark {
    --focus-ring: #417CDD;                       /* focus-ring:双模式同值 */
    --error-border: rgba(220, 38, 38, 0.4);      /* 面板一 Light error-border */
    --error-fg: #dc2626;
  }
  .scope-builtin-light {
    --settings-bg: #f8f8f6;                      /* surface */
    --surface-elevated: #ffffff;
    --settings-theme-card-bg: #faf9f5;           /* surface-card-ivory */
    --settings-theme-card-border: #d7d7d4;       /* border-default */
    --text-primary: #262626;
    --text-placeholder: #c4c4c4;
    --text-tertiary-stone: #737373;
    --text-tertiary-mid: #525252;                /* 行标签(settings-section-sublabel) */
    --settings-section-sublabel: var(--text-tertiary-mid);
    --settings-input-text: var(--text-primary);            /* alias 默认 forward-resolve */
    --settings-input-placeholder: var(--text-placeholder);
    --settings-input-border: var(--border-default);
    --settings-input-border-focus: var(--text-tertiary-stone);
    --border-default: #d7d7d4;
  }
  .scope-builtin-dark {
    --settings-bg: #1f1f1e;
    --surface-elevated: #2c2c2a;
    --settings-theme-card-bg: #2c2c2a;
    --settings-theme-card-border: #3c3c3a;
    --text-primary: #d4d4d4;
    --text-placeholder: #525252;
    --text-tertiary-stone: #737373;
    --text-tertiary-mid: #737373;
    --settings-section-sublabel: var(--text-tertiary-mid);
    --settings-input-text: var(--text-primary);
    --settings-input-placeholder: var(--text-placeholder);
    --settings-input-border: var(--border-default);
    --settings-input-border-focus: var(--text-tertiary-stone);
    --border-default: #3c3c3a;
    --error-border: #7f1d1d;                     /* 面板一 Dark error-border */
    --error-fg: #f87171;
  }

  /* 面板二:受控测试主题 —— 全局 Tier-1 覆盖(蓝系)+ settings-input-* 局部覆盖(棕系)。
     覆盖值取自 docs/design-evidence/2026-09-06/input-theme-compat.md 的实测表(真实 Desktop
     构建 CDP 测量),非新设计色值;surface / focus-ring / error 未覆盖,保持生产值。 */
  .scope-test-light, .scope-test-dark {
    --focus-ring: #417CDD;
    --settings-bg: #f8f8f6;
    --surface-elevated: #ffffff;
    --settings-theme-card-bg: #faf9f5;
    --text-tertiary-mid: #525252;
    --settings-section-sublabel: var(--text-tertiary-mid);
    --error-border: rgba(220, 38, 38, 0.4);
    --error-fg: #dc2626;
  }
  .scope-test-light {
    --text-primary: #234567;      /* 全局覆盖:rgb(35,69,103) */
    --border-default: #56789A;    /* 全局覆盖:rgb(86,120,154) */
    --settings-theme-card-border: var(--border-default); /* 卡片边框随全局覆盖(真实链路) */
    --text-placeholder: #789ABC;  /* 全局覆盖:rgb(120,154,188) */
    --text-tertiary-stone: #345678; /* 全局覆盖(通用 Input 焦点边框):rgb(52,86,120) */
    --settings-input-text: #654321;            /* 局部覆盖:rgb(101,67,33) */
    --settings-input-placeholder: #AA8866;     /* 局部覆盖:rgb(170,136,102) */
    --settings-input-border: #876543;          /* 局部覆盖:rgb(135,101,67) */
    --settings-input-border-focus: #A98765;    /* 局部覆盖:rgb(169,135,101) */
  }
  .scope-test-dark {
    --text-primary: #AACCEE;     /* 全局覆盖:rgb(170,204,238) */
    --border-default: #88AACC;   /* 全局覆盖:rgb(136,170,204) */
    --settings-theme-card-border: var(--border-default);
    --text-placeholder: #789ABC; /* 全局覆盖:rgb(120,154,188) */
    --text-tertiary-stone: #BBDDFF; /* 全局覆盖:rgb(187,221,255) */
    --settings-input-text: #EECBAA;            /* 局部覆盖:rgb(238,203,170) */
    --settings-input-placeholder: #AA8866;     /* 局部覆盖:rgb(170,136,102) */
    --settings-input-border: #BB9977;          /* 局部覆盖:rgb(187,153,119) */
    --settings-input-border-focus: #FFDDBB;    /* 局部覆盖:rgb(255,221,187) */
    --error-border: #7f1d1d;
    --error-fg: #f87171;
  }

  /* ============ 底部 token 对照表 ============ */
  .token-table { border-collapse: collapse; font-size: 12px; margin-top: 10px; width: 100%; }
  .token-table th, .token-table td { border: 1px solid #dedcd8; padding: 4px 8px; text-align: left; vertical-align: top; }
  .token-table th { background: #f6f5f2; font-weight: 600; }
  .footnote { font-size: 12px; line-height: 1.7; color: #525252; margin-top: 14px; }
</style>
</head>
<body>
<div class="page">
  <h1>DS-4b 设置输入框旧主题兼容 — 界面效果证据</h1>
  <p class="lede">
    受控组件样例:左右两列渲染同一份 <code>components/ui/input.tsx</code>(size lg,与四个真实接入点一致:
    AgentResourceSection 最大并发数,CollaborationSection 软/硬上限与空闲释放分钟),右列额外叠加
    <code>SettingsTextInput</code><code>LEGACY_INPUT_CHROME</code>。CSS 声明逐条对应组件 utility,
    色值取自 <code>themes/colors.ts</code><code>docs/design-evidence/2026-09-06/input-theme-compat.md</code> 的实测表。所有输入框均可点击聚焦,
    <code>:focus</code> 表现与「焦点」行一致。非完整设置页端到端截图。
  </p>

  <div class="panel">
    <h2>面板一 · 内置主题(无局部覆盖)</h2>
    <p class="panel-note">
      <code>settings-input-*</code> alias 无覆盖时 forward-resolve 到 Tier-1 —— 两列逐值相同,
      对应回归测试「内置主题同值」;即未自定义主题的用户看不到任何变化。
    </p>
    <div class="modes">
      <div class="mode-card scope-builtin-light">
        <p class="mode-title">Light</p>
        <div class="app-card">
          <div class="cols">
            <span></span>
            <span class="col-head">通用 Input(Tier-1 默认)</span>
            <span class="col-head">SettingsTextInput(兼容封装)</span>

            <span class="row-label">正常(有值)</span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4"></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4"></span>

            <span class="row-label">空值 + placeholder</span>
            <span class="input-shell"><input class="cindy-input" type="number" placeholder="未设置"></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" placeholder="未设置"></span>

            <span class="row-label">焦点<small>静态呈现,点击任意框可复现</small></span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4" data-static-focus></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4" data-static-focus></span>

            <span class="row-label">错误态<small>边框/焦点切 --error-*,优先于局部样式</small></span>
            <span class="input-shell"><input class="cindy-input is-error" type="number" value="404"></span>
            <span class="input-shell"><input class="cindy-input settings-input is-error" type="number" value="404"></span>

            <span class="row-label">禁用态</span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4" disabled></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4" disabled></span>
          </div>
        </div>
      </div>
      <div class="mode-card scope-builtin-dark">
        <p class="mode-title">Dark</p>
        <div class="app-card">
          <div class="cols">
            <span></span>
            <span class="col-head">通用 Input(Tier-1 默认)</span>
            <span class="col-head">SettingsTextInput(兼容封装)</span>

            <span class="row-label">正常(有值)</span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4"></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4"></span>

            <span class="row-label">空值 + placeholder</span>
            <span class="input-shell"><input class="cindy-input" type="number" placeholder="未设置"></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" placeholder="未设置"></span>

            <span class="row-label">焦点<small>静态呈现,点击任意框可复现</small></span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4" data-static-focus></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4" data-static-focus></span>

            <span class="row-label">错误态<small>边框/焦点切 --error-*,优先于局部样式</small></span>
            <span class="input-shell"><input class="cindy-input is-error" type="number" value="404"></span>
            <span class="input-shell"><input class="cindy-input settings-input is-error" type="number" value="404"></span>

            <span class="row-label">禁用态</span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4" disabled></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4" disabled></span>
          </div>
        </div>
      </div>
    </div>
  </div>

  <div class="panel">
    <h2>面板二 · 受控测试主题(全局覆盖 + 设置域局部覆盖)</h2>
    <p class="panel-note">
      同一主题同时提供两组故意不同的覆盖:全局 Tier-1 覆盖为<strong>蓝系</strong>(通用 Input 跟随),
      <code>settings-input-*</code> 局部覆盖为<strong>棕系</strong>(仅设置域输入消费)——以此证明作用域隔离:
      局部覆盖不会泄漏为通用 Input 的默认色。覆盖值即实测表数值,非新设计色;surface、focus-ring、error
      未覆盖,保持生产值。
    </p>
    <div class="modes">
      <div class="mode-card scope-test-light">
        <p class="mode-title">Light</p>
        <div class="app-card">
          <div class="cols">
            <span></span>
            <span class="col-head">通用 Input(跟全局蓝系覆盖)</span>
            <span class="col-head">SettingsTextInput(跟局部棕系覆盖)</span>

            <span class="row-label">正常(有值)</span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4"></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4"></span>

            <span class="row-label">空值 + placeholder</span>
            <span class="input-shell"><input class="cindy-input" type="number" placeholder="未设置"></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" placeholder="未设置"></span>

            <span class="row-label">焦点<small>静态呈现,点击任意框可复现</small></span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4" data-static-focus></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4" data-static-focus></span>

            <span class="row-label">错误态<small>边框/焦点切 --error-*,优先于局部样式</small></span>
            <span class="input-shell"><input class="cindy-input is-error" type="number" value="404"></span>
            <span class="input-shell"><input class="cindy-input settings-input is-error" type="number" value="404"></span>

            <span class="row-label">禁用态</span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4" disabled></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4" disabled></span>
          </div>
        </div>
      </div>
      <div class="mode-card scope-test-dark">
        <p class="mode-title">Dark</p>
        <div class="app-card">
          <div class="cols">
            <span></span>
            <span class="col-head">通用 Input(跟全局蓝系覆盖)</span>
            <span class="col-head">SettingsTextInput(跟局部棕系覆盖)</span>

            <span class="row-label">正常(有值)</span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4"></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4"></span>

            <span class="row-label">空值 + placeholder</span>
            <span class="input-shell"><input class="cindy-input" type="number" placeholder="未设置"></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" placeholder="未设置"></span>

            <span class="row-label">焦点<small>静态呈现,点击任意框可复现</small></span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4" data-static-focus></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4" data-static-focus></span>

            <span class="row-label">错误态<small>边框/焦点切 --error-*,优先于局部样式</small></span>
            <span class="input-shell"><input class="cindy-input is-error" type="number" value="404"></span>
            <span class="input-shell"><input class="cindy-input settings-input is-error" type="number" value="404"></span>

            <span class="row-label">禁用态</span>
            <span class="input-shell"><input class="cindy-input" type="number" value="4" disabled></span>
            <span class="input-shell"><input class="cindy-input settings-input" type="number" value="4" disabled></span>
          </div>
        </div>
      </div>
    </div>
  </div>

  <div class="panel">
    <h2>Token 对照(本页用到的全部变量)</h2>
    <table class="token-table">
      <tr><th>变量</th><th>面板一 Light / Dark</th><th>面板二 Light / Dark(覆盖值)</th><th>来源</th></tr>
      <tr><td><code>--text-primary</code></td><td>#262626 / #d4d4d4</td><td>#234567 / #AACCEE(全局覆盖)</td><td>colors.ts · 实测表</td></tr>
      <tr><td><code>--border-default</code></td><td>#d7d7d4 / #3c3c3a</td><td>#56789A / #88AACC(全局覆盖)</td><td>colors.ts · 实测表</td></tr>
      <tr><td><code>--text-tertiary-stone</code></td><td>#737373 / #737373</td><td>#345678 / #BBDDFF(全局覆盖,通用 Input 焦点边框)</td><td>colors.ts · 实测表</td></tr>
      <tr><td><code>--text-placeholder</code></td><td>#c4c4c4 / #525252</td><td>#789ABC / #789ABC(全局覆盖)</td><td>colors.ts · 实测表</td></tr>
      <tr><td><code>--settings-input-text</code></td><td>→ --text-primary</td><td>#654321 / #EECBAA(局部覆盖)</td><td>colors.ts 默认 · 实测表</td></tr>
      <tr><td><code>--settings-input-border</code></td><td>→ --border-default</td><td>#876543 / #BB9977(局部覆盖)</td><td>colors.ts 默认 · 实测表</td></tr>
      <tr><td><code>--settings-input-border-focus</code></td><td>→ --text-tertiary-stone</td><td>#A98765 / #FFDDBB(局部覆盖)</td><td>colors.ts 默认 · 实测表</td></tr>
      <tr><td><code>--settings-input-placeholder</code></td><td>→ --text-placeholder</td><td>#AA8866 / #AA8866(局部覆盖)</td><td>colors.ts 默认 · 实测表</td></tr>
      <tr><td><code>--surface-elevated</code>(输入底色)</td><td>#ffffff / #2c2c2a</td><td>未覆盖,同左</td><td>colors.ts</td></tr>
      <tr><td><code>--focus-ring</code>(2px 焦点环)</td><td>#417CDD / #417CDD</td><td>未覆盖,同左</td><td>colors.ts</td></tr>
      <tr><td><code>--error-border</code> / <code>--error-fg</code></td><td>rgba(220,38,38,.4)·#dc2626 / #7f1d1d·#f87171</td><td>未覆盖,同左</td><td>colors.ts</td></tr>
      <tr><td><code>--settings-bg</code> / 卡片底 <code>--settings-theme-card-bg</code></td><td>#f8f8f6·#faf9f5 / #1f1f1e·#2c2c2a</td><td>同左(卡片边框随全局覆盖变蓝,真实链路)</td><td>colors.ts</td></tr>
    </table>
    <p class="footnote">
      几何与字号(DESIGN.md §4 / tailwind.config.ts):单行胶囊 9999px;sm/md/lg = 32/36/40px;
      本页四个真实接入点均为默认 lg = 40px 高、14px 字号、左右 12px 内边距。禁用态 60% 不透明度。
      页面文档外壳(本段排版用白底与灰字)不属于被证据的 App UI。
    </p>
  </div>
</div>
</body>
</html>

怎么验证的

自动验证

pnpm test:unit:related
pnpm --filter desktop run --if-present typecheck
pnpm --filter mobile typecheck
pnpm check:endpoints
pnpm check:i18n
pnpm check:brand-terminology
pnpm check:i18n-glossary
pnpm --filter desktop db:validate
pnpm ci:scheduler-guard
pnpm --filter mobile test:scope
pnpm check:design-inventory
pnpm check:dco
结果:通过。
  • 提交基于最新 origin/main f045326f1e;模拟合并所得树与候选树相同,合并后的 Desktop 类型检查通过。
  • 新增兼容测试覆盖两模式、全局/局部并存、缺新 placeholder slot 的旧文件、完整导出副本、重复加载、磁盘字节不变、内置主题同值及错误态优先。
  • 相关测试曾在提示气泡首次聚焦处偶发失败;该测试 helper 现在复用已有初始焦点等待,避免弹窗下一帧聚焦名称框与帮助按钮操作竞争。原交互断言与默认超时保留,最终默认并发门禁通过。

手工验证

独立 Desktop dev 沙箱启动 ready、身份校验 MATCH;Light / Dark 下测量并目检文字、边框、placeholder、focus、错误及禁用态。截图使用故意不同的全局/局部测试色;不是新增设计色值。

未执行的验证

  • 完整登录后的设置页端到端及全部内置主题实机遍历未执行;沙箱停留在登录协议前,未代用户同意。内置主题同值由自动测试覆盖。
  • Linux / Windows 完整单测及打包验证交由 CI;本地执行相关单测。
  • 截图附件未上传,不将其登记为已完成上传;界面效果以 description 内的 HTML 证据页交付(色值经真实 Chromium 逐项核对,见「UI 变化」)。

风险

风险分类

  • 其他:旧自定义主题局部配色恢复,属于有意可见变化。

影响与回滚

  • 影响范围:原 SettingsTextInput 消费者及四个原 settings alias 数字输入;通用 Input 默认、错误态和焦点环保持现有合同。无用户数据/存量插件迁移。
  • 回滚 / 降级方式:独立 revert 本 PR 即可恢复 DS-4 的直接标准 Input 消费;用户主题文件没有写回,无需数据回滚。回滚会重新失去本批恢复的局部配色效果。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s
  • UI 改动已注明设计规范章节
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

目标: 恢复旧设置输入框的局部主题配色兼容。
非目标: 不修改通用 Input 的默认配色,不改写用户主题文件,不执行跨域 alias 全族迁移。
验收: 旧主题覆盖在亮暗模式生效,错误态优先,相关测试及类型检查通过;如实记录完整页面与附件上传缺口。

Signed-off-by: kirozeng <kirozeng@gmail.com>
@kirozeng
kirozeng requested a review from a team as a code owner September 6, 2026 12:04
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@greptile-apps

greptile-apps Bot commented Sep 6, 2026

Copy link
Copy Markdown

Greptile Summary

本 PR 恢复设置输入框对旧 settings-input-* 局部主题 alias 的消费,同时保持通用 Input 的 Tier-1 默认和标准错误态优先级。

  • 新增 SettingsTextInput 薄封装,并通过 inputClassName 注入旧设置域文字、边框、焦点边框及 placeholder 绑定。
  • AgentResource 与 Collaboration 的四个数字输入切换到该封装。
  • 增加本地主题加载、亮暗模式、局部与全局覆盖、错误态及内置主题一致性的回归测试。
  • 更新设计规范、治理台账和验证证据。

Confidence Score: 5/5

未发现由本 PR 引入的具体缺陷,当前改动看起来可以安全合并。

设置域 alias 的注入、主题解析、属性透传和样式优先级形成了完整路径;新增测试覆盖了主要兼容场景,且通用 Input 默认与错误态合同未被改变。

Important Files Changed

Filename Overview
apps/desktop/src/renderer/components/settings/SettingsTextInput.tsx 将原直接重导出改为保留旧设置域主题 alias 的薄封装,并完整透传标准 Input 属性。
apps/desktop/src/renderer/components/ui/input.tsx 新增内层 input 样式扩展入口,合并顺序确保局部封装覆盖默认样式且错误态最终优先。
apps/desktop/src/renderer/components/ui/tests/inputThemeCompatibility.test.tsx 覆盖真实本地主题加载链、亮暗模式、alias 作用域、内置主题同值和错误态优先级。
apps/desktop/src/renderer/components/settings/AgentResourceSection.tsx 将一个既有数字输入接入设置域兼容封装,其他属性和交互保持不变。
apps/desktop/src/renderer/components/settings/CollaborationSection.tsx 将三个既有数字输入接入设置域兼容封装,保留原数值约束与更新行为。

Reviews (1): Last reviewed commit: "fix(design-system): DS-4b 设置输入框旧主题兼容收口" | Re-trigger Greptile

@MagicLizi MagicLizi added status:ci-running CI 还在跑(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) labels Sep 6, 2026
@kirozeng

kirozeng commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

已核实本轮反馈,无需代码改动。

本轮新增的两条评论都是机器人消息:一条是 Codex 用量提醒,不涉及代码;另一条是 Greptile 复审摘要,置信 5/5,未发现本 PR 引入的缺陷,结论是可以安全合并。

PR 现状:head 仍是 3c959f2,client-ci、DCO、pr-design-basis 全部通过,也没有人工 review 提出的待办。因此本轮维持现状,不追加提交。

dispatch:9e13d67461ece753

@MagicLizi MagicLizi removed the status:ci-running CI 还在跑(review-pr 自动维护,仅展示) label Sep 6, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

命中 UI 路径(apps/desktop/src/renderer/components/settings/AgentResourceSection.tsx / apps/desktop/src/renderer/components/settings/CollaborationSection.tsx / apps/desktop/src/renderer/components/settings/SettingsTextInput.tsx 等)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码重审通过:当前 head 未发现 P0/P1,全部 conversation 已 resolve。设置输入框旧主题走 --settings-input-* alias,通用 Input 仍绑 Tier-1;测试夹具写临时主题 JSON,不是外发。

@kirozeng

kirozeng commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

已按 UI 证据提醒把界面效果证据补进 description:在「UI 变化」段末尾附了一张自包含的 HTML 复刻页(```html 代码块,保存为 .html 用浏览器打开即可查看)。

这张页面怎么来的:DOM 与样式逐条对应 components/ui/input.tsx 的真实 utility(lg 档 40px/14px/胶囊圆角),色值全部取自 themes/colors.ts 与 docs/design-evidence/2026-09-06/input-theme-compat.md 的实测表,没有新造颜色。页面展示两组对照——内置主题(两列逐值相同,对应「内置主题同值」测试)和受控测试主题(全局蓝系覆盖 vs 设置域棕系局部覆盖,证明作用域隔离),各含 Light/Dark 与正常/placeholder/焦点/错误/禁用五种状态,底部附 token 对照表。

怎么验证的:在真实 Chromium 里渲染该页面并逐项读取 computed style,与实测表核对——56/56 通过(文字/边框/placeholder/焦点边框/焦点环/错误优先级/几何/禁用透明度)。

如实说明边界:截图附件仍未上传(此前仅本地目检,本次未补传);这张 HTML 页是受控组件样例,不是登录后完整设置页的端到端截图;本轮验证是机器核对(computed style 逐项一致),像素级人工目检未执行。description 中「未执行的验证」一节已同步更新。

dispatch:ebcda2034660a49a

@MagicLizi
MagicLizi merged commit e9c3729 into makecindy:main Sep 6, 2026
12 checks passed
@MagicLizi

Copy link
Copy Markdown
Contributor

旧主题下的设置输入框终于跟通用 Input 各归各位了,局部配色还在、通用件也不再被带跑。谢谢这次把兼容合同写进规范。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants