---
"@ux-team/tvu-design-system": patch
---

组件选型契约补一条「表单字段族按主题定、且同一界面内不混用」（owner 2026-08-31 裁定）。

**缘起**：owner 在 Claude Design 预览里看到同一个表单里线框（`InputBoxLine` = `<tvu-input>`）与
填充（`<tvu-select-box-filled>`）混用、视觉不统一。逐条查完**不是 AI 乱选** —— 契约层根本没给判据：
`component-affordances.json` 里 line/filled 四条 `when_to_use` 是互指式（「线框风格…深底填充风格用 X」
↔ 反过来再说一遍），driver `conventions.md` 那条 Forms 规则把两族**并列**，全仓没有一句说不许混用。

**裁定与规则**：族由**主题**决定 —— 深色主题（默认 `:root`）用 filled，浅色主题（`[data-theme="light"]`）
用 line；一个界面只有一个主题，所以**同一表单 / 面板内混用即为 bug**。数值录入仍是 `InputNumber`
（它没有 line/filled 之分）。

**为什么是主题条件式而不是单选一族**（量自 token，非口味）：填充底 `--input-filled-bg` 在 dark 解析为
`--bg-layer4` `#353535`，与页面层 `#141414` / `#1f1f1f` 有真实层次；在 light 解析为 `--bg-layer1`
`#ffffff`，与页面底**同色**，只剩边框可见 —— `src/components/Input/Input.vue` 的样式注释逐字写着
"border visible in light"。⇒ 浅色主题下 filled 退化成 line 的观感，等于用更重的组件拿同样的视觉。

**顺带治一条命名陷阱**：`InputBoxLine` 的 CE tag 是全套里最朴素的 `tvu-input`（filled 版叫
`tvu-input-box-filled`），而 select 两侧对称（`tvu-select-box-line` / `-filled`）。这次混用的另一半成因
就是「名字最短 ⇒ 当成默认」。两处规则都显式写了 ⛔ 别这么读 —— 默认由主题定，不由 tag 名定。

**落点两处，分属两个通道**（`composition.json` **不是**第三个落点：`generate-composition-exports.mjs`
读的 srcPath 就是 `component-affordances.json`，它是派生物）：
- `docs/internal/component-affordances.json` 六条 entry（4 条消费级 + 2 条 base 的指向语）
  → 经 `pnpm generate:component-affordances` 出 `.md` 视图、经 `generate-composition-exports.mjs`
  出 **consumer-facing 的 `./composition` 出口**（`dist/composition/composition.json`），也是 bundle 通道
  `reference/02` 的来源。
- `.design-sync/conventions.md` 的 Forms 规则 → driver 通道的 `readmeHeader`，盖进远端 `README.md`，
  即设计 agent 的 system prompt。

闸：`audit:component-affordances` PASS（39 entries，coverage 39/39，props + MD 一致）·
`audit:composition-exports` PASS。
