feat(ui): 自研 Celadon 组件族入库与 AntD 消费全量替换 - base(Kbd/StatusBadge/IconButton/ToolButton)+product(EmptyState/Callout/SegmentedControl/Checkbox/Select/Tooltip/Switch), composio 视觉基底, globals.css 覆盖清理 (ADR-0008)

This commit is contained in:
maomaochong-ai
2026-09-06 20:28:51 +08:00
parent 0dcd8e1c72
commit c3e2758736
128 changed files with 2791 additions and 737 deletions

View File

@@ -0,0 +1,101 @@
# ADR-0008: 自研 UI 组件层(Celadon UI)——吸收 dbx 组织纪律与 BoardUI 设计体系,分阶段替换 AntD
状态:已接受。日期:2026-09-05(初版);2026-09-05(修订 1:吸收 BoardUI 设计体系);2026-09-05(修订 2:视觉数值基准改为直接采用 composio-brand-package,见 D3 与「考虑过的方案」末条)。来源:`web/src/components/ui` 混乱整治;参考 dbx(`apps/desktop/src/components/ui`)、BoardUI(`boardui/`)的组织形态与设计纪律,以及 composio-brand-package(`../../../composio-brand-package/`,与 open-ai-canvas 同级的兄弟目录,设计 token 唯一数值权威源);AntD 依赖面证据来自清点脚本复核(数字见「背景」)。
## 背景
`web/src/components/ui` 混乱、不统一的根因不是缺组件,而是缺一层有纪律的自研组件契约:
- `components/ui/` 目前几乎全是**一次性装饰件**(`aceternity/` 下的 comet-card、floating-dock、spotlight-surface 等,另有顶层 `animated-theme-toggler`、`announcement-content`、`dia-text-reveal`),深路径引用,无目录规范、无变体契约、无统一导出。
- 工作台高频交互件(画布工具条按钮、工具激活态、状态/节点徽章、空态、加载态、截断文本提示等)无归属,散落在 `pages/**` 与 `components/canvas/**` 各自私有实现,样式与键盘/无障碍行为漂移。
- 主题基建已成熟:`web/src/styles/globals.css`(约 892 行 CSS 变量声明)三层 token(Primitive→Semantic→Component),`--color-neutral-*` 色板、`--palette-node-*`、`--palette-status-*`、`--space-*`、`--fs-*` 字号梯度、`--r-*` 圆角梯度;`app-theme.ts` 统一管理 AntD 6 皮肤。缺组件层消费规范与产品级组件沉淀位置。
- AntD 依赖面:约 180/637 文件导入 AntD、41 个命名导入;Top:Button、App、Input、Modal、Select、Switch、Tooltip、Form、InputNumber、Tag、Segmented、Dropdown、Drawer、Skeleton、Popconfirm;低使用率但对等成本高:Table 5、Upload 3、DatePicker 2、Tree 2(2026-09-05 清点脚本)。
- 工具链:`cn`(clsx+tailwind-merge)、cva ^0.7、motion ^12.42、lucide-react ^1.25、antd ^6.5.1、tailwindcss ^4.3.3。
### 参考吸收(两套参考,结论不同)
**dbx**(shadcn-vue/reka-nova 风格,Vue SFC):优秀项 = 目录即组件族 + `index.ts` barrel 导出 variants、cva 变体即公共 API、紧凑桌面密度档位、复合模式件下沉、语义状态色与自定义 radius。不足 = 目录半迁移(19 个组件目录旁仍散落 CustomContextMenu/ErrorBanner/LightDropdown 等 8 个顶层扁平遗留件)、token 粒度粗(单角色色值、交互态散在组件内)、无统一排版梯度、图标尺寸由调用方传 class、动效无统一纪律、无 agentic 界面沉淀。
**BoardUI**(`components/{base,application,foundations}`,agentic interfaces 设计系统):用 React 19 + Tailwind v4 + `react-aria-components` + remixicon + motion 构建,语义 token 做"状态位 × 前景/文本/背景/边框"矩阵与复合排版工具类(`text-body-medium`、`text-caption-1-semibold`…),kbd/segmented/status-dot 等全部消费专用语义 token;基础组件族目录平铺(`buttons/` 内含 button/icon-button/close-button/button-group),每组件头部注释 Figma 源节点与明暗差异;`application/` 沉淀 agent-chat(composer/history/message)、agent-thinking、notification-center、app-shell、data-table 等 agentic 产品块;动效抽 `button-press-motion` 等工具类并统一尊重 reduced-motion;accent 支持运行时整体换肤,chart/status 各自成组。与影策"AI 影视短剧创作工作台 + canvas-agent"定位高度同构。
**composio-brand-package**(设计 token 权威包,**直接采用**):`DESIGN.md`(角色化语义 token 表 + 组件配方 + Do/Don'ts)+ `tokens.json`(W3C DTCG 机器可读)+ `variables.css`/`theme.css`(CSS 变量 + Tailwind v4 @theme 落地)+ `preview.html`。**本项目配色/字体/间距/圆角的数值一律以它为准**(近黑 #0f0f0f 底、电蓝 #0007cd 主色、hairline 分隔、Inter/等宽字体、完整字号与间距梯度),翻译进 globals.css 三层 token;品牌名/Logo/营销文案/abcDiatype 字体(无授权)不采用。
**综合结论**:视觉数值取 composio-brand-package(唯一权威源,直接采用);契约形态取 dbx(barrel + cva variants);设计深度取 BoardUI(语义状态矩阵、复合排版、accent/chart/status 分组、RAC 原语、动效纪律、agentic application 层);三套参考都不搬代码。
## 决策
### D1 战略与执行(维持初版,补充地基阶段)
战略目标:组件层全自研(Celadon UI),最终不依赖 `antd`。执行:分阶段、按功能对等验收逐批替换(B1–B5,详见实施计划),禁止大爆炸与半替换观感并存。**新增一个"地基"前置项**:进入替换前先按 §D3 补齐 token 与契约(复合排版工具类、语义状态矩阵、accent/chart/status 分组),否则新组件会散落裸值。
### D2 分层结构(吸收 BoardUI 顶层分类)
`components/ui/` 按 `base / product / fx / application` 分层:
- `base/`:原语 + 基础件(buttons/、badges/、kbd/、segmented-control/…),职责同 dbx/BoardUI 的 base;
- `product/`:跨页面模式件(empty-state/、callout/、loading-state/、section-card/、property-row/…);
- `fx/`:特效件(现 `aceternity/*` 归位命名空间,引用随用随迁,不重写);
- `application/`:产品块(P3 起:agent-chat、notification-center、app-shell…,对齐 BoardUI application)。
AntD 皮肤在替换完成前继续由 `app-theme.ts` 统一管理。
### D3 token 义务(初版 D3 扩展,吸收 BoardUI 深度;数值以 composio-brand-package 为权威源)
**数值权威源**:配色/字体/间距/圆角数值一律以 composio-brand-package(`tokens.json` 优先,`DESIGN.md`/`theme.css` 对照)为准,翻译进 globals.css 三层 token 后组件只消费 `var(--*)`/工具类;禁止在页面或组件里直接写规范包裸值。品牌名/Logo/营销文案/abcDiatype 字体(无授权)不采用,字体以 Inter + 开源等宽替代。
组件只消费三层 token,禁止裸 `text-[Npx]`/`rounded-[Npx]`/硬编码色;明暗自适应,不读皮肤 ID。在此基础上:
- **语义状态矩阵**:高频角色补齐 `-default/-hover/-active/-disabled`(含 `-selected`)状态位,消费方直接用状态位,不在组件推算色值。
- **复合排版工具类**:将 `--fs-*` 字号 + 行高/字重注册为 `text-body-*`、`text-caption-1-*`、`text-title-1-*` 等复合类(Tailwind v4 @theme),并扩展 `cn` 的 tailwind-merge 使其正确合并;组件禁止裸字号堆叠。
- **分组色系**:`accent`(整体换肤品牌 ramp)、`chart`(`--palette-chart-1..9` + active)、`status`(既有 `--palette-status-*` 上补 halo/dot 成对)、`node`(沿用 `--palette-node-*`)。
- 新 token 走 globals.css 三层流程并同步 ADR/规范文档。
### D4 目录与导出规范(初版 D4 修订为"组件族目录")
```text
components/ui/base/buttons/
├── index.ts # 族级 barrel:重导出组件 + variants 类型
├── button.tsx
├── icon-button.tsx
├── tool-button.tsx
└── button-group.tsx
```
每族一目录、族内按文件拆变体、族级 `index.ts` 汇总导出(同 dbx barrel 形态);无全局 barrel;深路径导入 `@/components/ui/<layer>/<family>[/<file>]`。cva variants 即公共 API(导出 `XxxVariants` 类型);`className` 经 `cn` 合并;ref 转发;根元素 `data-slot`。持久切换用 `aria-pressed` + `data-active`;`type="primary"` 只表主要命令;保留 `:focus-visible`;尊重 `prefers-reduced-motion`。每组件头注释:用途、token 组、接管/对标对象、明暗差异(对齐 BoardUI 溯源注释)。
### D5 原语与无障碍策略(吸收 BoardUI:RAC 为地基)
- 简单件用原生语义元素 + 自有键盘/ARIA 处理。
- 复杂控件替换(B3+:Select/Modal/Drawer/Popconfirm/日期/Combobox)以 **`react-aria-components`** 为无障碍地基(同 BoardUI segmented-control/date-picker 做法),包 Celadon 观感与 token;不自研焦点陷阱/键盘导航/ARIA,不引入 Radix 全家桶。B3 启动时正式加入依赖,并先用 1 个样板(SegmentedControl)评审。
### D6 图标契约(吸收 BoardUI)
统一 `lucide-react`(既有),图标以**组件引用**传入(`icon={Move}`),尺寸/颜色由宿主组件以 token 语义档位决定;禁止调用方传 icon className 改尺寸。
### D7 动效契约(吸收 BoardUI,项目已有 motion v12)
按压/工具切换/浮层出入抽统一工具类或小组件(对齐 `button-press-motion` 思路),统一尊重 `prefers-reduced-motion`;渐变悬停等细节抽复用类,不在页面散写。
### D8 进库门槛、首批清单与试点(维持初版)
新组件须满足:① ≥2 处真实重复(PR 附 grep 证据);② 隔离明确协议/交互契约。纯透传壳不进库。P0 六件:IconButton、ToolButton、StatusBadge、EmptyState、Callout、Kbd。P1:NodeTypeBadge、TextTooltip、LoadingState、SectionCard、PropertyRow、IconGroup。试点热区:画布工具条/工具注册表、节点状态徽章、画布空态与提示——替换即删私有实现。
## 考虑过的方案
- **双层架构(AntD 基座 + 自研轻量契约层,初版推荐)**:作为过渡形态被吸收(替换期 AntD 皮肤继续由 app-theme.ts 统一管理);作为战略目标被否决——最终观感与密度不应长期受第三方主题系统约束。
- **一步全量替换 AntD**:180 文件一次性重写,不可回滚;否决,改 B1–B5 批次。
- **仅规范化不动代码**:解决不了页面私有重复与观感不可控;目录规范并入 D4。
- **引入 Radix 全家桶套皮**:与自研目标不符;否决全家桶,仅对复杂控件采纳 RAC(BoardUI 已验证路径)作无障碍地基。
- **照搬 BoardUI 或 dbx 代码/清单**:两套均无 AntD 语境且技术栈不同;否决照搬,仅吸收形态与纪律。BoardUI 的 application 产品块映射到影策 AI 工作台场景按需立项(P3),不整层照搬。
- **沿用既有中性色视觉(初版方向,后被推翻)**:原计划沿用旧中性+状态色 token,不换视觉语言;因配色/字体/间距混乱且无权威数值规范,用户 2026-09-05 决策改为**直接采用 composio-brand-package 视觉**(近黑底 + 电蓝 #0007cd + hairline 分隔 + Inter/等宽),数值全部以该包为准。
## 后果
- 长线工程:180 文件/41 导入按 B1–B5 推进;新增"地基阶段"先行补齐 token 与排版工具类,组件质量从第一批起就受纪律约束。
- RAC 作为唯一新增运行时依赖(B3 起);其余沿用既有工具链(cva/cn/motion/lucide),不引入 Radix、recharts 等(图表类延后按需评估,chart token 先行备好)。
- 自研件与 AntD 皮肤同源观感过渡(同消费三层 token);试点先在画布热区,降低样式漂移风险。
- 视觉迁移是一次性大转向(近黑底 + 电蓝 accent + Inter):集中在阶段 A 完成 token 层翻译与 app-theme 同步换肤,避免新旧视觉长期并存;light/dark 双主题由同一 Semantic token 推导(规范包为深色单主题,light 角色自行推导)。
- 依赖下降可量化:每批后重跑清点,数字写进批记录并回写本文档「背景」。
- Table/DatePicker/Tree/Upload 对等成本最高,B5 强制受控子集评审。
- 不为旧组件加兼容层、不按皮肤 ID 分叉组件、不建全局 barrel;测试基建暂缓引入,组件逻辑保护按需再评估。
- 批次与里程碑排期见实施计划 `docs/plans/ui-kit-rollout-plan.mdx`;长期规范与组件 backlog 维护在 `docs/plans/ui-design-system.mdx`(活文档)。

View File

@@ -32,6 +32,7 @@
- [ADR-0005:编辑器预设插件架构](adr/0005-editor-preset-plugin-architecture.md):参考 open-vetta「万物皆可插件」,编辑器全部 UI 与能力为预设插件贡献,插件 SDK 演进为 v2(UI 插槽 + 预设分发 + 权限执行校验)。
- [ADR-0006:语音滤镜与项目模板](adr/0006-voice-filters-and-templates.md):补充评估 Concat 剩余两个缺口——语音滤镜走 Web Audio 预览近似 + ffmpeg 音频滤镜图导出,模板走项目快照服务化;均为预设插件且服从单一滤镜图计划。
- [ADR-0007:AI 编辑交互](adr/0007-ai-editing-interaction.md):对话式剪辑作为预设插件——AI 输出受约束命令 JSON(schema 校验 fail-closed),与手势命令同队列同撤销栈;≤3 条直接执行、批量改动 diff 预览待确认。
- [ADR-0008:自研 UI 组件层与 AntD 替换](adr/0008-ui-component-layer-antd-replacement.md):`components/ui` 重建为自研组件层(Celadon UI),吸收 dbx 契约形态(族目录+barrel)与 BoardUI 设计深度(语义状态矩阵/复合排版/RAC 原语/动效纪律/agentic 产品块),分阶段替换 AntD(依赖面 180 文件/41 导入)最终脱离;试点画布工具条/节点徽章,唯一实施计划见 [plans/ui-kit-rollout-plan.mdx](plans/ui-kit-rollout-plan.mdx),活规范见 [plans/ui-design-system.mdx](plans/ui-design-system.mdx)。
## 本地协作文档(不随仓库分发)

View File

@@ -0,0 +1,110 @@
# Celadon UI 组件规范(自研组件层)
> 决策记录见 [ADR-0008](../adr/0008-ui-component-layer-antd-replacement.md);唯一实施计划见 [ui-kit-rollout-plan](./ui-kit-rollout-plan.mdx)。本文是长期维护的**组件编写规范与 backlog**。
> **视觉数值唯一权威源**:`/Users/zhugeyue/Desktop/project/bigdate/github-source-code/composio-brand-package/`(规范包;配色/字体/间距/圆角一律以它为准,消费规则见实施计划 §2.4)。
> 形态来源:契约与 barrel 取 dbx(`apps/desktop/src/components/ui`);设计深度(语义状态矩阵、复合排版、accent/chart/status 分组、react-aria 原语、动效纪律、application 产品块)取 BoardUI(`components/{base,application,foundations}`)。
## 1. 分层与适用范围
`web/src/components/ui/` 是自研组件层(Celadon UI),按职责分四层:
| 层 | 目录 | 内容 |
| --- | --- | --- |
| base | `ui/base/` | 原语 + 基础件:`buttons/`、`badges/`、`kbd/`、`segmented-control/` 等 |
| product | `ui/product/` | 跨页面模式件:`empty-state/`、`callout/`、`loading-state/`、`section-card/`、`property-row/`、`text-tooltip/` |
| fx | `ui/fx/` | 特效件(现 `aceternity/*` 归位至此命名空间,引用随用随迁,不重写) |
| application | `ui/application/` | 产品块(P3 起):agent-chat、notification-center、app-shell 等,对齐 BoardUI application |
替换完成前 AntD 用法与皮肤仍由 `web/src/lib/app-theme.ts` 统一管理;**同一控件职能不允许两套实现并存超过一个替换周期**。
## 2. 目录与导出规范(组件族目录 + 族级 barrel)
```text
ui/base/buttons/
├── index.ts # 族级 barrel:重导出全部组件 + XxxVariants 类型
├── button.tsx
├── icon-button.tsx
├── tool-button.tsx
└── button-group.tsx
```
- 每"族"一目录,族内按文件拆变体;族级 `index.ts` 汇总导出(dbx barrel 形态);**无全局 barrel**。
- 导入一律深路径 `@/components/ui/<layer>/<family>`(或 `.../<family>/<file>`)。
- 组件 `PascalCase`、文件 `kebab-case.tsx`、目录 `kebab-case/`。
- cva 定义 `xxxVariants` 并从 `index.ts` 导出;`className` 经 `cn` 合并;ref 转发;根元素 `data-slot`。
- 持久切换状态:`aria-pressed` + `data-active`;`type="primary"` 只表"主要命令";保留 `:focus-visible`;尊重 `prefers-reduced-motion`。
## 3. Token 义务(含 BoardUI 深度扩展;数值以 composio-brand-package 为权威源)
- **数值权威源**:新 token 的色值/字号/间距/圆角一律取自规范包(`tokens.json` 优先,`DESIGN.md`/`theme.css` 对照),先翻译进 globals.css 三层 token 再被组件消费;禁止组件/页面直写规范包裸值。字体采用 Inter + 开源等宽(不采用规范包 abcDiatype)。
- 只消费三层 token(Primitive→Semantic→Component 的 `var(--*)` 或其 Tailwind 映射);**禁止裸 `text-[Npx]`、裸圆角、硬编码色**。
- **语义状态矩阵**:高频角色用 `-default/-hover/-active/-disabled`(及 `-selected`)状态位 token,不在组件里推算色值。
- **复合排版工具类**:字号走 `text-body-*` / `text-caption-1-*` / `text-title-1-*` 等注册类(由 `--fs-*` 映射),禁止裸字号堆叠;`cn` 的 tailwind-merge 已扩展识别这些类。
- **分组色系**:`accent`(品牌 ramp,默认电蓝 #0007cd + 状态位)、`chart`(`--palette-chart-1..9`)、`status`(`--palette-status-*` 的成对 halo/dot)、`node`(`--palette-node-*`)。
- 明暗自适应由 CSS 变量完成;不读皮肤 ID、不分叉业务逻辑。新 token 走 globals.css 三层流程并同步 ADR-0008/本文档/实施计划。
## 4. 原语 / 图标 / 动效契约
- **原语**:简单件用原生语义元素;复杂控件(Select/Modal/Drawer/Popconfirm/日期/Combobox)以 `react-aria-components` 为无障碍地基,包 Celadon 观感。不引入 Radix。
- **图标**:统一 `lucide-react`,以组件引用传入(`icon={Move}`);尺寸/颜色由宿主组件用语义档位决定,禁止调用方传 icon className 改尺寸。
- **动效**:按压/切换/浮层出入抽统一工具类或小组件(`press-motion` 思路),统一尊重 `prefers-reduced-motion`。
## 5. 组件头注释规范(对齐 BoardUI 溯源注释)
每组件文件头:用途、消费的 token 组、接管/对标对象(原 AntD 组件或 dbx/BoardUI 组件)、明暗差异要点。
## 6. 归属决策表
| 场景 | 归属 |
| --- | --- |
| 数据表格、复杂表单、日期、树、上传、大对话框、带搜索下拉 | AntD(B3/B5 替换前保持现状;替换后为 RAC 基底的 Celadon 控件) |
| 纯图标按钮、工具激活态、紧凑分组、尺寸密度 | IconButton / ToolButton / ButtonGroup(base/buttons) |
| 状态点徽章、节点类型徽章 | StatusBadge / NodeTypeBadge(base/badges,对标 AntD Tag/Badge) |
| 空态、加载/进度态、轻量提示横幅 | EmptyState / LoadingState / Callout(product,对标 AntD Empty/Alert) |
| 单行截断悬停全文、快捷键提示 | TextTooltip / Kbd |
| 属性面板行、分区卡片 | PropertyRow / SectionCard |
| 右键菜单、下拉、气泡 | AntD Dropdown/Popover(替换前);B3 后为 RAC 基底控件 |
| 单/多选分段工具切换 | IconGroup / SegmentedControl(base/segmented-control,对标 AntD Segmented) |
| 特效件(aceternity 等) | fx 层命名空间,随用随迁,不重写 |
## 7. 进库门槛(D8)
新组件必须满足其一:① ≥2 处真实重复(PR 附 grep 证据);② 隔离明确协议/交互契约(如工具激活态、截断语义)。纯透传壳不进库;P2/P3 组件先立证据再立项。
## 8. 组件 backlog
### P0(阶段 B,已拍板)
| 组件 | 族目录 | 要点 | 对标 |
| --- | --- | --- | --- |
| IconButton | base/buttons | size 档位、colorRole、loading/dot、图标引用契约 | dbx icon-button |
| ToolButton | base/buttons | `aria-pressed` 工具激活态 | 画布工具注册表 |
| StatusBadge | base/badges | 语义成对 halo/dot + 文本;variant=outline(默认)/filled | BoardUI status-dot + AntD Tag |
| EmptyState | product/empty-state | icon/title/description/action/compact | AntD Empty |
| Callout | product/callout | info/success/warning/error + action + onClose(closable) | dbx ErrorBanner + AntD Alert |
| Kbd | base/kbd | 全语义 token(`--kbd-bg/fg`) | BoardUI kbd |
### P1(阶段 C)
NodeTypeBadge(`--palette-node-*`)、TextTooltip、LoadingState、SectionCard、PropertyRow、IconGroup。
### P2(B3+ 随替换批次,RAC 基底按需立项)
Button/Input 全量、Dialog/Modal、Drawer、Popconfirm、Tabs、Combobox/Select、Switch、Tooltip、SegmentedControl 等替代件。
### P3(阶段 E,先立证据)
application 产品块:agent-chat(composer/history/message)、agent-thinking 指示、notification-center、app-shell、data-table——映射影策 AI 工作台场景。
### fx
现有 `aceternity/*` 归位 `ui/fx/` 命名空间(不重写)。
## 9. 新组件检查清单
- [ ] 落在正确分层;目录 `kebab-case`、族级 `index.ts` 导出 variants 与类型、`data-slot` 根元素、头注释齐备
- [ ] 样式仅消费既有 token(含状态位/复合排版/分组色系),无裸值;明暗双态冒烟通过
- [ ] 图标以组件引用传入且由组件定尺寸;动效走统一工具并尊重 reduced-motion
- [ ] 键盘可操作、焦点环可见、持久状态 `aria-pressed` 可感知
- [ ] 满足进库门槛;PR 描述写明对标对象;替换场景已删私有实现

View File

@@ -0,0 +1,223 @@
# Celadon UI 自研组件层实施计划(唯一方案)
状态:已接受(2026-09-05)。关联:决策记录 [ADR-0008](../adr/0008-ui-component-layer-antd-replacement.md);组件编写规范 [ui-design-system](./ui-design-system.mdx)。
**视觉数值权威源(AI 消费入口)**:`/Users/zhugeyue/Desktop/project/bigdate/github-source-code/composio-brand-package/`(与 open-ai-canvas 同级的兄弟仓库目录,下称「规范包」)。改造本项目配色/字体/间距时,**数值一律以该规范包为唯一权威源**,消费规则见 §2.4,禁止凭记忆或截图自拟色值/字号/间距。
本方案是本次 UI 治理的**唯一实施计划**,统管两件事:① 把 `web/src/components/ui` 重建为自研组件层(代号 Celadon UI);② 按功能对等批次替换 AntD,最终脱离 `antd` 依赖。参考对象:**composio-brand-package**(唯一视觉数值权威源,直接采用其配色/字体/间距/圆角体系)+ **dbx**(组织与契约纪律,优秀项保留)+ **BoardUI**(设计深度:语义 token 状态矩阵、复合排版工具、react-aria 无障碍原语、动效纪律、agentic 应用层,弥补 dbx 短板)。
## 1. 目标与非目标
目标:
- 一套**可继承进项目日常开发**的自研组件层:目录规范、token 义务、变体契约、无障碍与动效纪律齐备,页面只消费 `@/components/ui/*`。
- AntD 依赖按批次归零;过程中任何时刻不出现"同一控件两套观感并存"。
- 组件观感以规范包(composio 视觉:近黑底 + 电蓝主色 + Inter/等宽字体)为唯一数值基准,迁移期内与 AntD 皮肤同源过渡(同一套三层 token),无裸值。
非目标:
- 不照搬 dbx/BoardUI 参考代码(dbx 是 Vue,BoardUI 是独立设计系统);只吸收“形态与规范”。规范包**只取其数值与视觉体系,不取代码**(其为独立 CSS 变量集,落地时翻译进本项目三层 token)。
- 本轮(B1 周期)不启动 Table/DatePicker/Tree/Upload 等重型自研;它们进入 B5 专项评审。
- 不引入 Radix、不重建样式基座、不新增全局 barrel、不为旧组件加兼容层。
## 2. 参考吸收对照(决策依据)
### 2.1 dbx(`apps/desktop/src/components/ui`,shadcn-vue/reka-nova 风格)——优秀项保留
| dbx 特征 | 处置 |
| --- | --- |
| 目录即组件族 + `index.ts` barrel 集中导出 variants | ✅ 保留(见 §5 目录规范) |
| cva variants 作为公共 API 契约(props 即变体) | ✅ 保留(本项目已用 cva ^0.7) |
| 紧凑桌面密度档位(h-6…h-9、icon-xs/sm/lg) | ✅ 保留,映射到既有 `--space-*`/`--r-*` token |
| 复合模式件下沉(ErrorBanner/LightTooltip 等思路) | ✅ 保留为"模式件"职责(Callout/TextTooltip 等) |
| 语义状态色扩展 + 自定义 radius 命名 | ✅ 保留,本项目 globals.css 已有等价 `--palette-status-*`/`--r-*` |
### 2.2 dbx 不足处 —— 用 BoardUI 丰富
| dbx 短板 | BoardUI 做法 | 采纳 |
| --- | --- | --- |
| 目录处于半迁移状态(19 个组件目录旁仍散落 8 个顶层扁平 `.vue`/`.ts` 遗留件) | 顶层三分类 `base / application / foundations`,全组件进分类 | ✅ 本方案 §4 采用"base 原语 / product 模式件 / application 产品块"分层 |
| token 粒度粗:单角色色值,交互态(hover/active/disabled)分散在组件里 | 语义 token 状态矩阵:`foreground/text/background/border × default/hover/active/disabled`,明暗只翻 token 不翻 class | ✅ §6.1 语义状态矩阵扩展 |
| 无统一排版梯度,组件内散落 `text-[13px]` 式裸字号 | `typography.css` 把整套 Figma 字号梯度注册为复合工具类 `text-body-medium`、`text-title-1-semibold`…(经 tailwind-merge 扩展识别) | ✅ §6.2 复合排版工具类 |
| 无系统级换肤 | `@theme` 声明 accent ramp,运行时整体 re-tint;chart/status 各自 hue-lock | ✅ §6.3 accent/chart/status 分组 |
| Vue + reka-ui,无 AntD 语境 | React Aria(`react-aria-components`)作表单/浮层原语,键盘/焦点/ARIA 开箱即得 | ✅ §7 原语策略:复杂控件替换以 RAC 为地基 |
| 图标由调用方传任意尺寸 class | Icon 以**组件引用**传入,尺寸/颜色由宿主组件用 token 决定(`@remixicon/react`) | ✅ §8 图标契约(本项目沿用 lucide-react) |
| 动效无统一纪律 | `button-press-motion` 等工具类 + `::before` 渐变悬停交叉淡化 + `prefers-reduced-motion` | ✅ §9 动效纪律(本项目已有 motion v12) |
| 组件注释缺溯源 | 每个组件头注释标注 Figma 源节点、尺寸表、明暗差异 | ✅ §10 注释规范(引用 token 组 + 对标对象) |
| 无"agentic 界面"沉淀 | `application/agent-chat`(composer/history/message)、`agent-thinking`、`notification-center`、`app-shell`、`data-table` 等产品块 | ✅ §12 backlog 的 P3 application 层(对齐影策 AI 工作台) |
### 2.3 BoardUI 事实基线(2026-09-05 勘察)
- 分层目录:`components/{base,application,foundations}`;base 下每"族"一目录(`buttons/`、`badges/`、`kbd/`、`segmented-control/`、`date-picker/`…),族内平铺多个文件(`button.tsx`/`icon-button.tsx`/`close-button.tsx`/`button-group.tsx`),无全局 barrel,深路径导入。
- 每组件:`interface XxxProps`(含 `ref`)+ 具名函数 + `cx` 合并 + 头部注释(Figma 源节点/尺寸/明暗差异)。变体用本地 style map(`sortCx`),不用 cva——**本项目沿用 cva**(既有习惯 + variants 类型导出更贴合 dbx barrel 形态)。
- 语义 token 命名如 `bg-kbd-background`、`text-kbd-foreground`、`text-caption-1-semibold`、`bg-status-dot-green-halo`;radius 语义名 `radius/md`、`radius/2lg`;暗色仅调 halo 透明度等细节。
- 依赖:`react-aria-components ^1.17`、`@remixicon/react ^4.9`、`@tanstack/react-table`、`recharts`、`@internationalized/date`、`motion ^12`、`tailwind-merge ^3`。
- 形态定位:"agentic interfaces"(chat/thinking/agent log/composer/sidebar)——与影策 AI 影视短剧工作台高度同构。
### 2.4 规范包(composio-brand-package)——唯一视觉数值权威源(AI 消费规则)
> 用户决策(2026-09-05):**直接采用 composio 视觉**(近黑底 + 电蓝主色 + 无衬线/等宽字体),数值全部以该包为准。
**消费顺序(AI 每次改造配色/字体/间距前必读,由浅入深)**:
1. `preview.html`——浏览器打开,先看整体视觉基调(近黑 #0f0f0f 底、电蓝 #0007cd 主色、hairline 分隔、终端质感);
2. `DESIGN.md`——人类可读规范:语义角色 token 表、排版梯度、组件配方、Do/Don'ts(禁止引入色板外颜色等纪律条款);
3. `tokens.json`——W3C DTCG 机器可读格式,数值唯一权威(颜色/字号/间距/圆角的 $value 一律以这里为准);
4. `variables.css` / `theme.css`——CSS 变量落地 + Tailwind v4 @theme 映射,作为翻译进本项目三层 token 的对照样本。
**采用边界**:
- 采用:语义角色命名(ink/body/muted/canvas/surface-*/hairline/on-*/primary/accent-*)、完整状态位(-default/-hover/-active/-disabled)、字号梯度、间距/圆角尺度、深色底 + 电蓝 accent 的整体视觉方向;
- 不采用:其品牌名/Logo/营销文案、abcDiatype 字体(无授权,替换为 Inter + 系统栈;代码用 JetBrains Mono/Fira Code 等开源等宽,本项目已有的 lucide/icon 不变);
- 落地规则:数值翻译进本项目 globals.css 三层 token(Primitive→Semantic→Component),组件继续只消费 `var(--*)`/工具类,**不允许在页面/组件里直接写规范包裸值**;
- 明暗:规范包为深色单主题,本项目 light/dark 双主题照旧——light 由同一 Semantic 角色推导(组件不读皮肤 ID,明暗只翻 token 层)。
## 3. 现状基线(证据)
- `web/src/components/ui/`:仅 `aceternity/`(特效装饰件)+ 3 个顶层单文件(`animated-theme-toggler.tsx`、`announcement-content.tsx`、`dia-text-reveal.tsx`),无 barrel、无变体契约。
- 主题基建:`web/src/styles/globals.css`(约 892 行 CSS 变量声明)三层架构(Primitive→Semantic→Component),含 `--color-neutral-*` 色板、`--palette-node-*`、`--palette-status-*`、`--space-*`、`--fs-*`(nano→display)、`--r-*`(xs→5xl + 语义圆角)等;`@custom-variant dark`;tw-animate-css + shadcn/tailwind.css。
- AntD 皮肤由 `web/src/lib/app-theme.ts` 统一管理(light/dark + skins)。
- 工具链:`cn`(clsx+tailwind-merge)就绪(`web/src/lib/utils.ts`);cva 可用;`motion ^12.42.2`、`lucide-react ^1.25`、`antd ^6.5.1`、`tailwindcss ^4.3.3`。
- AntD 依赖面(清点脚本复核,数字随 ADR):约 180/637 文件导入 AntD、41 个命名导入,Top 为 Button/App/Input/Modal/Select。
- 视觉混乱面(本方案治理对象):配色/字体/间距散落于 globals.css 既有 token 之外,组件与页面存在裸 `text-[13px]`、硬编码色、非标间距/圆角——以规范包数值对齐收敛。
## 4. 目标架构(分层)
```text
web/src/
styles/globals.css # 三层 token(Primitive→Semantic→Component)+ @theme 工具映射(不改基座,只扩展)
lib/app-theme.ts # AntD 皮肤唯一管理点(替换完成前继续使用)
lib/utils.ts # cn;按需扩展 tailwind-merge 识别复合排版工具类
components/ui/ # Celadon UI
base/ # 原语 + 基础件:buttons/ badges/ kbd/ segmented-control/ …
product/ # 模式件:empty-state/ callout/ loading-state/ section-card/ property-row/ …
fx/ # 特效件(现 aceternity/ 归位命名空间,引用随用随迁)
application/ # 产品块(P3 起):agent-chat/ notification-center/ app-shell/ …(对齐 BoardUI application)
```
导入约定:一律深路径 `@/components/ui/{base,product,fx,application}/<family>/<file>`(或族级 barrel);不建全局 barrel。
## 5. 目录与导出规范(沿用 dbx 形态 + BoardUI 族目录)
```text
components/ui/base/buttons/
├── index.ts # 重新导出族内全部组件 + variants 类型(族级 barrel)
├── button.tsx # Button(cva variants)
├── icon-button.tsx # IconButton(本族专用,不另开目录)
├── tool-button.tsx # ToolButton(aria-pressed 工具态)
└── button-group.tsx # ButtonGroup
```
- 组件族一目录,族内按文件拆分相关变体;每族 `index.ts` 汇总导出(同 dbx);无全局 barrel。
- 变体契约:cva 定义 `xxxVariants` 并从 `index.ts` 导出 `XxxVariants` 类型;`className` 经 `cn` 合并;forwardRef 透传;根元素 `data-slot`。
- 命名:组件 `PascalCase`、文件 `kebab-case.tsx`、目录 `kebab-case/`。
## 6. token 扩展规范(对齐 BoardUI 深度;数值以规范包为权威,在既有三层上扩展)
### 6.1 语义状态矩阵(Semantic 层补齐)
为高频角色补齐 `-default/-hover/-active/-disabled`(及可选 `-selected`)状态位,命名 `--<role>-<prop>-<state>` 风格(如 `--control-bg-hover`),消费方直接用状态位,不在组件里做色值推算。明暗只改 token 定义,组件不读皮肤 ID。
### 6.2 复合排版工具类(Component 层注册 @theme)
把既有 `--fs-*` 字号 + 行高/字重映射为 `text-body-regular|medium|semibold`、`text-caption-1-*`、`text-title-1-*` 等**复合工具类**(Tailwind v4 `@theme` 或工具类层注册),并扩展 `cn` 的 tailwind-merge 配置使其可正确合并。**组件禁止再写裸 `text-[Npx]`/`text-sm font-medium` 组合**(对齐 BoardUI typography.css 纪律)。
### 6.3 分组色系(沿用既有 --palette-* 思路,扩展完整 ramp)
- `accent`:品牌 ramp 默认取规范包主色 `#0007cd`(含 -hover/-active/-glow 等状态位,见 tokens.json);不再沿用旧中性主色。
- `chart`:图表系列 `--palette-chart-1..9` + `-active`(供后续图表块使用)。
- `status`:在既有 `--palette-status-*` 上按 BoardUI 语义补齐成对 halo/dot 类 token(如 `--status-success-halo`)。
- `node`:沿用 `--palette-node-*`(画布节点类型),NodeTypeBadge 消费。
### 6.4 专用 token
组件专用语义 token(如 `--kbd-bg/--kbd-fg`、`--segmented-track`、`--toolbar-bg`)按需在 Component 层新增并在组件头注释标注引用组。所有新 token 走 globals.css 三层流程并同步 ADR/规范文档。
## 7. 原语策略(BoardUI 贡献的关键决策)
- **简单件**(按钮、徽章、空态、kbd…):原生语义元素(`button`/`kbd`/`span`)+ 自有键盘/ARIA 处理(`aria-pressed`、`:focus-visible`)。
- **复杂控件替换(B3+:Select/Modal/Drawer/Popconfirm/日期/Combobox)**:以 **`react-aria-components`** 为无障碍地基(对齐 BoardUI segmented-control/date-picker 做法),在其上包 Celadon 观感与 token——不自研焦点陷阱/键盘导航/ARIA,也不引入 Radix 全家桶。`react-aria-components` 在 B3 启动时作为正式依赖加入。
## 8. 图标契约
- 统一 `lucide-react`(项目既有),**以组件引用传入**(`icon={Move}`),尺寸/颜色由宿主组件用 token 决定;禁止调用方传 icon className 改尺寸(对齐 BoardUI remixicon 引用契约)。`IconButton`/`ToolButton` 提供 `iconSize` 语义档位而非裸像素。
## 9. 动效纪律(项目已有 motion v12)
- 按压动效、工具切换、浮层出入:抽 `press-motion`/入场/出场工具类或小组件(对齐 BoardUI `button-press-motion` 思路),**统一尊重 `prefers-reduced-motion`**。
- 渐变/悬停细节(如 BoardUI 的 `::before` 交叉淡化)抽成可复用类,不在页面散写。
## 10. 组件头注释规范(对齐 BoardUI Figma 溯源注释)
每组件文件头:用途、消费的 token 组、接管/对标对象(原 AntD 组件或 dbx/BoardUI 组件)、明暗差异要点(如有)。页面私有组件不含此注释义务。
## 11. 里程碑与批次(唯一路线)
### 阶段 A:地基(M0)——并入本方案的 token/契约升级
1. `globals.css`:**按 §2.4 消费规范包**,把配色/字号/间距/圆角数值翻译进三层 token(近黑底 + 电蓝 accent + hairline 分隔),新增语义状态矩阵、复合排版工具类、chart/status 成对 token(新增项见 §6)。
2. `utils.ts`:扩展 tailwind-merge 识别复合排版工具类。
3. `components/ui/README.md` 规范落文字(本文 §5–§10 浓缩)。
4. 样板组件 **Kbd**(对齐 BoardUI kbd:`bg-kbd-background`/`text-kbd-foreground` 全语义)。
验证:`bun run build` 通过;新 token 与现有 AntD 皮肤明暗双态冒烟无回归;抽查页面无裸色值/裸字号残留。
### 阶段 B:P0 六组件 + 试点(M1–M2,第一个可评审 PR 取 Kbd/StatusBadge/EmptyState 子集)
| 组件 | 族目录 | 要点 | 对标 |
| --- | --- | --- | --- |
| IconButton | base/buttons | size 档位、colorRole、loading/dot | dbx icon-button + BoardUI 图标契约 |
| ToolButton | base/buttons | `aria-pressed` 工具激活态 | 画布工具注册表 |
| StatusBadge | base/badges | 语义成对 halo/dot + 文本 | BoardUI status-dot + AntD Tag 状态场景 |
| EmptyState | product/empty-state | icon/title/description/action | AntD Empty |
| Callout | product/callout | info/success/warning/error + action | dbx ErrorBanner + AntD Alert |
| Kbd | base/kbd | 全语义 token | BoardUI kbd |
试点热区(M2):画布工具条/工具注册表、节点状态徽章、画布空态与提示;替换即删除私有实现。
### 阶段 C:P1 模式件 + 页面铺开(M3–M4)
NodeTypeBadge、TextTooltip、LoadingState、SectionCard、PropertyRow、IconGroup(接管工具 Segmented)→ 资源/任务/项目库页接线,重复模式清零。
### 阶段 D:AntD 替换批次(B1–B5;B1 = 阶段 B/C 自研件顺带承接 Tag/Empty/Alert/Segmented/高密度按钮职能)
| 批次 | 内容 | 门禁(对应 antd 导入 → 0 或专项豁免;无双实现并存超一个周期;明暗无回归) |
| --- | --- | --- |
| B2 | Button/Input/InputNumber/Typography 等高频简单件 | Button/Input 计数归零 |
| B3 | Select/Modal/Drawer/Popconfirm/Switch/Tooltip/Dropdown/Tabs——**以 RAC 为地基** | Select/Modal 计数归零;键盘/焦点/ESC/遮罩逐项过 |
| B4 | Form 字段原语与布局、App(useApp 宿主语义)、ConfigProvider 收敛 | App/Form 归零 |
| B5 | 专项评审:Table/DatePicker/Tree/Upload/ColorPicker(受控子集 vs 对等实现) | antd 总导入归零 |
每批完成重跑依赖清点,把“依赖下降”数字写进批记录。批内按页面热区拆小 PR。
**执行状态(2026-09-05)**:
- M1(阶段 B):P0 六组件全部入库——Kbd / StatusBadge / EmptyState / IconButton / ToolButton / Callout(含 action、onClose);完整 `bun run build` 通过。
- M2 试点接线:EmptyState → `ai-art-critique-modal`、`workflow-test-workbench`、admin drawer、workflow 三页等;Kbd → 侧边栏/快捷键弹窗/命令面板;StatusBadge → OSS 设置表单;Callout/IconButton → `ai-art-critique-modal`。
- B1 周期实际推进:AntD Empty 全量归零(12 处);Alert → Callout 全量归零(18 处,唯一保留 `detail.tsx` 归档 banner 横幅);被替换文件同步剔除对应 antd import。
- **第二轮收尾(同日)**:StatusBadge 增加 `variant="filled"`(tone 色块纯文本胶囊,对标 AntD filled Tag;outline 保持现状零回归);状态徽章 Tag → StatusBadge 全部清零(累计 22 处:首轮 14 + ArtifactStatus / logical-models×2 / storyboard / prompt-preferences / local-cli×2 / portrait×4);ArtifactStatus 改消费 filled、`workflow.css` 死代码块删除。全库剩余 Tag 均为分类/信息/icon/计数 chips 或定制着色,非状态语义。
- 小件盘点:Badge 全库零使用;Spin 4 处异形;Segmented 为结构性控件——无新归并项。P1 候选(NodeTypeBadge / LoadingState / SectionCard / PropertyRow / IconGroup)盘点后证据不足或形态异质,均不立项,待真实重复自然积累。
- UI kit 引用文件 20+;每批 `bun run typecheck` + dev server 编译(HTTP 200)验证通过。git 改动未提交,批次提交按 §ADR 约定进行。
- **下一闸口**:composio Stage A token 迁移(globals.css 数值翻译 + antd skin 同步),改动会全局位移视觉,需用户目验确认后再动。
### 阶段 E:application 产品块(P3,按需立项)
对齐 BoardUI `application/`:agent-chat(composer/history/message)、agent-thinking 指示、notification-center、app-shell、data-table 等,映射影策 AI 工作台场景(画布 AI 助手面板、生成/转写日志、通知中心)。每块立项前先有真实页面需求与 ≥2 处重复证据。
## 12. 组件 backlog(汇总)
- P0(阶段 B):IconButton、ToolButton、StatusBadge、EmptyState、Callout、Kbd。
- P1(阶段 C):NodeTypeBadge、TextTooltip、LoadingState、SectionCard、PropertyRow、IconGroup。
- P2(B3+,随替换批次):Button/Input 全量、Dialog/Modal、Drawer、Popconfirm、Tabs、Combobox/Select、Switch、Tooltip、SegmentedControl 等替代件(每个以 RAC 或原生实现按需立项)。
- P3(阶段 E,先立证据):application 产品块。
- fx:现有 `aceternity/*` 归位 `components/ui/fx/` 命名空间(引用随用随迁,不重写)。
## 13. 验收清单(用户可检查)
- [ ] `components/ui/{base,product,fx}` 分层就位;每族有 `index.ts`、组件有 `data-slot` 与头注释
- [ ] 试点热区换用新组件且无私有实现残留;明暗与各 skin 无回归
- [ ] 新组件无裸 `text-[Npx]`/`rounded-[Npx]`/硬编码色;排版走复合工具类
- [ ] 键盘 Tab/回车/空格可操作、焦点环可见、持久态 `aria-pressed` 可感知、reduced-motion 生效
- [ ] `bun run build` 通过;每批依赖清点数字落进批记录(ADR 后果同步更新)
- [ ] token/规范变更已同步 ADR-0008、ui-design-system.mdx 与本方案 §2.4;配色/字体/间距数值可回溯到规范包 tokens.json
- [ ] 页面抽查无裸色值/裸字号/非标间距;light/dark 双态由同一 Semantic token 推导
- [ ] token/规范变更已同步 ADR-0008 与 ui-design-system.mdx
## 14. 风险与回退
| 风险 | 缓解 | 回退 |
| --- | --- | --- |
| 战线过长观感分裂 | 批次门禁 + app-theme 统一皮肤 | 停靠已验收批次,未接管控件继续 AntD |
| 范围蔓延 | 进库门槛(≥2 处重复或协议隔离) | 停在当前阶段 |
| token 扩展影响现有皮肤 | 只增不改、双主题冒烟 | 撤销新增 token,组件引用不动 |
| 规范包数值与既有观感冲突(视觉转向大) | 阶段 A 集中迁移 + app-theme 同步换肤,一次性过渡 | 停靠已验收批次,先回滚视觉迁移 |
| RAC 引入学习成本 | B3 才引入;先行 1 个样板(SegmentedControl)评审 | 该批暂缓,AntD 继续 |
| Table/DatePicker 自研失控 | B5 强制受控子集评审 | 专项豁免并记录 |
| 图标尺寸失控 | 图标引用契约(§8)评审强制 | 单组件回退 |