Files
mini-openclaw/docs/project-process/04-ui-spec.md
T
2026-09-28 16:34:10 +08:00

117 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 阶段 ④ UI Spec — UI 规则定义与约束规范
> **定义**:定义每个交付面的 UI 行为与视觉约束,让 UI 实现者(人或 agent)不发明任何决策:页面骨架、组件粒度、状态机、动作权限由**表面规格(Surface Specification)** 规定;颜色/字号/间距/组件形态由**设计系统契约(DESIGN.md)** 规定。
> **输入**:① 规格 §3(Surface Specification)+ ②/③ 的接口契约(UI 消费的字段)。
> **输出**:表面规格 + DESIGN.md(含 token)+ i18n 约束。
> **进入下一阶段(⑤ 实现)**:状态机、动作权限、设计 token、i18n 全部定案。
> 适用判定:本阶段仅当改动拥有用户可见 UI(web 界面、Electron 窗口、设置面板、硬件设备界面)时强制;纯后端/网关/CLI 改动标记 `not applicable`。
---
## 1. 要求(Requirements)
### 1.1 进入条件
- 规格 §3 已定义交付面清单与每个面的消费字段(字段有类型、可空性、枚举值)。
- 项目已有或需要建立视觉事实源(`DESIGN.md` / 主题变量 / 组件库)。
### 1.2 完成条件(DoD)
- [ ] 每个交付面有:页面骨架 + 组件粒度边界 + 完整状态机 + 动作×权限表
- [ ] 每个 UI 提交/展示的字段能在规格 §2 找到(契约门)
- [ ] 视觉 token(颜色/字号/间距/圆角/组件)有语义化来源,不出现临时发明的 `blue500` 类裸色
- [ ] 全部 UI 文案走 i18n(本仓:`packages/web-ui/src/i18n/messages.ts`,zh-CN/en-US 双语),无硬编码用户可见字符串
- [ ] 可访问性约束写明:对比度(WCAG AA)、focus-visible、颜色不单独承载状态、reduced-motion
- [ ] 异常态(加载/空/错误/禁用/提交中)有明确视觉与文案定义(对应规格 `E-*`)
---
## 2. 规则(Rules)
### 2.1 表面规格规则(Surface Specification)
| 编号 | 规则 |
|---|---|
| R-4.1 | **骨架先行**:每个交付面先定页面骨架(区域划分),再定组件,禁止直接进入像素级布局。 |
| R-4.2 | **组件粒度即所有权边界**:明确"哪个组件拥有哪个状态"(如筛选条是查询条件的唯一事实源、表格不持有选择集)。组件不得越界:表格不能清空选择,只能向拥有者发请求。 |
| R-4.3 | **状态机完整**:`Idle/Loading/Ready/Empty/Error/Submitting` 等状态全列;`Loading`(骨架屏)与 `Submitting`(保留现有内容+禁用交互)是不同状态,不得合并。 |
| R-4.4 | **动作×权限表**:每个动作列角色与禁用条件(如"Auditor 看到页面但没有动作控件,而非禁用按钮")。 |
| R-4.5 | **交互约束显式**:URL 持有可分享状态、筛选变更清空选择、选择集不跨页、破坏性操作需确认且写明数量——写成条目,不留给实现。 |
| R-4.6 | **截图不是 spec**:图片可表达布局,但必须同时有规则、状态转换、权限(R-1.7 在 UI 层同样生效)。 |
### 2.2 设计系统规则(DESIGN.md / 视觉 token)
| 编号 | 规则 |
|---|---|
| R-4.7 | **视觉事实源唯一**:有 UI 的项目维护唯一的视觉 token 事实源(本仓现状:`packages/web-ui/src/theme/tokens.css`,语义 token + CSS 变量,经 `styles.css` `@import` 消费;若将来建根级 `DESIGN.md` 则与之对齐);禁止在组件里临时发明颜色/间距/字号。 |
| R-4.8 | **语义 token 优先**:token 用语义角色(`primary`/`surface`/`danger`),不用调色板名(`teal-500`);组件 token 带状态(如 `button-primary-hover`、`text-input-focused`)。 |
| R-4.9 | **token 可导出可防漂移**:token 能导出为 CSS 变量/主题,并用 lint/diff/单测检查漂移(本仓:`tokens.css` 变量 + `styles.test.ts` 等单测守卫;`useAppearance.ts` 归一化主题 id);"文件存在"不等于"被使用"(G-3)。 |
| R-4.10 | **可访问性硬约束**:正文与 focus 态满足 WCAG AA 对比度;错误/成功/选中状态不得只靠颜色表达;支持 reduced-motion;表单与错误态有明确指引。 |
| R-4.11 | **不强推框架外规范**:后端/CLI/纯数据项目标记 `not applicable`,不套用视觉契约。 |
### 2.3 i18n 规则
| 编号 | 规则 |
|---|---|
| R-4.12 | 所有用户可见文案走 key 化翻译(本仓:`packages/web-ui/src/i18n/messages.ts`,扁平 key + `t(key, params?)`,key 按命名空间组织:`common.*`/`task.*`/`settings.*`/`shell.*`/`inspector.*`/`mode.*`);禁止硬编码中文/英文串。 |
| R-4.13 | 多语言文案与 UI 状态同步维护;新增文案必须同时补齐既有语言包。 |
| R-4.14 | 设备端/子窗口界面不做 i18n 决策,文案由宿主统一注入(避免每窗口维护语言状态)。 |
---
## 3. 输出规范
### 3.1 表面规格结构(每个交付面一份)
```text
Skeleton 页面骨架:区域划分与信息层级
Component 组件粒度:组件清单 + 各自拥有的状态 + 不允许越界的边界
Granularity
State Machine 状态全集 + 合法转换 + 每个状态的禁用手势(表格或图)
Actions & Guards 动作 × 角色 × 禁用条件(含"只读角色无控件而非禁用")
Interaction 交互约束:URL 状态、选择集规则、确认对话框、虚拟化/固定行高、截断策略
Constraints
```
> 模板参考:`vendor/better-harness/references/bootstrap/examples/frontend-web-spec.md` 的 §3(复用结构,内容必须基于本仓事实)。
### 3.2 DESIGN.md 结构
```text
frontmatter(机器可读) colors / typography / rounded / spacing / components
(顶层组,语义角色 + 组件状态 token,支持 {colors.primary} 引用)
Markdown(人读) Overview / Colors / Typography / Layout / Elevation & Depth /
Shapes / Components / Do's and Don'ts
+ 可访问性(对比度、focus-visible、color-not-alone、reduced-motion)
+ 每个 token 的"何时用 / 何时不用 / 防止什么 agent 错误"
```
> 完整示例:`vendor/better-harness/case-studies/project-harness/design-md-complete-example.md`(结构性回退模板,数值必须替换为本仓已核实的来源)。若项目尚无 DESIGN.md:从现有代码/主题推断并标注"推断",未决品牌决策标记 `needs-design-decision`,禁止编造。
### 3.3 交付物清单
- 每个交付面的表面规格
- `DESIGN.md`(若建)或其缺失项清单;本仓现状:视觉 token 事实源为 `packages/web-ui/src/theme/tokens.css`(含证据分级:Present / Structured / Token-ready / Agent-ready / Aligned / Backstopped)
- i18n key 清单(新增/变更)
- UI 验收映射:表面规格的每条交互约束 ↔ 规格 `AC-xx` ↔ [06-validation.md](06-validation.md) 的测试点(组件/E2E)
---
## 4. UI 验证约束(预置,详见阶段 ⑥)
- UI 验证分驱动平面(D0 进程内渲染树 → D1 浏览器自动化协议 → D2 附加运行中浏览器 → D3 OS 输入/无障碍 → D4 物理设备),选满足声明的最便宜平面,失败再升级。
- **驱动与观察分离**:同一模型既驱动 UI 又目测自己的截图 = 无独立裁判,不能算 pass(`Self-reported success` 反模式)。截图基线只追加不覆盖。
- 定位器禁止跨动作缓存(元素索引/坐标每次交互前重新读取);降级顺序:语义选择器 → 文本/aria → 原始坐标,并记录最终落到哪一级。
---
## 5. 轻量路径(小改动)
- 单组件样式调整:更新 DESIGN.md 对应 token + 表面规格的组件小节,不重写整份规格。
- 触碰多交付面、状态机重构、主题切换:必须完整走本阶段。
---
## 6. 相关文档
- 输入:阶段 ① [01-requirement.md](01-requirement.md) §3、阶段 ③ [03-detailed-design.md](03-detailed-design.md)
- 验证:阶段 ⑥ [06-validation.md](06-validation.md)(UI 驱动平面与裁判分离约束)