Skip to content

Commit bb12bed

Browse files
committed
docs(frontend): define canonical component standards
1 parent 2e97a17 commit bb12bed

2 files changed

Lines changed: 182 additions & 9 deletions

File tree

frontend/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ for VeADK Studio, including these non-negotiable rules:
9797
- New or updated product icons must be repository-owned, hand-drawn SVG React
9898
components. Do not add generic icon-library, emoji, or remote-icon usage.
9999
- Reuse the existing semantic color tokens, restrained enterprise-workbench
100-
visual language, bounded scrolling regions, and accessible interaction states.
100+
visual language, component inventory, typography and control-size scale,
101+
bounded scrolling regions, and accessible interaction states.
101102
- Feature configuration must remain explicit in its domain section and runtime
102103
environment summary; secrets must never enter generated source, browser
103104
persistence, logs, documentation, or committed files.

frontend/SPEC.md

Lines changed: 180 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,74 @@ hsl(var(--destructive))
135135
- 新增动效必须支持 `prefers-reduced-motion: reduce`
136136
- 动效不得阻塞点击、输入、导航或错误阅读。
137137

138+
### 3.6 可执行视觉度量基线
139+
140+
以下数值来自当前 Studio 的 Sidebar、Navbar、Composer、Agent 选择器、创建工作台
141+
和工具调用组件。新增组件必须从这些层级中选择,不得为单个页面随意创造新的字号、
142+
高度或圆角。已有非标准值不要求一次性重构;修改相关组件时应迁移到最近的层级。
143+
144+
#### 字号、行高与字重
145+
146+
| 层级 | 字号 | 建议行高 | 建议字重 | 典型用途 |
147+
| --- | --- | --- | --- | --- |
148+
| 展示标题 | `26px` | `1.2` | `600` | 新会话欢迎标题;不得用于普通页面 |
149+
| 页面标题 | `20px``21px` | `1.25` | `600``650` | 独立工作区、结果页主标题 |
150+
| 区域标题 | `17px` | `1.3` | `600` | 创建工作台区块、重要对话框标题 |
151+
| 强调文字 | `15px` | `1.4``1.5` | `500``600` | Composer 输入、Navbar 标题、主要选择项 |
152+
| 正文 | `13px``14px` | `1.5``1.65` | `400``500` | 表单内容、菜单、列表、说明文字 |
153+
| 紧凑正文 | `12px``12.5px` | `1.45``1.55` | `400``550` | 配置项、次级按钮、列表元信息 |
154+
| 辅助信息 | `11px``11.5px` | `1.35``1.5` | `400``500` | Session、时间、环境变量 |
155+
| Badge | `9.5px``10.5px` | `1.2``1.4` | `500``600` | 状态、Beta;禁止长文案 |
156+
157+
- 工具调用标题使用 `13px``13.5px``400` 字重,不得加粗。
158+
- 模型名、Agent 名、Runtime 名和 Session ID 默认使用继承字体;只有真实代码、命令、
159+
日志和代码编辑器可以使用等宽字体。
160+
- 中文正文不得小于 `12px``11px` 以下只允许短元信息和 Badge。
161+
- 标题不通过连续增加字重制造层级。相邻层级优先使用字号、颜色和间距区分。
162+
- 单行文字必须与同排图标共享 Flex/Grid 居中容器;禁止用任意 `translateY` 修正普通
163+
图标。确需光学校正时,必须局部作用于具体图标,并增加回归测试。
164+
165+
#### 控件和布局尺寸
166+
167+
| 对象 | 基线尺寸 | 说明 |
168+
| --- | --- | --- |
169+
| Navbar / 品牌栏 | `54px`| 左右区域必须垂直居中 |
170+
| Sidebar | `236px` 宽,折叠后 `56px` | 窄桌面可按现有断点收窄 |
171+
| 普通输入框 / 按钮 | `34px``36px`| 同一操作行必须统一高度 |
172+
| 紧凑按钮 / 筛选项 | `28px``32px`| 只用于高密度工具栏和列表 |
173+
| 主要图标按钮 | `36px × 36px` | Composer 发送、附件等主要操作 |
174+
| 普通图标按钮 | 至少 `28px × 28px` | SVG 可以更小,点击区域不能随之缩小 |
175+
| 对话正文列 | 最大 `768px` | Composer、错误和 Transcript 对齐 |
176+
| 新会话 Composer | 最小 `136px`| 文本区最小 `76px`,底部操作区 `36px` |
177+
| 主内容面板 | `12px` 圆角、`1px` 边框 | 使用 `--panel``--border` |
178+
179+
- 标准图标为 `16px`;列表和工具图标可使用 `18px`;主要入口和 Composer 图标可使用
180+
`20px`。Chevron、Check 等辅助图标使用 `12px``15px`
181+
- 图标容器必须设置 `flex-shrink: 0`,并用 `inline-flex``inline-grid`
182+
`align-items: center``place-items: center` 对齐。
183+
- 页面级固定宽高必须来自现有布局约束;禁止用魔法数字补偿父容器错误。
184+
185+
#### 间距与圆角阶梯
186+
187+
- 首选间距为 `4px``6px``8px``10px``12px``16px``20px``24px`
188+
- `2px` 只用于同组紧密元素;`28px` 及以上只用于页面留白或主区块分隔。
189+
- 行内图标与文字通常使用 `6px``9px` Gap;同级按钮组通常使用 `8px`
190+
- 小型图标按钮和微型标签使用 `4px``6px` 圆角。
191+
- 输入框、普通按钮和列表项使用 `6px``9px` 圆角。
192+
- 菜单、卡片、抽屉和面板使用 `10px``14px` 圆角。
193+
- `16px` 及以上圆角只用于 Composer 或明确的大型容器;`999px` 只用于 Pill、Badge
194+
和圆形按钮。
195+
196+
#### 状态与交互样式
197+
198+
- Hover 只能改变颜色、背景、边框、透明度或轻微阴影,不得改变元素尺寸和排版。
199+
- 普通列表 Hover 使用低对比中性色;工具调用整行 Hover 只高亮文字,不增加背景。
200+
- Focus 必须可见,优先沿用 `2px` Ring 和 `1px` Offset 的现有模式。
201+
- Disabled 必须同时包含视觉弱化和不可点击语义,不得只改变颜色。
202+
- Selected、Active 和 Previewed 必须有稳定且不同的状态,不得依赖 Hover 表示选中。
203+
- 加载文字统一使用 `TextShimmer`;禁止在业务组件中重复实现渐变文字动画。
204+
- Spinner、Shimmer、旋转箭头和脉冲状态都必须在 Reduced Motion 下停止或降级。
205+
138206
## 4. 图标规范
139207

