docs: ui kit migration brief (shadcn/lucide/motion/resizable/dnd-kit/zustand); component-library rule in AGENTS
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Ad9rqAB8pXXvyzh7f4X8v
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3632b0eabd
commit
01ec3d229b
@@ -112,7 +112,7 @@
|
||||
## 7. 前端红线
|
||||
|
||||
1. `./node_modules/.bin/tsc --noEmit` 通过;`npm run lint` **0 error**(react-hooks 编译器规则会拦 effect 内同步 setState、render 写 ref 等)。
|
||||
2. `next build` 后 `/` 保持 `○ Static`;首屏 gzip 变化在 ±2% 内,超出要在进度记录里给出原因。
|
||||
2. `next build` 后 `/` 保持 `○ Static`;首屏 gzip 变化在 ±2% 内,超出要在进度记录里给出原因。动效、拖拽、可拖宽布局这类库(Motion、dnd-kit、react-resizable-panels)一律按需加载,不进首屏;±2% 不因引入它们放宽(2026-10-23 产品定)。
|
||||
3. 测试总数不得低于开工时 `origin/staging` 的实测;改任何既有断言必须写"原值 / 新值 / 原因"三栏说明,不得静默弱化。
|
||||
4. 合同测试的 fixture 必须来自真实引擎响应(golden),不得手造形状。
|
||||
5. 改 UI 的提交同时更新 `frontend/DESIGN.md`;新文案对照 `frontend/docs/VOICE.md`。
|
||||
@@ -122,6 +122,7 @@
|
||||
9. Avoid unnecessary secondary labels and descriptions. Let the layout do the explaining.(2026-10-23 产品定)
|
||||
10. Avoid unnecessary supporting text, descriptive copy, and redundant UI microcopy.(2026-10-23 产品定)
|
||||
11. 删掉重复解释布局的文案,但保留必要的表单标签和控件名称。比如搜索框旁边已有「搜索」按钮,视觉上可以省掉重复标签,代码里的可访问名称却不能一起删。界面清爽和读屏能用不冲突。(2026-10-23 产品定)
|
||||
12. **已有依赖能正确表达的组件和行为,严禁自行设计实现**(2026-10-23 产品定)。指定依赖:组件用 shadcn/ui(`base-nova`,见 `frontend/components.json`,缺的组件用 shadcn CLI 加,不手抄改写);图标只用 Lucide;动效只用 Motion;可拖宽 / 可收起的分栏用 react-resizable-panels(经 shadcn `Resizable`);拖拽排序用 dnd-kit;跨组件状态用 Zustand。GSAP 不再使用。新增手写的按钮、弹窗、菜单、下拉、页签、抽屉、提示框由 lint 拦截;迁移完成前存量文件列在白名单里,白名单只许减少。占星专有的画法(星盘、星图、报告排版)不在此列。
|
||||
|
||||
## 8. 隐私与安全
|
||||
|
||||
|
||||
@@ -37,8 +37,9 @@
|
||||
|
||||
| 任务书 | 进度 | 主题 | 状态 | 落点 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `TASK-ui-kit-migration-20261023.md` | — | **界面统一换成组件库**:shadcn base-nova(补 `shadcn/tailwind.css`)· Lucide · Motion · react-resizable-panels · dnd-kit · Zustand;lint 拦手写控件(白名单只减不增);对话旁星盘面板;会话、档案拖动排序(动表);长相不变。产品 2026-10-23 拍板 D1~D8;8 个 issue(K0~K7)串行,取代全站动效 #98 #100 #101 | 待领取(循环) | 原型 https://claude.ai/artifact/PGnWsjHhu38KJseEfEMNWG |
|
||||
| `TASK-onboarding-journey-20261022.md` | — | **新用户启程**:建档加「先看谁的盘」(自己 / 帮别人看,本人资料可后补)、人物关系字段、首问免费(服务端原子)、起步三问、启程清单(七项从数据推导,收费项标价,老用户可见)、八条一次性提示(含星盘四页签)、启程流程专用动效。产品 2026-10-22 拍板 D1~D6;动表经产品同意进循环,拆四个 issue 串行。BUG-1420 起 | 待领取(循环) | 原型 https://claude.ai/artifact/PcTwMVb9RD611R3qStxv3U |
|
||||
| `TASK-site-motion-20261022.md` | — | **全站动效**:换页按侧栏方向滑入、选中块跟随、页签、盘型切换星体移宫、换人、翻日期、列表补位、弹窗从触发处长出、抽屉、顶部提示、点数滚动、中英交叉淡入;重写 DESIGN §6(推翻 180 ms 上限与 Spatial Instant),不引动画库,先验证 View Transitions。产品 2026-10-22 拍板;三个 issue,排在启程(三)之后、启程(四)之前 | 待领取(循环) | 原型 https://claude.ai/artifact/7u9goivnmTNSGTNWNeVMQd |
|
||||
| `TASK-site-motion-20261022.md` | — | **全站动效**:换页按侧栏方向滑入、选中块跟随、页签、盘型切换星体移宫、换人、翻日期、列表补位、弹窗从触发处长出、抽屉、顶部提示、点数滚动、中英交叉淡入;重写 DESIGN §6(推翻 180 ms 上限与 Spatial Instant),不引动画库,先验证 View Transitions。产品 2026-10-22 拍板;三个 issue,排在启程(三)之后、启程(四)之前;**2026-10-23 被 ui-kit-migration 取代** | 已取代 | 原型 https://claude.ai/artifact/7u9goivnmTNSGTNWNeVMQd |
|
||||
| `TASK-rectification-narrower-delivery-20261016.md` | `PROGRESS-rectification-narrower-delivery-fix-20261017.md` | **交付区间收窄**:显示改按活着的簇分段。第 1 次打回只补两处显示漏段(取整差 8 分、缺区间整段退回)。对半出题和门槛 8 改 6 仍不做。基线与对照各 924 条,12 格包含率都过红线。BUG-1367 起,本轮原记 BUG-1370,因与婚恋合盘保留号冲突改为 BUG-1392 | 待验收 | `codex/rectification-narrower-delivery-20261016` |
|
||||
| —(子代理直接执行,无任务书) | `PROGRESS-bug-1060-d9-double-transit-20260927.md` | **双重过运 D9 目标错配(BUG-1060)**:D9 第 N 宫目标误用 D9 上升、D9 宫主目标误用 D1 度数,改为标签所写的 D9 星座;D1 / CL 层逐字节不变;数据卡 golden 重采集(一张盘跨层结论 9→10);另记 BUG-1061 跨层数字比对(未修) | 已验收(待部署) | `codex/bug-1060-d9-double-transit-20260927`(未推送) |
|
||||
| —(子代理直接执行,无任务书;产品 2026-09-27 授权) | `PROGRESS-bug-1061-cross-layer-pairing-20260927.md` | **双重过运跨层配对按名字数字比对(BUG-1061)**:改为结构化身份配对(D1 第 N 宫↔D9 第 N 宫;D1 第 N 宫主↔同一颗星的 D9 目标);各层结果与 D1/CL golden 逐字节不变;48 样本跨层条目 31→38;数据卡 golden 重采集(乔布斯 6→9、泰勒 9→10) | 已验收(待部署) | `codex/bug-1061-cross-layer-pairing-20260927`(未推送) |
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# TASK · 新用户启程:先看谁的盘、首问免费、起步三问、启程清单、一次性提示与动效(2026-10-22)
|
||||
|
||||
> **2026-10-23 更新:** 红线 8 和 T7 里的「用 CSS 和 Web Animations API、复用 `lib/motion/` 底座」改为「**用 Motion**,复用 `TASK-ui-kit-migration-20261023.md` K0 做好的 Motion 预设」。界面控件一律用 shadcn 组件(AGENTS.md §7 第 12 条)。文案按 AGENTS.md §7 第 9~11 条删减,可访问名称要保留。顺序也跟着调整:#96 等迁移单 K0 合入后再开工;#99 改为依赖 K0,不再依赖 #98。
|
||||
|
||||
设计原型(可点,含两条路径与全部动效):https://claude.ai/artifact/PcTwMVb9RD611R3qStxv3U 。原型与本任务书不一致时,以本任务书为准。原型里的名字、日期、星位都是虚构示例。
|
||||
|
||||
## 基线
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# TASK · 全站动效:换页、页签、盘型、列表、弹窗、抽屉、提示、数字(2026-10-22)
|
||||
|
||||
> **2026-10-23 更新:本单不再单独执行。** 产品推翻了下面的 D3「不引入动画库」,改为一律用 Motion(见 `TASK-ui-kit-migration-20261023.md` 的 D2)。本单的**动效规范表仍然有效**,由迁移单 K0 做成 Motion 预设;M0~M4 并入迁移单 K1~K5。issue #98、#100、#101 不再执行。
|
||||
|
||||
设计原型(可在「现在 / 改后」之间对比):https://claude.ai/artifact/7u9goivnmTNSGTNWNeVMQd 。原型和本任务书不一致时,以本任务书为准。
|
||||
|
||||
## 基线
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
# TASK · 界面统一换成组件库:shadcn/ui · Lucide · Motion · react-resizable-panels · dnd-kit · Zustand(2026-10-23)
|
||||
|
||||
可交互原型(保持现在的 Claude 风格,全部用下列依赖实现,带「显示组件来源」开关):https://claude.ai/artifact/PGnWsjHhu38KJseEfEMNWG 。原型和本任务书不一致时,以本任务书为准。原型的数据是虚构的。
|
||||
|
||||
## 基线
|
||||
|
||||
- 写本单时的 `origin/staging` 是 `3632b0eab`。每个 issue 开工时,以当时的 `origin/staging` 为准。
|
||||
- BUG 编号:开工时用 `grep -oE "BUG-[0-9]+" docs/BUG_HISTORY.md | sort -t- -k2 -n | tail -1` 核对最大号,从下一个号开始(写本单时是 BUG-1420)。
|
||||
- 本单拆成 8 个 issue,串行执行,见文末「循环交接」。其中 K1 和 K4 要动表(加排序列),产品已经同意。
|
||||
|
||||
## 现状实证(2026-10-23 在 staging 代码上实测)
|
||||
|
||||
1. **shadcn 装了,但几乎没用。**
|
||||
- `frontend/components.json` 已经配成 `style: "base-nova"`、`iconLibrary: "lucide"`。
|
||||
- 但 `src/components/ui/` 下只有 8 个组件:button、calendar、popover、select、sidebar、sonner、tabs、textarea。
|
||||
- 业务代码(不含后台)里有手写 `<button>` 148 处、原生 `<dialog>` 8 个、自写 `role="dialog"` 弹层 3 个,还有 4 处自己 `createPortal`。
|
||||
2. **样式全靠手写。** `src/app/globals.css` 有 7002 行、902 个自定义类、14 段 `@keyframes`。同一种控件各写一份,例如:
|
||||
- 会话行菜单 `.session-actions` / `.session-action-item`,其实就是一个手写的 DropdownMenu;
|
||||
- 账户入口 `.profile-trigger`;
|
||||
- `.new-chat`、`.report-nav-button` 等。
|
||||
3. **漏引 shadcn 的变体规则。** `globals.css` 没有 `@import "shadcn/tailwind.css"`。base-nova 组件用到的 `data-horizontal:`、`data-vertical:`、`data-active:` 等变体都定义在这个文件里,漏引时页签方向、分段按钮拼接、选中态都会错。原型第一版就踩过这个坑。
|
||||
4. **动效分散。** 有 14 段手写关键帧;`chat-message-row.tsx` 里用了一处 GSAP。
|
||||
5. **状态分散。** 首页 `Home()` 和各个 hook 里共有 171 处 `useState`、2 个 context,状态靠参数一层层往下传。
|
||||
6. **没有拖拽,也没有可拖宽的分栏。** 侧栏宽度是写死的;想看星盘只能单独开一页。
|
||||
7. 手写控件最多的文件(按钮、弹窗、菜单出现次数):
|
||||
- `email-otp-login.tsx` 18
|
||||
- `people/people-page.tsx` 12
|
||||
- `report-export-drawer.tsx` 7
|
||||
- `synastry-add-dialog.tsx` 6
|
||||
- `chart-type-picker.tsx` 6
|
||||
- `birth-time-choice-question.tsx` 6
|
||||
- `onboarding-redeem-paywall.tsx` 5
|
||||
- `birth-time-candidate-result.tsx` 5
|
||||
- `app/(app)/page.tsx` 5
|
||||
- 其余见各 issue 的文件清单。
|
||||
|
||||
## 根因
|
||||
|
||||
- 引入 shadcn 的时候只拷了几个组件,之后每个新功能都自己写控件和样式;没有规矩、也没有检查拦住手写。
|
||||
- 动效、状态、拖拽都没有定好用哪个库,于是各写各的。
|
||||
|
||||
## 决策记录(产品负责人 2026-10-23 拍板,全部同意)
|
||||
|
||||
| # | 决定 | 推翻了什么 |
|
||||
| --- | --- | --- |
|
||||
| D1 | **加 4 个依赖、去掉 1 个**:加 `motion`、`react-resizable-panels`(v4,经 shadcn `Resizable`)、`@dnd-kit/core` + `@dnd-kit/sortable` + `@dnd-kit/utilities`、`zustand`;去掉 `gsap` 和 `@gsap/react`。版本固定到发布满两周的版本 | AGENTS.md §7.7「不得顺手升级依赖」:本单是产品点名授权的新增 |
|
||||
| D2 | **动效一律用 Motion** | `TASK-site-motion-20261022.md` 的 D3「不引入动画库」,以及 `TASK-onboarding-journey-20261022.md` 红线 8 的「用 CSS 和 Web Animations API」。site-motion 的**动效规范表仍然有效**,按表里的时长和曲线做成 Motion 预设;它的 M0~M4 并入本单 |
|
||||
| D3 | **已有依赖能正确表达的组件和行为,严禁自行设计实现**,并加 lint 自动拦截 | 已写进 AGENTS.md §7 第 12 条 |
|
||||
| D4 | **首屏 ±2% 不放宽**。Motion、dnd-kit、react-resizable-panels 按需加载,不进首屏 | 已写进 AGENTS.md §7 第 2 条 |
|
||||
| D5 | **新功能:在对话旁边拉出星盘面板**,可以拖宽、可以收起 | 无 |
|
||||
| D6 | **会话和星盘档案可以拖动排序,顺序跨设备保留**。要加排序列,产品同意动表 | 无 |
|
||||
| D7 | **长相不变**:配色、字体、圆角沿用现有的 Claude 风格设计令牌,映射成 shadcn 的 CSS 变量(`--background`、`--primary` 等)。本单只换实现,不换长相 | 无 |
|
||||
| D8 | **文案规矩**按 AGENTS.md §7 第 9~11 条执行:删掉解释布局的副标题、说明句、重复标签,可访问名称保留 | 无 |
|
||||
|
||||
## 硬红线
|
||||
|
||||
1. 不得手抄或改写 shadcn 组件。缺什么组件就用 `npx shadcn@<固定版本> add <组件名>` 加。加进来之后只许改设计令牌和类名组合,不许改组件的行为。
|
||||
2. `globals.css` 第一行之后必须 `@import "shadcn/tailwind.css";`。没有这一行,验收直接不通过。
|
||||
3. 首屏:`next build` 后 `/` 仍为 `○ Static`,首屏 gzip ±2%。Motion 用 `LazyMotion` + `m` 组件,`domAnimation` 特性包异步加载;dnd-kit、react-resizable-panels 只在用到的页面里动态引入。
|
||||
4. 揭幕后不得出现新的等待动画(AGENTS.md §6)。动效只回应用户操作;一律包在 `MotionConfig reducedMotion="user"` 里,尊重系统的减少动态效果设置。
|
||||
5. 冻结合同:`Home()` 的 `useState` / `useRef` 数只许减少(状态迁进 Zustand 后应当明显下降)。`ChatComposer` 仍然是唯一的输入框,只是改为用 shadcn `InputGroup` 实现。
|
||||
6. 不得改动业务行为和数据:同样的输入,接口请求、扣点、落库都必须和改前一致。每个 issue 都要对比改前改后的全量测试;改了既有断言要写「原值 / 新值 / 原因」三栏。
|
||||
7. 删除手写类和关键帧之前,按 AGENTS.md §7 第 8 条先 grep 源码文本合同测试,同一轮跟着改。
|
||||
8. 动表只加列(排序列可为空,有默认值),对已部署代码向后兼容;必须真跑 `npm run test:db`。
|
||||
9. 星盘画法、星图、报告排版、天空过场这些占星专有的绘制保留手写,不算违规;但其中的按钮、菜单等控件仍要换成组件。
|
||||
10. 文案按 D8 删减时,读屏名称不能跟着删:图标按钮要有 `aria-label`,表单控件要有可访问名称。
|
||||
|
||||
## 任务分解
|
||||
|
||||
### K0 底座与规矩
|
||||
|
||||
- 加 D1 列的依赖,去掉 gsap。`chat-message-row.tsx` 里的 GSAP 改用 Motion,效果不变。
|
||||
- `globals.css` 加 `@import "shadcn/tailwind.css"`。把现有设计令牌映射到 shadcn 变量,深色、浅色都要映射(D7)。
|
||||
- 用 shadcn CLI 加以下组件:
|
||||
- dialog、alert-dialog、sheet、drawer
|
||||
- dropdown-menu、tooltip、card、badge、table、separator、scroll-area、avatar
|
||||
- input、input-group、label、field、toggle、toggle-group、resizable
|
||||
- checkbox、radio-group、switch、collapsible、empty、kbd、skeleton
|
||||
- 说明:skeleton 只给星盘页 BUG-1016 那一处例外用。
|
||||
- `src/lib/motion/`:
|
||||
- 把 `TASK-site-motion-20261022.md` 动效规范表里的每一档做成 Motion 预设(时长、曲线、方向);
|
||||
- 包装好 `LazyMotion` 和 `MotionConfig`;
|
||||
- 不另写任何动画逻辑。
|
||||
- `src/stores/`:先建骨架,有会话、人物、账户、界面四个 store。状态在后面各个 issue 里逐步迁入。
|
||||
- **lint 规则**:在 `src/components/ui/**` 以外:
|
||||
- 出现 JSX 原生 `button`、`dialog`、`select`、`input type=checkbox|radio`,或 `role="dialog|menu|menuitem|tablist|tab|listbox"`,或 `createPortal`,就报错;
|
||||
- 用字符充当图标(☰ ↑ × ⋯ ✓ ▾ 等出现在 JSX 文本里)也报错。
|
||||
- **存量白名单**:迁移前已有的违规文件列进白名单,再加一条测试,断言白名单只能变短、不能变长。
|
||||
- 星盘和星图里的 SVG 绘制不受图标规则限制,规则里写明豁免哪些路径。
|
||||
|
||||
**验收**
|
||||
- `npm ls` 里能看到新依赖,看不到 gsap。
|
||||
- 往 `src/components/` 下新加一个含 `<button>` 的文件,lint 报错。
|
||||
- 首屏 gzip ±2%,`/` Static。
|
||||
- 界面截图和改前一致:K0 只加底座,不换控件。
|
||||
|
||||
### K1 外壳:侧栏、会话列表、账户菜单、设置、页面切换
|
||||
|
||||
文件:`app-sidebar.tsx`、`sidebar-session-row.tsx`、`theme-preference-menu.tsx`、`account-dialog-overlay.tsx`、`profile-panel.tsx`、`billing-panel.tsx`、`account-deletion-section.tsx`、`account-deletion-gate.tsx`、`feedback-dialog.tsx`、`subject-switcher.tsx`,以及 `globals.css` 里对应的手写类。
|
||||
|
||||
- **侧栏**:
|
||||
- 用 shadcn `Sidebar` 的菜单组件;
|
||||
- 桌面上放进 `ResizablePanelGroup`,可以拖宽(200–360 px),拖到最左收起,宽度记在本机;
|
||||
- 手机上用 `Sheet` 从左边滑出;
|
||||
- 当前页的高亮底色用 Motion 的 `layoutId` 滑动。
|
||||
- **会话行**:
|
||||
- 更多菜单用 `DropdownMenu`(收藏、重命名、转发、删除);
|
||||
- 删除前弹 `AlertDialog`;
|
||||
- 拖动排序用 dnd-kit,键盘也能排;
|
||||
- 顺序写进新加的排序列(D6,动表);收藏的会话仍然排在最前。
|
||||
- **账户菜单**:
|
||||
- 用 `DropdownMenu`,主题是 `DropdownMenuRadioGroup`;
|
||||
- 触发按钮只显示头像和名字,点数不在这里重复显示(D8)。
|
||||
- **设置弹窗**:
|
||||
- 用 `Dialog` + `Tabs`,三个分区名不变;
|
||||
- 注销确认用 `AlertDialog`,反馈用 `Dialog`。
|
||||
- **页面切换**:Motion 的 `AnimatePresence`,方向跟随侧栏顺序(site-motion 规范表的「页面切换」档)。
|
||||
- **顶栏点数**:
|
||||
- 改成正常大小的 `Button variant="outline"`,内容是 Lucide `Coins` 图标加数字;
|
||||
- 「点」字只放在 `aria-label` 里;
|
||||
- 数字变化时上下滚动。
|
||||
- 现有的手写类 `.session-row`、`.session-actions`、`.profile-trigger`、`.new-chat`、`.report-nav-button` 等,迁移后删除,并从 lint 白名单里移出对应文件。
|
||||
|
||||
**验收**
|
||||
- 拖动会话排序后刷新、换设备,顺序都保持(DB 测试加交互测试)。
|
||||
- 快速连点侧栏 5 次,最终停在最后点的那一页,没有残留的旧页。
|
||||
- 侧栏拖到最左能收起,宽度刷新后仍然记得。
|
||||
- 手机 375 px 宽时侧栏是抽屉,页面不横向滚动。
|
||||
|
||||
### K2 对话页
|
||||
|
||||
文件:`chat-composer.tsx`、`chat-message-row.tsx`、`chat-message-actions.tsx`、`conversation-follow-ups.tsx`、`reply-down-reason.tsx`、`model-selector.tsx`、`onboarding-redeem-paywall.tsx`、`starter-home.tsx`、`app/(app)/page.tsx`、`jump-to-latest-button.tsx`。
|
||||
|
||||
- **输入框**:
|
||||
- `ChatComposer` 改用 `InputGroup` + `InputGroupTextarea`;
|
||||
- 底部 `InputGroupAddon align="block-end"` 放两样东西:左边是模型选择(`DropdownMenu`),右边是圆形发送按钮;
|
||||
- 发送按钮和输入框同在一个框里,底边对齐;
|
||||
- 模型选择从顶栏移进输入框,各模型的价格只在菜单里显示。
|
||||
- **回答操作**:赞、踩、复制、重新生成用 `Button size="icon-sm"`,每个配 `Tooltip`;「不满意原因」用 `Dialog`。
|
||||
- **追问**:用 `Button variant="outline" size="sm"`,依次浮出(Motion 的 stagger)。
|
||||
- **兑换窗**:改用 `Dialog`,文案不变。
|
||||
- **对话旁的星盘面板(D5)**:
|
||||
- 顶栏加一个 `PanelRightOpen` / `PanelRightClose` 图标按钮,配 `Tooltip`,带 `aria-label`;
|
||||
- 面板放在 `ResizablePanelGroup` 里,可以拖宽、可以收起,宽窄记在本机;
|
||||
- 面板里是当前人物的本命盘(复用星盘页的绘制组件);
|
||||
- 手机上不显示这个入口。
|
||||
- **对话状态**:当前会话、消息、流式状态迁进 Zustand 的会话 store;`Home()` 里对应的 `useState` 删掉。
|
||||
- **流式输出**:逐字释放的逻辑不改;消息进场用 Motion。
|
||||
|
||||
**验收**
|
||||
- 回归原有的对话测试:流式、停止、排队、撤回、退点、寒暄免费。
|
||||
- `Home()` 的 hook 数下降,写进进度记录。
|
||||
- 星盘面板打开、拖宽、收起、刷新后仍然记得状态。
|
||||
|
||||
### K3 星盘页
|
||||
|
||||
文件:`chart-page/*`(`chart-page-view.tsx`、`chart-type-picker.tsx`、`chart-vedic-tab.tsx`、`chart-dasha-tab.tsx`、`chart-basics-tab.tsx`、`chart-western-tab.tsx`、`chart-birth-editor.tsx`、`chart-param-table.tsx`、`chart-symbol-help.tsx`)。
|
||||
|
||||
- **四个页签**:用 `Tabs`,`variant="line"`。
|
||||
- **盘型条**(本命、D9、D10、月亮…):用 `ToggleGroup variant="outline" spacing={0}`,选满盘型时用 `ScrollArea` 横向滚动;「星盘类型」面板用 `Popover` 或 `Sheet`。
|
||||
- **盘与参数**:桌面上两栏放在 `ResizablePanelGroup` 里,可以拖宽;手机上上下排。
|
||||
- **行星表**:
|
||||
- 用 `Table`,**跨满整行**(继承 #102 的修复,不得回归);
|
||||
- 状态列统一用 `Badge`:落陷、敌用 `destructive`,其余用 `secondary`,没有状态就写「—」。同一列不得出现两种徽标形状。
|
||||
- **出生资料就地编辑**:用 `Popover` 或 `Dialog`,表单用 `Field` 和 `Input`。
|
||||
- **Motion**:换盘型时星体从旧宫位移到新宫位;换人时格线重画;大运展开用 `Collapsible` 加 Motion。
|
||||
- 星盘 SVG 的绘制保留手写(红线 9)。
|
||||
|
||||
**验收**
|
||||
- 切盘型后星体最终坐标和直接渲染一致(坐标断言)。
|
||||
- D1 字节冻结测试仍然通过。
|
||||
- 1024、1280、390 三种宽度下截图都正常。
|
||||
|
||||
### K4 星盘档案与婚恋合盘
|
||||
|
||||
文件:`people/people-page.tsx`、`people-home-links.tsx`、`chart-profile-form.tsx`、`profile-gender-field.tsx`、`synastry/*`(`synastry-add-dialog.tsx`、`synastry-picker.tsx`、`synastry-report-view.tsx` 等)。
|
||||
|
||||
- **人物卡**:用 `Card`,加 `CardAction`,更多菜单用 `DropdownMenu`;编辑用 `Dialog`;删除用 `AlertDialog`。
|
||||
- **拖动排序**:用 dnd-kit 的网格排序,顺序写进 `chart_profiles` 的新排序列(D6,动表);本人始终排在第一。
|
||||
- **关系选择**:用 `ToggleGroup`,表单的标签和读屏名称都要保留(D8)。
|
||||
- **合盘选人页**:
|
||||
- 去掉页内重复的标题和副标题(顶栏已经有页名);
|
||||
- 两个 `Select` 左右并排,中间一个 Lucide `X`(`aria-hidden`);
|
||||
- 下方正中放「开始合盘 · {价格} 点」按钮;
|
||||
- 手机上两个选择框上下排;
|
||||
- 两个 `Select` 都有可访问名称「第一个人」「第二个人」。
|
||||
|
||||
**验收**
|
||||
- 拖动排序后刷新、换设备,顺序都保持。
|
||||
- 删人后,相关的合盘和报告照原逻辑处理。
|
||||
- 合盘按钮在桌面和手机上都居中。
|
||||
|
||||
### K5 报告、星历、登录与其余页面
|
||||
|
||||
文件:
|
||||
- `personal-report/*`:`report-actions.tsx`、`report-export-drawer.tsx`、`personal-report-center.tsx`、`report-edge-jump.tsx`、`report-row-delete.tsx`
|
||||
- `ephemeris/*`
|
||||
- `email-otp-login.tsx`、`legal/*`、`app/global-error.tsx`、`markdown-code-block.tsx`、`birth-sky/birth-sky-replay.tsx` 里的控件
|
||||
|
||||
具体改法:
|
||||
- **中英切换**:用 `ToggleGroup`,带 `aria-label="报告语言"`。
|
||||
- **导出**:用 `Sheet`(桌面从右侧滑出,手机从底部);删掉说明句和文件大小(D8)。
|
||||
- **星历翻日期**:用 `Button` 加 Lucide 箭头,内容按方向翻页(Motion)。卡片不得被翻页容器裁掉边框,原型第一版就出过这个问题。
|
||||
- **登录页**:输入框和按钮换成组件;验证码输入用 shadcn `InputOTP`。
|
||||
|
||||
**验收**
|
||||
- BUG-1126 回归测试通过(中英切换后不残留旧语言节点)。
|
||||
- 登录页 E2E(或交互测试)全过。
|
||||
|
||||
### K6 生时校正界面
|
||||
|
||||
文件:`birth-time-*`、`rectification-*` 系列组件(`birth-time-choice-question.tsx`、`birth-time-candidate-result.tsx`、`birth-time-rectification.tsx`、`rectification-choice-card.tsx`、`rectification-board.tsx` 等)。
|
||||
|
||||
- 只换控件和动效,**题目逻辑、计分、落库一概不动**。
|
||||
- 选项卡片改用 `ToggleGroup` 或 `RadioGroup`。
|
||||
- 排在 #103(校正入口修复)合入之后。
|
||||
|
||||
**验收**:校正的全量前端测试、Python `test_rectification_*`,改前改后逐条一致。
|
||||
|
||||
### K7 收尾
|
||||
|
||||
- 删掉 `globals.css` 里已经没人用的手写类和 `@keyframes`,进度记录里写清改前改后的行数。
|
||||
- lint 白名单清空(占星绘制的豁免除外)。
|
||||
- 重写 `frontend/DESIGN.md`:
|
||||
- 第一节改为「组件一律用 shadcn base-nova,令牌如下」,动效节改为 Motion 预设表;
|
||||
- 旧的 `CLAUDE_DESIGN.md` 改编说明降为参考。
|
||||
- 更新 `frontend/docs/VOICE.md`:按 D8 删掉已不存在的说明句。
|
||||
|
||||
## 让步顺序
|
||||
|
||||
做不完时,按下面的顺序先砍:
|
||||
|
||||
1. K7 里 `globals.css` 的彻底清理(白名单仍然只减不增)
|
||||
2. 星盘面板宽窄的本机记忆
|
||||
3. 换人时的格线重画
|
||||
4. 拖动排序的键盘操作(鼠标拖动不让)
|
||||
|
||||
D3 的 lint 规则、`shadcn/tailwind.css`、首屏体积、文案规矩、读屏名称都不能让。
|
||||
|
||||
## 循环交接
|
||||
|
||||
- **执行方**:Grok(Windows + Docker)。每个 issue 一个分支,只推自己的分支。
|
||||
- **Grok 自跑**:`tsc --noEmit`、`npm run lint`、相关测试文件、`npm run build`(记录 `/` 是否 Static 和首屏 gzip)。动表的 issue 还要跑 `npm run test:db`,与 `tools/agent-loop/windows-known-failures.txt` 逐条比对。
|
||||
- **Claude 验收时跑**:前端全量 `npm test`,逐条对比基线;复核首屏 gzip;对照原型截图检查。
|
||||
- **真机清单**:`docs/testing/ui-kit-migration-20261023.md`,由 K1 创建,后面的 issue 往里追加。
|
||||
- 每个 issue 在同一变更里更新 `docs/BUG_HISTORY.md`(体验改进类记 `enhancement`)、`CHANGELOG.md` 和 `frontend/DESIGN.md`。
|
||||
|
||||
| issue | 内容 | 分支 | 前置 |
|
||||
| --- | --- | --- | --- |
|
||||
| 组件库(K0) | 底座与规矩 | `codex/ui-kit-0-base-20261023` | #95 合入 |
|
||||
| 组件库(K1) | 外壳 | `codex/ui-kit-1-shell-20261023` | #97 合入 |
|
||||
| 组件库(K2) | 对话页 | `codex/ui-kit-2-chat-20261023` | K1 合入 |
|
||||
| 组件库(K3) | 星盘页 | `codex/ui-kit-3-chart-20261023` | K2、#102 合入 |
|
||||
| 组件库(K4) | 档案与合盘 | `codex/ui-kit-4-people-20261023` | K3 合入 |
|
||||
| 组件库(K5) | 报告、星历、登录 | `codex/ui-kit-5-pages-20261023` | K4 合入 |
|
||||
| 组件库(K6) | 生时校正界面 | `codex/ui-kit-6-rectification-20261023` | K5、#103 合入 |
|
||||
| 组件库(K7) | 收尾 | `codex/ui-kit-7-cleanup-20261023` | K6 合入 |
|
||||
|
||||
新用户启程的几单也跟着调整:#96 改为等 K0 合入后再开工,新界面直接用组件库;#99(启程动效)改为依赖 K0 的 Motion 预设,不再依赖 #98。#98、#100、#101(全站动效一、二、三)并入 K1~K5,不再单独执行。
|
||||
Reference in New Issue
Block a user