140208
### 4.1 产品图标必须自绘
@@ -233,6 +301,107 @@ export function ExampleIcon(props: SVGProps<SVGSVGElement>) {
233301
- 动态错误和校验信息应使用 `role="alert"``aria-live`
234302
- 点击区域不得小于当前同级控件的可用尺寸,图标按钮应保持稳定方形区域。
235303

304+
### 5.5 现有组件复用索引
305+
306+
新增 UI 前必须先检查以下组件。已有组件能够覆盖需求时,禁止复制 JSX 和 CSS 创建
307+
外观相似但行为不同的版本。
308+
309+
| 场景 | 优先复用 | 约束 |
310+
| --- | --- | --- |
311+
| 全局框架 | `Sidebar``Navbar``.main` | 不得另建第二套页面 Shell |
312+
| Agent 选择 | `AgentSelector``AgentIdentityIcon` | Sidebar 与输入框可以有独立作用域样式 |
313+
| 会话输入 | `Composer``NewChatModeSelector` | 保留 IME、键盘、附件和发送状态行为 |
314+
| 临时会话 | `SandboxLaunchDialog``SandboxSession` | 不得复用普通 ADK Session 流程 |
315+
| Skill A/B 创建 | `SkillCreateWorkspace``SkillCandidatePane` | 保持双流输出、模型名和预览切换 |
316+
| 工具调用 | `BuiltinToolHeader``ui/builtin-tools/` | 新内置工具通过 Registry 扩展 |
317+
| 加载文字 | `TextShimmer` | 不得新增独立 Shimmer 实现 |
318+
| Markdown | `Markdown``MarkdownPromptEditor` | 外部 Markdown 禁止启用原始 HTML |
319+
| 代码查看 | `CodeBrowserDialog``CodeEditor` | 不得用普通 Textarea 冒充代码浏览器 |
320+
| 部署错误 | `DeploymentErrorMessage` | 保留展开、复制、重试和脱敏能力 |
321+
| Runtime / Agent 拓扑 | `AgentTopology``RuntimeIdentityIcon` | 状态色之外必须有文字或形状提示 |
322+
| 图片、音视频 | `Media` | 复用预览、加载、错误和移除行为 |
323+
| 搜索 | `Search` | 复用数据源可用性和显式提交逻辑 |
324+
| A2UI | `src/a2ui/components/` 与 Registry | Renderer 与后端 Catalog 同步更新 |
325+
326+
#### 基准样式映射
327+
328+
组件“对齐”不是只使用相近颜色,而是必须匹配参考实现的结构、尺寸、文字层级、图标、
329+
边框、圆角、弹层位置和完整交互状态。新增同类组件时按下表选择视觉基准:
330+
331+
| 组件族 | 当前视觉基准 | 必须保持一致的内容 |
332+
| --- | --- | --- |
333+
| 下拉选择 | `A2aSpaceSelect``.cw-a2a-space-*` | Trigger、Chevron、Menu、Option 和状态 |
334+
| 分段 Tab | Agent 类型 `.cw-typeradio-*` | 轨道、滑块、选项尺寸、选中和禁用状态 |
335+
| 表单字段 | `.cw-label``.cw-input``.cw-help` | 标签、输入、帮助和错误的纵向节奏 |
336+
| 主要按钮 | `.cw-btn``.cw-btn-primary` | 高度、字号、圆角、按下和禁用状态 |
337+
| 次级按钮 | `.cw-btn-ghost``.cw-btn-soft` | 中性背景、边框和 Hover 层级 |
338+
| 图标按钮 | `.cw-icon-btn` | 方形点击区、图标居中和危险态 |
339+
| 展开更多 | `.cw-more-options` | 无边框文字按钮、计数 Badge 和 Chevron |
340+
| 行内错误 | `.cw-banner``.cw-error-text` | 错误位置、字号、颜色和解释文案 |
341+
| 简单确认框 | `.confirm-*` | Scrim、内容宽度、标题和操作区 |
342+
| 复杂对话框 | `CodeBrowserDialog``.cw-skill-dialog` | Header、独立滚动区、关闭和焦点行为 |
343+
344+
基准实现以当前源码为准:A2A 下拉位于 `src/create/CustomCreate.tsx`
345+
`A2aSpaceSelect``src/create/CustomCreate.css``.cw-a2a-space-*`;Agent 类型分段
346+
控件位于相同文件的 `.cw-typeradio-*`。实现新组件时按以下顺序决策:
347+
348+
1. 业务语义和交互一致时,直接复用现有组件。
349+
2. 数据来源不同但展示和键盘行为一致时,提取共享展示组件,领域请求仍保留在功能目录。
350+
3. 只有现有模式无法满足产品要求时才新建模式,并在 PR 中说明差异和无法复用的原因。
351+
4. 基准实现与本文档不一致时不得静默选择;应在同一改动中修正文档或实现。
352+
353+
下拉选择必须以 A2A 中心选择器为基准:
354+
355+
- Trigger 为 `36px` 高、`6px` 圆角、`1px --border`,左右 Padding 与文字基线一致。
356+
- Trigger 文字使用 `12px`;Placeholder 使用 `--muted-foreground` 和普通字重。
357+
- Chevron 为仓库内自绘 SVG,使用 `18px` 视觉框;展开时旋转,不更换另一枚图标。
358+
- Menu 位于 Trigger 下方 `6px`,宽度与 Trigger 一致,最大高度 `238px`,内部
359+
Padding 为 `4px`
360+
- Option 最小高度 `34px``4px` 圆角、`12px` 字号;Hover、Focus 和 Selected
361+
使用中性背景,不使用高饱和填充。
362+
- 必须覆盖 Default、Hover、Focus、Open、Selected、Disabled、Loading、Empty 和
363+
Error;长选项必须省略并能通过 `title` 或详情查看全文。
364+
- 新增第二个相同交互的下拉框时,应提取共享的展示与键盘行为,而不是复制整段 CSS;
365+
领域数据加载和文案仍保留在各自组件内。
366+
367+
分段 Tab 必须以 Agent 类型切换为基准:
368+
369+
- 外层轨道为 `44px` 高、`4px` Padding、`4px` Gap、`10px` 圆角,使用弱化的
370+
`--secondary` 背景和低对比边框。
371+
- 选中滑块距离轨道四边 `4px`,使用白色背景、`7px` 圆角和轻边框。
372+
- 单项最小高度 `34px`,文字使用 `12px``13px``500``600` 字重。
373+
- Hover 只使用极浅中性背景;选中态主要通过滑块、前景色和字重表达。
374+
- 滑块移动沿用 `0.24s cubic-bezier(0.22, 1, 0.36, 1)`,Reduced Motion 下取消。
375+
- 视觉样式与语义必须分开:互斥配置使用 `radiogroup` / `radio`,页面切换使用
376+
`tablist` / `tab` / `tabpanel`,不能为了复用样式使用错误的 ARIA Role。
377+
- Tab 数量变化时必须重新计算等分宽度和滑块偏移;窄窗口不能出现文字互相覆盖。
378+
379+
- 领域组件放在对应功能目录;只有跨两个以上领域稳定复用的组件才放入 `src/ui/`
380+
- 功能专属 CSS 与组件同目录;`src/styles.css` 只承载全局变量、Shell 和真正共享样式。
381+
- 组件通过 Props 接收业务状态,不得在纯展示组件内重新请求同一份数据。
382+
- 同一视觉状态使用 `is-active``is-open``is-done` 等明确类名或 `data-*` 属性,
383+
不使用依赖 DOM 层级的模糊选择器表达业务状态。
384+
- 运行时测量得到的坐标和尺寸可以使用 Inline Style;固定颜色、字号、圆角和间距必须
385+
写入 CSS,不得散落在 JSX 中。
386+
387+
### 5.6 基础组件状态契约
388+
389+
所有新增或修改的交互组件必须覆盖适用的状态:
390+
391+
| 组件类型 | 必须覆盖的状态 |
392+
| --- | --- |
393+
| Button | Default、Hover、Focus、Active、Disabled、Loading |
394+
| Input / Textarea | Empty、Filled、Focus、Disabled、Invalid、IME Composition |
395+
| Select / Menu | Closed、Open、Keyboard Active、Selected、Disabled、Empty |
396+
| List | Loading、Data、Empty、Error、Selected、Pagination |
397+
| Dialog / Drawer | Opening、Open、Closing、Focus Return、Escape、Outside Click |
398+
| Async Task | Preparing、Running、Success、Failed、Cancelled、Retrying |
399+
400+
- Loading 状态不得清空已有数据;刷新列表时应尽量保留可读内容。
401+
- Error 必须出现在发生问题的组件附近;全局错误只用于影响整个页面的故障。
402+
- Empty 表示请求成功但没有数据,不能用于表示无权限、未配置或请求失败。
403+
- Disabled 控件如果由配置缺失导致,必须说明“为什么不可用”和“如何恢复”。
404+
236405
## 6. Agent 创建与配置规范
237406

238407
### 6.1 配置必须显式
@@ -350,21 +519,24 @@ AI 每次开发任务必须按以下顺序执行:
350519

351520
1. 阅读相关组件、类型、样式、测试和后端接口。
352521
2. 明确需求边界、假设和可验证成功标准。
353-
3. 选择最小实现,说明会影响的代码生成、Runtime 或安全边界。
354-
4. 先补充复现测试或契约测试,再实现功能。
355-
5. 使用现有视觉变量和组件完成 UI,产品图标必须自绘。
356-
6. 验证加载、错误、空状态、取消、重试、窄窗口和键盘行为。
357-
7. 运行测试、构建、Ruff、Pyright、文档检查和密钥扫描。
358-
8. 检查 Diff,删除仅由本次改动产生的无用代码,不处理无关历史问题。
359-
9. 更新 `frontend/README.md` 和相关用户文档。
360-
10. 在 PR 中列出实际验证结果和仍未覆盖的限制,禁止夸大完成度。
522+
3. 找到同类基准组件,记录需要对齐的结构、尺寸和状态;没有基准时才提出新模式。
523+
4. 选择最小实现,说明会影响的代码生成、Runtime 或安全边界。
524+
5. 先补充复现测试或契约测试,再实现功能。
525+
6. 使用现有视觉变量和组件完成 UI,产品图标必须自绘。
526+
7. 验证加载、错误、空状态、取消、重试、窄窗口和键盘行为。
527+
8. 运行测试、构建、Ruff、Pyright、文档检查和密钥扫描。
528+
9. 检查 Diff,删除仅由本次改动产生的无用代码,不处理无关历史问题。
529+
10. 更新 `frontend/README.md` 和相关用户文档。
530+
11. 在 PR 中列出实际验证结果和仍未覆盖的限制,禁止夸大完成度。
361531

362532
## 13. PR 审查清单
363533

364534
- [ ] 改动与需求直接相关,没有无关重构。
365535
- [ ] 所有新增产品图标均为仓库内自绘 SVG。
366536
- [ ] 没有新增通用图标库用法、Emoji 图标或远程图标。
367537
- [ ] 使用现有颜色、间距、圆角和状态模式。
538+
- [ ] 新增下拉、分段 Tab、表单或对话框已与对应基准组件逐项对齐。
539+
- [ ] 没有复制一套近似 CSS;第二个同类组件已复用或提取共享展示行为。
368540
- [ ] 键盘、IME、焦点和无障碍属性完整。
369541
- [ ] 加载、空状态、错误、重试和取消路径完整。
370542
- [ ] 配置在功能区域与环境变量摘要中均可见。

0 commit comments

Comments
 (0)