@teamix-evo/skills 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +7 -3
  2. package/manifest.json +3 -2
  3. package/package.json +2 -2
  4. package/src/teamix-evo-code-opentrek/SKILL.md +12 -10
  5. package/src/teamix-evo-code-opentrek/api-layering.md +8 -5
  6. package/src/teamix-evo-code-opentrek/checklist.md +2 -0
  7. package/src/teamix-evo-code-opentrek/error-and-loading.md +38 -25
  8. package/src/teamix-evo-code-opentrek/file-structure.md +63 -54
  9. package/src/teamix-evo-code-opentrek/forms-and-validation.md +14 -12
  10. package/src/teamix-evo-code-opentrek/reuse-first.md +2 -0
  11. package/src/teamix-evo-code-opentrek/routing-and-codesplit.md +23 -21
  12. package/src/teamix-evo-code-opentrek/testing.md +32 -28
  13. package/src/teamix-evo-code-uni-manager/SKILL.md +12 -10
  14. package/src/teamix-evo-code-uni-manager/api-layering.md +2 -0
  15. package/src/teamix-evo-code-uni-manager/checklist.md +2 -0
  16. package/src/teamix-evo-code-uni-manager/error-and-loading.md +3 -1
  17. package/src/teamix-evo-code-uni-manager/file-structure.md +2 -0
  18. package/src/teamix-evo-code-uni-manager/forms-and-validation.md +2 -0
  19. package/src/teamix-evo-code-uni-manager/reuse-first.md +3 -1
  20. package/src/teamix-evo-code-uni-manager/routing-and-codesplit.md +3 -1
  21. package/src/teamix-evo-code-uni-manager/testing.md +2 -0
  22. package/src/teamix-evo-design-opentrek/SKILL.md +34 -41
  23. package/src/teamix-evo-design-opentrek/boundaries.md +22 -2
  24. package/src/teamix-evo-design-opentrek/brand.md +7 -7
  25. package/src/teamix-evo-design-opentrek/checklist.md +15 -13
  26. package/src/teamix-evo-design-opentrek/components.md +60 -11
  27. package/src/teamix-evo-design-opentrek/foundations.md +3 -0
  28. package/src/teamix-evo-design-opentrek/generation-flow.md +70 -12
  29. package/src/teamix-evo-design-opentrek/patterns/color-mapping.md +96 -0
  30. package/src/teamix-evo-design-opentrek/patterns/dashboard.md +2 -0
  31. package/src/teamix-evo-design-opentrek/patterns/detail-page.md +10 -9
  32. package/src/teamix-evo-design-opentrek/patterns/form-page.md +35 -32
  33. package/src/teamix-evo-design-opentrek/patterns/list-page.md +80 -47
  34. package/src/teamix-evo-design-opentrek/patterns/page-types.md +17 -12
  35. package/src/teamix-evo-design-opentrek/patterns/sidebar.md +122 -0
  36. package/src/teamix-evo-design-opentrek/philosophy.md +7 -5
  37. package/src/teamix-evo-design-uni-manager/SKILL.md +17 -26
  38. package/src/teamix-evo-design-uni-manager/boundaries.md +4 -1
  39. package/src/teamix-evo-design-uni-manager/components.md +3 -0
  40. package/src/teamix-evo-design-uni-manager/foundations.md +3 -0
  41. package/src/teamix-evo-design-uni-manager/generation-flow.md +43 -7
  42. package/src/teamix-evo-design-uni-manager/patterns/dashboard.md +3 -1
  43. package/src/teamix-evo-design-uni-manager/patterns/detail-page.md +41 -12
  44. package/src/teamix-evo-design-uni-manager/patterns/form-page.md +49 -12
  45. package/src/teamix-evo-design-uni-manager/patterns/list-page.md +44 -11
  46. package/src/teamix-evo-design-uni-manager/patterns/page-types.md +3 -1
  47. package/src/teamix-evo-design-uni-manager/philosophy.md +3 -1
  48. package/src/teamix-evo-manage/SKILL.md +74 -66
@@ -1,18 +1,20 @@
1
1
  # 测试规范
2
2
 
3
+ > ⚠️ **Prerequisites**: 本文件是 [SKILL.md](./SKILL.md) Step 7 的读取项。纯函数和 zod schema 必测,其余按关键路径覆盖。
4
+
3
5
  > **核心约定**:`vitest` + `@testing-library/react` + `msw`,文件就近 `*.test.ts(x)`。**不追求覆盖率数字**,追求"关键路径必有测试 + 纯函数全测"。
4
6
 
5
7
  ---
6
8
 
7
9
  ## 选型(业界主流)
8
10
 
9
- | 类型 | 工具 | 理由 |
10
- | --- | --- | --- |
11
- | 测试 runner | `vitest` | 与 Vite 原生集成,ESM 友好,API 与 Jest 兼容 |
12
- | 组件测试 | `@testing-library/react` + `@testing-library/user-event` | 测行为不测实现,业界事实标准(Kent C. Dodds) |
13
- | API mock | `msw`(Mock Service Worker) | 拦截真实 fetch / axios,测试与生产共用 service 层 |
14
- | 断言 | `vitest` 内置 `expect`(兼容 Jest) | 无需 chai |
15
- | E2E(可选) | `playwright` | 关键流程冒烟,**不在本 skill 范围** |
11
+ | 类型 | 工具 | 理由 |
12
+ | ----------- | -------------------------------------------------------- | ------------------------------------------------ |
13
+ | 测试 runner | `vitest` | 与 Vite 原生集成,ESM 友好,API 与 Jest 兼容 |
14
+ | 组件测试 | `@testing-library/react` + `@testing-library/user-event` | 测行为不测实现,业界事实标准(Kent C. Dodds) |
15
+ | API mock | `msw`(Mock Service Worker) | 拦截真实 fetch / axios,测试与生产共用 service 层 |
16
+ | 断言 | `vitest` 内置 `expect`(兼容 Jest) | 无需 chai |
17
+ | E2E(可选) | `playwright` | 关键流程冒烟,**不在本 skill 范围** |
16
18
 
17
19
  **不要混用**:已经选 vitest 就不要再加 jest;已经用 msw 就不要再自己 mock axios。
18
20
 
@@ -57,16 +59,16 @@ src/test/
57
59
 
58
60
  按 ROI 排序:
59
61
 
60
- | 优先级 | 类型 | 例子 | 必测? |
61
- | --- | --- | --- | --- |
62
- | P0 | 纯函数(`src/utils/`、`src/services/`) | `formatMoney`、`isValidOrder` | ✅ **必测** |
63
- | P0 | zod schema | `CreateOrderInputSchema.parse(...)` | ✅ **必测** |
64
- | P0 | 关键业务路径(下单 / 支付 / 鉴权) | E2E-style 组件测 | ✅ **必测** |
65
- | P1 | Hook(数据 hook + 自定义 UI hook) | `useOrderList`、`useDebounce` | 推荐 |
66
- | P1 | 复用业务组件(`src/components/`) | `OrderStatusBadge` 各状态渲染 | 推荐 |
67
- | P2 | 页面组件 | 用 RTL 渲染 + msw mock | 可选 |
68
- | ❌ | ui 包源码 | 已在 `@teamix-evo/ui` 包内测过 | **不要重复测** |
69
- | ❌ | 三方库 | `react-router`、`react-query` | **不要测** |
62
+ | 优先级 | 类型 | 例子 | 必测? |
63
+ | ------ | ------------------------------------- | ----------------------------------- | -------------- |
64
+ | P0 | 纯函数(`src/utils/`、`src/services/`) | `formatMoney`、`isValidOrder` | ✅ **必测** |
65
+ | P0 | zod schema | `CreateOrderInputSchema.parse(...)` | ✅ **必测** |
66
+ | P0 | 关键业务路径(下单 / 支付 / 鉴权) | E2E-style 组件测 | ✅ **必测** |
67
+ | P1 | Hook(数据 hook + 自定义 UI hook) | `useOrderList`、`useDebounce` | 推荐 |
68
+ | P1 | 复用业务组件(`src/components/`) | `OrderStatusBadge` 各状态渲染 | 推荐 |
69
+ | P2 | 页面组件 | 用 RTL 渲染 + msw mock | 可选 |
70
+ | ❌ | ui 包源码 | 已在 `@teamix-evo/ui` 包内测过 | **不要重复测** |
71
+ | ❌ | 三方库 | `react-router`、`react-query` | **不要测** |
70
72
 
71
73
  **红线**:不要为了凑覆盖率数字测 `Button` 能不能渲染、`React.useState` 能不能用。
72
74
 
@@ -158,7 +160,9 @@ function wrapper({ children }: { children: React.ReactNode }) {
158
160
  }
159
161
 
160
162
  it('加载订单列表', async () => {
161
- const { result } = renderHook(() => useOrderList({ status: 'all' }), { wrapper });
163
+ const { result } = renderHook(() => useOrderList({ status: 'all' }), {
164
+ wrapper,
165
+ });
162
166
  await waitFor(() => expect(result.current.isSuccess).toBe(true));
163
167
  expect(result.current.data).toHaveLength(1);
164
168
  });
@@ -238,16 +242,16 @@ renderWithProviders(<OrderListPage />, { route: '/orders?status=pending' });
238
242
 
239
243
  ## §5 · 反模式速查
240
244
 
241
- | 反模式 | 为什么禁 | 应该 |
242
- | --- | --- | --- |
243
- | 测 `setState` 是否被调用 | 测了实现,重构即崩 | 测渲染结果 / 用户行为 |
244
- | `getByTestId` 当默认查询 | data-testid 跟可访问性绑不上 | `getByRole` / `getByLabelText` 优先 |
245
- | 一个 it 里 expect 10 次无关断言 | 失败定位难 | 拆多个 it |
246
- | mock 整个 hook(`vi.mock('@/hooks/...')`) | 失去集成价值 | msw mock 后端,hook 真跑 |
247
- | 自己 mock fetch / axios | 与生产代码路径不一致 | 用 msw |
248
- | 测试里写 `setTimeout(..., 1000)` 等异步 | 慢且不稳定 | `await waitFor` / `findBy*` |
249
- | 全局 mock console.error 静默 | 错过真实告警 | 让测试输出 console.error,但 setup 里 fail on it |
250
- | 追求 80% 覆盖率刷数字 | 测了没价值的代码 | 按"优先级表"测,不看覆盖率盲冲 |
245
+ | 反模式 | 为什么禁 | 应该 |
246
+ | ---------------------------------------- | ---------------------------- | ----------------------------------------------- |
247
+ | 测 `setState` 是否被调用 | 测了实现,重构即崩 | 测渲染结果 / 用户行为 |
248
+ | `getByTestId` 当默认查询 | data-testid 跟可访问性绑不上 | `getByRole` / `getByLabelText` 优先 |
249
+ | 一个 it 里 expect 10 次无关断言 | 失败定位难 | 拆多个 it |
250
+ | mock 整个 hook(`vi.mock('@/hooks/...')`) | 失去集成价值 | msw mock 后端,hook 真跑 |
251
+ | 自己 mock fetch / axios | 与生产代码路径不一致 | 用 msw |
252
+ | 测试里写 `setTimeout(..., 1000)` 等异步 | 慢且不稳定 | `await waitFor` / `findBy*` |
253
+ | 全局 mock console.error 静默 | 错过真实告警 | 让测试输出 console.error,但 setup 里 fail on it |
254
+ | 追求 80% 覆盖率刷数字 | 测了没价值的代码 | 按"优先级表"测,不看覆盖率盲冲 |
251
255
 
252
256
  ---
253
257
 
@@ -29,16 +29,18 @@ If the task is purely about _visual design_ of a screen, use [`teamix-evo-design
29
29
 
30
30
  ## What this skill does
31
31
 
32
- Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-4 are baseline (always run); steps 5-7 are topic gates (run when the task touches that topic); step 8 is the final self-review.
32
+ Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-4 are baseline (**必须执行,不得跳过**); steps 5-7 are topic gates (run when the task touches that topic); step 8 is the final self-review (**必须执行,不得跳过**).
33
33
 
34
- 1. **Reuse-first check** — read [`reuse-first.md`](reuse-first.md). Before creating any new component, query the `@teamix-evo/ui` registry (via MCP `list_components` / `find_components`), the **biz-ui/uni-manager** layer (um-topbar / CloudBadge / ContextSwitcher placeholders), and grep the local project. Only write new code when no reuse path exists. **组件兜底铁律**:找不到时优先 ui 原子件组合,**禁止**自撸基础件。
35
- 2. **Layering check** — read [`api-layering.md`](api-layering.md). Any code that talks to a backend goes under `src/services/<domain>.ts`; multi-tenant / multi-region / multi-cloud context (tenantId / regionId / cloudProvider) is **propagated through `lib/http.ts` interceptors**, not as ad-hoc params per call. Components never call `fetch` / `axios` directly. Data hooks live in `src/hooks/` and consume services.
36
- 3. **Directory check** — read [`file-structure.md`](file-structure.md). Place the new file under the right top-level folder; uni-manager-specific shells (TenantContext / RegionContext / CloudBadge) have conventional locations.
37
- 4. **Forms gate** — if the task involves a form, read [`forms-and-validation.md`](forms-and-validation.md). `react-hook-form` + `zod`; schema lives at `src/services/<domain>.schema.ts`. Dangerous operations (delete / release / destroy) **must** route through `useDangerConfirm` (input resource name).
38
- 5. **Error/loading gate** — if the task adds a page or data hook, read [`error-and-loading.md`](error-and-loading.md). Ensure global ErrorBoundary, page-level fallback, and three-state handling (`isPending` / `isError` / data) are in place; mutations report success/error via `toast`. Cross-cloud resource-not-found has a dedicated fallback.
39
- 6. **Routing gate** — if the task adds a route or page-entry, read [`routing-and-codesplit.md`](routing-and-codesplit.md). Pages use `React.lazy`; auth/role guards live in `src/routes/guards.tsx`; **list-page filters MUST sync `tenantId` / `regionId` / `cloudProvider` into URL search params**; um-topbar context switch rewrites the current URL.
40
- 7. **Testing gate** — read [`testing.md`](testing.md). Pure functions and zod schemas are **mandatory** to test; tenant-context-aware http handlers must be covered by msw.
41
- 8. **Self-review** — run [`checklist.md`](checklist.md). Every item must pass before declaring the change done.
34
+ 1. **🚧 Reuse-first check** — **MUST READ** [`reuse-first.md`](reuse-first.md). Before creating any new component, query the `@teamix-evo/ui` registry (via MCP `list_components` / `find_components`), the **biz-ui/uni-manager** layer (um-topbar / CloudBadge / ContextSwitcher placeholders), and grep the local project. Only write new code when no reuse path exists. **组件兗底铁律**:找不到时优先 ui 原子件组合,**禁止**自撸基础件。
35
+ 2. **🚧 Layering check** — **MUST READ** [`api-layering.md`](api-layering.md). Any code that talks to a backend goes under `src/services/<domain>.ts`; multi-tenant / multi-region / multi-cloud context (tenantId / regionId / cloudProvider) is **propagated through `lib/http.ts` interceptors**, not as ad-hoc params per call. Components never call `fetch` / `axios` directly. Data hooks live in `src/hooks/` and consume services.
36
+ 3. **🚧 Directory check** — **MUST READ** [`file-structure.md`](file-structure.md). Place the new file under the right top-level folder; uni-manager-specific shells (TenantContext / RegionContext / CloudBadge) have conventional locations.
37
+ 4. **🚧 Forms gate** — if the task involves a form, **MUST READ** [`forms-and-validation.md`](forms-and-validation.md). `react-hook-form` + `zod`; schema lives at `src/services/<domain>.schema.ts`. Dangerous operations (delete / release / destroy) **must** route through `useDangerConfirm` (input resource name).
38
+ 5. **Error/loading gate** — if the task adds a page or data hook, **MUST READ** [`error-and-loading.md`](error-and-loading.md). Ensure global ErrorBoundary, page-level fallback, and three-state handling (`isPending` / `isError` / data) are in place; mutations report success/error via `toast`. Cross-cloud resource-not-found has a dedicated fallback.
39
+ 6. **Routing gate** — if the task adds a route or page-entry, **MUST READ** [`routing-and-codesplit.md`](routing-and-codesplit.md). Pages use `React.lazy`; auth/role guards live in `src/routes/guards.tsx`; **list-page filters MUST sync `tenantId` / `regionId` / `cloudProvider` into URL search params**; um-topbar context switch rewrites the current URL.
40
+ 7. **Testing gate** — **MUST READ** [`testing.md`](testing.md). Pure functions and zod schemas are **mandatory** to test; tenant-context-aware http handlers must be covered by msw.
41
+ 8. **🚧 Self-review** — **MUST READ** [`checklist.md`](checklist.md). Every item must pass before declaring the change done.
42
+
43
+ > ⚠️ **禁止行为**: 跳过 Step 1 (reuse-first) 直接写新组件、跳过 Step 8 (checklist) 不做自检、凭"已有知识"省略任何文件读取。
42
44
 
43
45
  ## Inputs the user provides
44
46
 
@@ -84,7 +86,7 @@ Before AI writes or commits code, it performs an **8-step gated flow**. Steps 1-
84
86
 
85
87
  - [`teamix-evo-design-uni-manager`](../teamix-evo-design-uni-manager/SKILL.md) — visual / interaction rules for uni-manager screen generation. Run **alongside** this skill when the task includes UI; this skill never overrides design on visual concerns.
86
88
  - [`teamix-evo-code-opentrek`](../teamix-evo-code-opentrek/SKILL.md) — sister code skill for OpenTrek variant. The two skills share 80% of conventions (file structure / layering / forms / testing); uni-manager-specific deltas are in this skill's SKILL/reuse-first/api-layering/routing/checklist.
87
- - [`teamix-evo-manage`](../teamix-evo-manage/SKILL.md) — lifecycle (`init` / `update` / `uninstall` / `skills add`). Out of scope here.
89
+ - [`teamix-evo-manage`](../teamix-evo-manage/SKILL.md) — lifecycle (`init` / `update` / `uninstall` / `skills init` / `skills add`). Out of scope here.
88
90
 
89
91
  ## Why these conventions(uni-manager 视角)
90
92
 
@@ -1,5 +1,7 @@
1
1
  # API 数据层规范(uni-manager)
2
2
 
3
+ > ⚠️ **Prerequisites**: 本文件是 [SKILL.md](./SKILL.md) Step 2 的强制读取项。任何涉及后端通信的代码必须先读本文件。
4
+
3
5
  > **核心原则**:组件不直接 fetch。所有与后端通信的代码都落在 `src/services/`,通过 `src/hooks/` 暴露给组件。
4
6
  >
5
7
  > **uni-manager 增强**:多租户 / 多区域 / 跨云上下文(tenantId / regionId / cloudProvider)通过 **`src/lib/http.ts` 的 request interceptor 自动注入**,service 函数与 hook 不感知;只有"显式跨上下文"的少数 API 才在调用处显式覆盖。
@@ -1,5 +1,7 @@
1
1
  # 编码自检清单(uni-manager)
2
2
 
3
+ > ⚠️ **Prerequisites**: 本文件是 [SKILL.md](./SKILL.md) Step 8 的强制读取项。AI 写完/改完代码后必须读取并逐项核对。不得跳过。
4
+
3
5
  > AI 写完 / 改完代码后,**必须**逐项核对。任何一项未通过都不应交付,需要先修复或显式告诉用户哪条不通过、为什么。
4
6
 
5
7
  ---
@@ -1,6 +1,8 @@
1
1
  # 错误与加载态规范(uni-manager)
2
2
 
3
- > **核心约定**:渲染错误用 `ErrorBoundary`,异步加载用 `react-query` 的 `isPending/isError`(必要时叠 `Suspense`),全局兜底必须存在。**不允许**白屏 / 红屏直出给用户。**uni-manager 额外提供跨云资源专属 fallback。**
3
+ > ⚠️ **Prerequisites**: 本文件是 [SKILL.md](./SKILL.md) Step 5 的条件读取项。任务涉及页面或数据 hook 时必须读取。
4
+
5
+ > **核心约定**:渲染错误用 `ErrorBoundary`,异步加载用 `react-query` 的 `isPending/isError`(必要时叠 `Suspense`),全局兗底必须存在。**不允许**白屏 / 红屏直出给用户。**uni-manager 额外提供跨云资源专属 fallback。**
4
6
 
5
7
  ---
6
8
 
@@ -1,5 +1,7 @@
1
1
  # 业务工程目录约定(uni-manager)
2
2
 
3
+ > ⚠️ **Prerequisites**: 本文件是 [SKILL.md](./SKILL.md) Step 3 的强制读取项。AI 确定新文件放置位置前必须读完本文件。
4
+
3
5
  > 业内主流 React/Vite 业务工程的标准目录骨架。本文件是 AI 决定"新建文件应该放在哪"的唯一参考。**uni-manager 在通用结构基础上,额外约定多租户/多区域/跨云上下文相关目录。**
4
6
 
5
7
  ---
@@ -1,5 +1,7 @@
1
1
  # 表单与校验规范(uni-manager)
2
2
 
3
+ > ⚠️ **Prerequisites**: 本文件是 [SKILL.md](./SKILL.md) Step 4 的条件读取项。任务涉及表单时必须读取。
4
+
3
5
  > **核心约定**:表单状态用 `react-hook-form`,schema 用 `zod`,**永远不要**用一堆 `useState` 拼表单。**uni-manager 额外约定:危险操作走 `useDangerConfirm`(输入资源完整名称才执行),切租户/区域时表单未保存内容必须二次确认。**
4
6
 
5
7
  ---
@@ -1,8 +1,10 @@
1
1
  # Reuse-First · 组件 / 工具复用决策流(uni-manager)
2
2
 
3
+ > ⚠️ **Prerequisites**: 本文件是 [SKILL.md](./SKILL.md) Step 1 的强制读取项。AI 写任何新代码前必须先读完本文件并执行复用查询。
4
+
3
5
  > 在写**任何**新组件 / Hook / 工具函数之前,AI 必须按本流程跑一遍。"没找到现成的"必须是查询的结论,不能是默认假设。
4
6
  >
5
- > uni-manager 在 OpenTrek 通用流程之上,叠加 **biz-ui/uni-manager** 实物层与"组件兜底铁律"。
7
+ > uni-manager 在 OpenTrek 通用流程之上,叠加 **biz-ui/uni-manager** 实物层与"组件兗底铁律"。
6
8
 
7
9
  ---
8
10
 
@@ -1,6 +1,8 @@
1
1
  # 路由与代码分包规范(uni-manager)
2
2
 
3
- > **核心约定**:页面级 `React.lazy` 默认分包,鉴权 / 角色守卫集中在 `src/routes/`,404 / 401 / 403 必有兜底。**uni-manager 额外约定:tenantId / regionId / cloudProvider 同步到 URL search params,um-topbar 切换上下文时改写 URL。**
3
+ > ⚠️ **Prerequisites**: 本文件是 [SKILL.md](./SKILL.md) Step 6 的条件读取项。任务涉及路由或页面入口时必须读取。
4
+
5
+ > **核心约定**:页面级 `React.lazy` 默认分包,鉴权 / 角色守卫集中在 `src/routes/`,404 / 401 / 403 必有兗底。**uni-manager 额外约定:tenantId / regionId / cloudProvider 同步到 URL search params,um-topbar 切换上下文时改写 URL。**
4
6
 
5
7
  ---
6
8
 
@@ -1,5 +1,7 @@
1
1
  # 测试规范(uni-manager)
2
2
 
3
+ > ⚠️ **Prerequisites**: 本文件是 [SKILL.md](./SKILL.md) Step 7 的读取项。纯函数和 zod schema 必测,其余按关键路径覆盖。
4
+
3
5
  > **核心约定**:`vitest` + `@testing-library/react` + `msw`,文件就近 `*.test.ts(x)`。**不追求覆盖率数字**,追求"关键路径必有测试 + 纯函数全测"。**uni-manager 额外要求 msw handler 校验 X-Tenant-Id / X-Region-Id / X-Cloud-Provider 请求头。**
4
6
 
5
7
  ---
@@ -17,55 +17,48 @@ description: |
17
17
 
18
18
  <!-- teamix-evo:managed:start id="core" -->
19
19
 
20
- ## 意图路由
20
+ ## ⚠️ 执行协议(MANDATORY — 跳步即失败)
21
21
 
22
- 收到页面相关请求时,按意图分流:
22
+ 收到页面相关请求时,**必须先识别意图,再进入对应的唯一执行路径**。不允许跳过路径中的任何步骤。
23
23
 
24
- | 意图 | 识别关键词 | 执行路径 |
25
- | -------- | -------------------------------------------------- | ------------------------------------------- |
26
- | **生成** | "生成" / "创建" / "新建" / "设计一个" / "做一个" | → generation-flow.md 六步流程 |
27
- | **翻新** | "改造" / "升级" / "翻新" / "对齐规范" / "重新生成" | → generation-flow.md §翻新路径 |
28
- | **验证** | "检查" / "验证" / "评估" / "是否符合规范" | → checklist.md 逐项对照 |
29
- | **查询** | "token" / "色值" / "间距" / "组件尺寸" | → foundations.md(MCP `tokens_*` 工具规划中) |
24
+ ### 意图路由
30
25
 
31
- ## 三阶段 Dispatch
26
+ | 意图 | 识别关键词 | 唯一执行路径 |
27
+ | -------- | -------------------------------------------------- | ----------------------------------------------------------------------- |
28
+ | **生成** | "生成" / "创建" / "新建" / "设计一个" / "做一个" | **必须完整执行** [generation-flow.md](./generation-flow.md) §1 七步门控 |
29
+ | **翻新** | "改造" / "升级" / "翻新" / "对齐规范" / "重新生成" | **必须完整执行** [generation-flow.md](./generation-flow.md) §2 翻新路径 |
30
+ | **验证** | "检查" / "验证" / "评估" / "是否符合规范" | **必须完整执行** [generation-flow.md](./generation-flow.md) §3 验证路径 |
31
+ | **查询** | "token" / "色值" / "间距" / "组件尺寸" / "圆角" | → [foundations.md](./foundations.md)(MCP `tokens_*` 工具规划中) |
32
32
 
33
- ```
34
- 阶段 ① 确定页面类型
35
- → 读 patterns/page-types.md 决策树
36
- → 读 components.md 确认组件集
33
+ ### 不可跳过的前置读取
37
34
 
38
- 阶段 匹配子类型 + 布局
39
- - List / Detail / Form → patterns/{list|detail|form}-page.md
40
- - Dashboard → patterns/dashboard.md
41
- - Dialog/Sheet/Drawer → 视为复合组件(非页面);走 components.md §3.1 选型
42
- + boundaries.md F8 / F9 / S7 / C2 / FF1-FF4
43
- → 读 patterns/page-types.md §6 确认页间流转(主流转图 / 规则 / CRUD 速查)
44
- → 涉及用户旅程时读 flows.md(A 资源查找 / B 创建 / C 异常 / D 批量)
35
+ 无论哪种意图,进入 generation-flow.md 后**每个 Step 都有明确的 MUST READ 文件清单**。AI 不得凭"已有知识"跳过任何文件读取 — 每次任务必须重新读取,因为文件内容可能已更新。
45
36
 
46
- 阶段 ③ 生成代码
47
- → 读 foundations.md (Token 约束)
48
- boundaries.md (硬规则)
49
- MCP get_component_meta(id) 查组件 Props
50
- 对照 checklist.md 自检
51
- ```
37
+ ### 禁止行为
38
+
39
+ - 跳过 generation-flow.md 直接写代码
40
+ - 只读 patterns/\*.md 不读 philosophy.md / boundaries.md / foundations.md
41
+ - 选择性读取("这个文件我已经知道内容了")
42
+ - ❌ 把 SKILL.md 文件索引当作"我可以只挑一个读"的菜单
52
43
 
53
44
  ## 文件索引
54
45
 
55
- | 文件 | 职责 |
56
- | ---------------------------------------------------- | -------------------------------------------------------- |
57
- | [philosophy.md](./philosophy.md) | 设计哲学 + 四大原则 + 方法论 |
58
- | [generation-flow.md](./generation-flow.md) | AI 六步生成/翻新/验证流程 |
59
- | [boundaries.md](./boundaries.md) | 硬约束:F/FF/S/C/I 五组共 38 条规则([ERROR]/[WARN]) |
60
- | [checklist.md](./checklist.md) | 10 项自检清单 |
61
- | [foundations.md](./foundations.md) | Token 用法 + 排版 + 间距 + 色彩 + 圆角 + 阴影 + 动效 |
62
- | [components.md](./components.md) | 组件选型决策树 + 双层架构索引 + 组合规则 |
63
- | [patterns/page-types.md](./patterns/page-types.md) | 5 种页面类型 + 识别决策树 + Zone Map + 页间流转(§6) |
64
- | [patterns/list-page.md](./patterns/list-page.md) | 列表页模式 (6 种子类型) |
65
- | [patterns/detail-page.md](./patterns/detail-page.md) | 详情页模式 |
66
- | [patterns/form-page.md](./patterns/form-page.md) | 表单页模式 (含 wizard) |
67
- | [patterns/dashboard.md](./patterns/dashboard.md) | Dashboard 数据概览(StatCard / Chart 标准结构) |
68
- | [flows.md](./flows.md) | 4 条核心用户旅程 + 流转自检 |
69
- | [brand.md](./brand.md) | OpenTrek 品牌调性 + 文案语气 + 正反例 |
46
+ | 文件 | 职责 |
47
+ | -------------------------------------------------------- | --------------------------------------------------------------------- |
48
+ | [philosophy.md](./philosophy.md) | 设计哲学 + 四大原则 + 方法论 |
49
+ | [generation-flow.md](./generation-flow.md) | AI 六步生成/翻新/验证流程 |
50
+ | [boundaries.md](./boundaries.md) | 硬约束:F/FF/S/C/I 五组共 38 条规则([ERROR]/[WARN]) |
51
+ | [checklist.md](./checklist.md) | 10 项自检清单 |
52
+ | [foundations.md](./foundations.md) | Token 用法 + 排版 + 间距 + 色彩 + 圆角 + 阴影 + 动效 |
53
+ | [components.md](./components.md) | 组件选型决策树 + 双层架构索引 + 组合规则 |
54
+ | [patterns/page-types.md](./patterns/page-types.md) | 5 种页面类型 + 识别决策树 + Zone Map + 页间流转(§6) |
55
+ | [patterns/list-page.md](./patterns/list-page.md) | 列表页模式 (6 种子类型) |
56
+ | [patterns/detail-page.md](./patterns/detail-page.md) | 详情页模式 |
57
+ | [patterns/form-page.md](./patterns/form-page.md) | 表单页模式 (含 wizard) |
58
+ | [patterns/dashboard.md](./patterns/dashboard.md) | Dashboard 数据概览(StatCard / Chart 标准结构) |
59
+ | [patterns/sidebar.md](./patterns/sidebar.md) | 侧边栏统一规范(3 / 2 级结构、收起态、品牌色槽位、禁止清单) |
60
+ | [patterns/color-mapping.md](./patterns/color-mapping.md) | v4.1 语义色映射表(主色 / 状态 5 档 / gray 8 / accent 10 / chart 10) |
61
+ | [flows.md](./flows.md) | 4 条核心用户旅程 + 流转自检 |
62
+ | [brand.md](./brand.md) | OpenTrek 品牌调性 + 文案语气 + 正反例 |
70
63
 
71
64
  <!-- teamix-evo:managed:end -->
@@ -1,6 +1,9 @@
1
1
  # 硬约束 · Boundaries
2
2
 
3
- > 本文件列出所有"AI 生成页面 / 组件代码时**不能做什么**"的硬规则。共 38 条规则分 5 组:
3
+ > ⚠️ **何时读本文件**: [generation-flow.md](./generation-flow.md) Step 7(自检)、翻新路径、验证路径均强制要求完整读取本文件。
4
+ > 本文件是硬规则的**唯一真值**,不得跳过。
5
+
6
+ > 本文件列出所有“AI 生成页面 / 组件代码时**不能做什么**”的硬规则。共 38 条规则分 5 组:
4
7
  >
5
8
  > - **F1-F10**:禁止项(视觉与 token 层面)
6
9
  > - **FF1-FF4**:表单专属硬约束(错误信息、必填、状态色块、Card 嵌套)
@@ -41,6 +44,23 @@
41
44
  >
42
45
  > 检查: eslint `teamix-evo/no-arbitrary-tw-value` (Tailwind className) · stylelint `teamix-evo/no-hardcoded-dimension` (CSS gap/padding/margin/width/height/font-size 等)
43
46
 
47
+ ### [ERROR] F2.5 · 禁止使用原生 HTML form 控件
48
+
49
+ ```diff
50
+ - <input value={v} onChange={(e) => setV(e.target.value)} />
51
+ - <select value={v} onChange={(e) => setV(e.target.value)}>...</select>
52
+ - <textarea ... />
53
+ + <Input value={v} onChange={setV} />
54
+ + <Select options={...} value={v} onChange={setV} />
55
+ + <Textarea ... />
56
+ ```
57
+
58
+ 任何场景(业务页面 / 模板 demo / 示例代码 / story)**都禁止**直接使用原生 `<input>` / `<select>` / `<textarea>` / `<form>` 字段元素 — 必须用 ui 包的 `<Input>` / `<Select>` / `<Textarea>` / `<Switch>` / `<Checkbox>` / `<RadioGroup>` / `<DatePicker>` 等组件。原生控件不带 token 视觉、不联动 Field 校验态、不参与 `react-hook-form` Controller。
59
+
60
+ **列表筛选区**用 `<FilterBarPreset>` / `<FilterBar>` + `<FormField>` + 原子组件;**表单页**用 `<Form>` + `<FieldGroup>` + `<FormField>` + 原子组件;**单字段输入**仍用 `<Input>` / `<Select>` 直传 value/onChange。
61
+
62
+ > 检查: eslint(规划中:`teamix-evo/no-native-form-control`)+ 人工 review
63
+
44
64
  ### [ERROR] F3 · 禁止按组件新增重复语义变量
45
65
 
46
66
  新增 CSS 变量前**必须**先检索 `tokens/theme.css`:
@@ -155,7 +175,7 @@
155
175
  + </Card>
156
176
  ```
157
177
 
158
- 白卡是表单页的**单例容器**(参 [list-page.md §9 嵌套约束](./patterns/list-page.md#9-嵌套约束) / [form-page.md §9](./patterns/form-page.md#9-嵌套约束))。分区表单确需嵌入子 Card 时,子 Card 必须有明确边框/阴影差异,且仅限**分区表单**用例(form-page.md §2.3)。
178
+ 白卡由 [`OpPageContainer`](../../biz-ui/variants/opentrek/op-page-container/op-page-container.meta.md) **内置**(`bg-card rounded-2xl p-6` 撑满主区),是 opentrek 任何页面类型的**单例容器**(参 [list-page.md §9 嵌套约束](./patterns/list-page.md#9-嵌套约束) / [form-page.md §9](./patterns/form-page.md#9-嵌套约束))。**不要再手写 `<Card>` 包整个 PageHeader / DataTable / Form**(违反白卡单例)。分区表单确需在白卡内嵌入子 Card 划分若干小节时,子 Card 必须有明确边框/阴影差异,且仅限**分区表单**用例(form-page.md §2.3)。
159
179
 
160
180
  > 检查: 无 lint (人工评审 / reviewer subagent)
161
181
 
@@ -6,13 +6,13 @@
6
6
 
7
7
  ## 1. 视觉风格五维
8
8
 
9
- | 维度 | 定位 | 具体表现 | 对立面(禁止) |
10
- | ------------ | -------- | --------------------------------------- | -------------------- |
11
- | **色彩情绪** | 沉稳专业 | 深色底色为主基调 + 高对比度信息层级 | 花哨多彩、渐变堆叠 |
12
- | **信息密度** | 高效紧凑 | 单屏承载核心操作,减少翻页 | 大面积留白、装饰占位 |
13
- | **视觉层次** | 克制有序 | 间距、字重、色彩建立 3 级层级 | 多重强调、全部高亮 |
14
- | **交互反馈** | 即时确定 | 操作后 200ms 内明确反馈 | 模糊状态、静默 |
15
- | **圆角风格** | 轻圆角 | `rounded-md` (6px) / `rounded-lg` (8px) | 全直角、超大圆角 |
9
+ | 维度 | 定位 | 具体表现 | 对立面(禁止) |
10
+ | ------------ | -------- | ---------------------------------------------------------------------------------- | -------------------- |
11
+ | **色彩情绪** | 沉稳专业 | 品牌主色 `#0055EE` (hsl(218.6 100% 46.7%)) + 高对比信息层级 | 花哨多彩、渐变堆叠 |
12
+ | **信息密度** | 高效紧凑 | 单屏承载核心操作,减少翻页 | 大面积留白、装饰占位 |
13
+ | **视觉层次** | 克制有序 | 间距、字重、色彩建立 3 级层级 | 多重强调、全部高亮 |
14
+ | **交互反馈** | 即时确定 | 操作后 200ms 内明确反馈 | 模糊状态、静默 |
15
+ | **圆角风格** | 中圆角 | OpenTrek v4.1:`rounded-md` (8px) / `rounded-lg` (12px);legacy `rounded-sm` (4px) | 全直角、超大圆角 |
16
16
 
17
17
  ---
18
18
 
@@ -8,19 +8,20 @@
8
8
 
9
9
  ## 强制项(12)
10
10
 
11
- | # | 检查点 | 失败示例 | 通过条件 | 规则 |
12
- | --- | ------------------------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------- | -------------- |
13
- | 1 | 无硬编码色值 | `bg-[#fff]` / `style={{color:'red'}}` | 走语义 token:`bg-background` / `text-foreground` | [F1] |
14
- | 2 | 状态不用原始色 | `text-green-500` / `bg-red-100` | `<Badge variant="secondary">` / `text-destructive` | [S8] |
15
- | 3 | 间距用 gap | `space-y-4` | `flex flex-col gap-4` | [S2] |
16
- | 4 | className 不覆盖组件颜色 / 字体 | `<Button className="bg-blue-500">` | `<Button variant="default">` | [S1] |
17
- | 5 | 复合组件结构完整 | `<Dialog>` DialogTitle / `<Tabs>` 直接放 Trigger | Dialog Title;Card Header+Content;Tabs List;详见 C | [C1-C12] |
18
- | 6 | 状态 / 占位 / 分隔走专用组件 | 自定义 styled span Badge / animate-pulse div | Badge / Skeleton / Empty / Separator / Alert / `toast()` | [C7-C12] |
19
- | 7 | 图标用 data-icon,不设尺寸类 | `<SearchIcon className="size-4 mr-2" />` | `<SearchIcon data-icon="inline-start" />` | [I1-I2] |
20
- | 8 | 不手动 z-index / dark: 覆盖 | `className="z-50"` / `dark:bg-gray-950` | 删除 z-index(组件自管);用语义 token | [S5] [S7] |
21
- | 9 | 条件类名用 cn() | `` `${active ? 'a' : 'b'}` `` | `cn('base', active ? 'a' : 'b')` | [S6] |
22
- | 10 | 危险操作二次确认 | `<Button onClick={delete}>删除</Button>` | `<AlertDialog>` + 陈述句标题 + 影响列表 + 重复动词按钮 | P4 [philosophy] |
23
- | 11 | 可交互元素显式带手型 | `<button onClick={...}>` 不带 `cursor-pointer` | `cursor-pointer` + `disabled:cursor-not-allowed` | [ADR0023] |
11
+ | # | 检查点 | 失败示例 | 通过条件 | 规则 |
12
+ | --- | --- | --- | --- | --- |
13
+ | 1 | 无硬编码色值 | `bg-[#fff]` / `style={{color:'red'}}` | 走语义 token:`bg-background` / `text-foreground` | [F1] |
14
+ | 2 | 状态不用原始色 | `text-green-500` / `bg-red-100` | `<Badge variant="secondary">` / `text-destructive` | [S8] |
15
+ | 3 | 间距用 gap | `space-y-4` | `flex flex-col gap-4` | [S2] |
16
+ | 4 | className 不覆盖组件颜色 / 字体 | `<Button className="bg-blue-500">` | `<Button variant="default">` | [S1] |
17
+ | 4.1 | Button 不传 size | `<Button size="sm">` / `<Button size="sm" className="h-9 w-9 p-0">` | `<Button>...</Button>`(default = `h-8` + `text-xs` 12px,ADR 0027 对齐 cd hybridcloud form-element-medium);icon-only `size="icon"` | [ADR0027] |
18
+ | 5 | 复合组件结构完整 | `<Dialog>` DialogTitle / `<Tabs>` 直接放 Trigger | Dialog Title;Card Header+Content;Tabs List;详见 C | [C1-C12] |
19
+ | 6 | 状态 / 占位 / 分隔走专用组件 | 自定义 styled span 当 Badge / animate-pulse div | Badge / Skeleton / Empty / Separator / Alert / `toast()` | [C7-C12] |
20
+ | 7 | 图标用 data-icon,不设尺寸类 | `<SearchIcon className="size-4 mr-2" />` | `<SearchIcon data-icon="inline-start" />` | [I1-I2] |
21
+ | 8 | 不手动 z-index / dark: 覆盖 | `className="z-50"` / `dark:bg-gray-950` | 删除 z-index(组件自管);用语义 token | [S5] [S7] |
22
+ | 9 | 条件类名用 cn() | `` `${active ? 'a' : 'b'}` `` | `cn('base', active ? 'a' : 'b')` | [S6] |
23
+ | 10 | 危险操作二次确认 | `<Button onClick={delete}>删除</Button>` | `<AlertDialog>` + 陈述句标题 + 影响列表 + 重复动词按钮 | P4 [philosophy] |
24
+ | 11 | 可交互元素显式带手型 | `<button onClick={...}>` 不带 `cursor-pointer` | `cursor-pointer` + `disabled:cursor-not-allowed` | [ADR0023] |
24
25
 
25
26
  > **强制项 #12(并入 #11 的纪律范围,与 [ADR 0024](../../../../../docs/adr/0024-scoped-css-radix-state-conflict.md) 同步)**:hover / focus 视觉反馈(border / bg / shadow)写在组件源码 className 时**必须**用 `enabled:` 前缀,disabled 态不触发样式变化。失败示例 `hover:border-primary`(disabled 仍响应);通过示例 `enabled:hover:border-primary`。Radix `data-state="checked"` / `"indeterminate"` / `"on"` 激活态视觉由组件自管,uni-manager scoped CSS 已统一在 `:not()` 链里排除这三个态值,新组件接入 `border-input` 类时务必核对。
26
27
  >
@@ -28,6 +29,7 @@
28
29
 
29
30
  [F1]: ./boundaries.md
30
31
  [ADR0023]: ../../../../../docs/adr/0023-cursor-pointer-explicit-in-component-source.md
32
+ [ADR0027]: ../../../../../docs/adr/0027-component-visual-token-alignment.md
31
33
  [S1]: ./boundaries.md
32
34
  [S2]: ./boundaries.md
33
35
  [S5]: ./boundaries.md
@@ -1,5 +1,8 @@
1
1
  # Components — 选型决策与组合规则
2
2
 
3
+ > ⚠️ **Prerequisites**: 你必须已完成 [generation-flow.md](./generation-flow.md) Step 1–3(已确定页面类型 + 子类型 + 区域骨架)后才能读本文件。
4
+ > 若未完成前置步骤,请先返回 [generation-flow.md](./generation-flow.md) 从 Step 1 开始。
5
+
3
6
  > **本文档只回答"用什么组件、怎么搭配",不写具体 Props / Examples / import 路径。**
4
7
  > 组件 API、Props、示例代码通过 MCP `get_component_meta` 实时查询;可用列表通过 `list_components` / `find_components` 查询。
5
8
 
@@ -13,24 +16,29 @@
13
16
 
14
17
  调用 `list_components` / `find_components` 命中失败、或本文件提到的组件名(例如 `SearchCombo` / `ContextSwitcher` / `ItemCard` / `CardGrid` / `CardActionBar`)在 `@teamix-evo/biz-ui` 中无实物时。
15
18
 
16
- ### 0.2 三步处置法
19
+ ### 0.2 四步处置法
17
20
 
18
21
  1. **不要自造同名组件入 `src/components/`** — 即使本文件提到该组件名,也必须先确认实物存在。
19
- 2. **改用 `@teamix-evo/ui` 中语义近似的原子组件做最小拼装**(参见本文件 §3 决策树和 §5 拼凑配方)。
20
- 3. **在响应中显式声明替代关系**,例如:
22
+ 2. **优先扫所有 ui 单体找语义等价**(见 §0.4) — 在 `@teamix-evo/ui` 89 个原子件中用 `find_components` 模糊搜 + 按七类法分类筛,找功能 / 结构等价的**单体**直接用。**这一步不可跳**。
23
+ 3. **单体彻底无等价 → 才用 ui 多原子最小拼装**(参见本文件 §3 决策树和 §5 拼凑配方)。
24
+ 4. **在响应中显式声明替代关系**,例如:
21
25
 
22
- > `// SearchCombo 暂未实物化 → Input + Select + Button 拼装`
26
+ > `// SearchCombo 暂未实物化 → ui filter-bar 单体语义等价 → 直接采用` > `// 或:// SearchCombo 暂未实物化 → 89 件单体扫尽无等价 → Input + Select + Button 最小拼装`
23
27
 
24
28
  ### 0.3 兜底优先序
25
29
 
26
30
  ```text
27
- biz-ui 实物组件 (优先)
31
+ biz-ui 实物组件(优先)
32
+ ↓ 未命中
33
+ ui 原子 — 精确名匹配(dialog→Dialog / button→Button…)
28
34
  ↓ 未命中
29
- ui 原子组件最小拼装 (兜底)
35
+ ui 原子 — 语义近似单体替代(扫所有 89 件,见 §0.4) ← 关键档:穷尽前不允许进下一档
36
+ ↓ 仍未命中
37
+ ui 多原子最小拼装(万不得已,注释声明)
30
38
  ↓ 仍无法表达
31
39
  跳转 patterns/*.md 找页面级模板
32
40
  ↓ 仍无法表达
33
- 回报用户:缺组件 + 已尝试拼装方案
41
+ 回报用户:缺组件 + 已尝试单体扫描记录 + 拼装方案
34
42
  ```
35
43
 
36
44
  **永远不要**:
@@ -38,6 +46,43 @@ ui 原子组件最小拼装 (兜底)
38
46
  - 在 `src/components/` 下新增与 biz-ui 同名的"私有版本"
39
47
  - 用 antd / arco / chakra 等其它库填补缺口
40
48
  - 在 skill 响应中写"假设 biz-ui 有 X"而不实查 MCP
49
+ - **跳过 §0.4 直接进多原子拼装** — 属于"以拼代查",违反单体优先原则
50
+
51
+ ---
52
+
53
+ ### 0.4 语义近似单体扫描指南(兜底关键步骤)
54
+
55
+ > 「**语义近似单体**」= ui 89 个原子里找到一个**功能等价 / 结构相容 / 视觉中性**的组件直接使用,避免几个原子捆一起的拼装代价。这是 §0.3 第 3 档的实操定义。
56
+
57
+ **扫描三板斧**:
58
+
59
+ 1. **关键词模糊搜**:`find_components(kw)` 多关键词试 — 例 `SearchBox` → 试 `search` / `find` / `query` / `filter` / `combo`
60
+ 2. **七类法分类筛**(按要做的事归类,再翻该类下的 ui 原子):
61
+ - `general`:Button / Icon / Typography
62
+ - `layout`:Flex / Grid / Space / Separator / Sidebar / PageHeader / Card / Container
63
+ - `navigation`:Breadcrumb / Pagination / DropdownMenu / Steps / NavigationMenu / Tabs
64
+ - `data-entry`:参见 §3.6 输入控件
65
+ - `data-display`:参见 §3.4 / §3.5;含 Accordion / Tooltip / Table / DataTable / Badge / Tag / Avatar / Descriptions / Statistic
66
+ - `feedback`:Alert / Dialog / Drawer / Sheet / Popover / Progress / Spinner / Empty / Skeleton / Toast
67
+ - `deprecated`:不出现在 `list_components` 默认结果,无视
68
+ 3. **能力边界核对**:候选单体用 `get_component_meta(name)` 确认 Props 是否承载所需语义,避免"看名字像"实际不通
69
+
70
+ **典型语义近似映射**(仅示例,使用前仍需 MCP 实查):
71
+
72
+ | 找不到的概念 | 优先尝试单体(语义近似) | 万不得已的拼装兜底 |
73
+ | ------------------ | -------------------------------------- | --------------------------------- |
74
+ | `ItemCard` | `card`(直接用) | CardHeader + CardContent + Footer |
75
+ | `SearchCombo` | `filter-bar`(直接用) | Input + Select + Button |
76
+ | `ContextSwitcher` | `combobox` / `dropdown-menu`(直接用) | command + popover + avatar |
77
+ | `Empty` / `NoData` | `empty`(直接用) | div + Icon + Text |
78
+ | `Loading` | `spinner` / `skeleton`(直接用) | div + animate-spin |
79
+ | `ConfirmDialog` | `alert-dialog`(直接用) | dialog + button + text |
80
+ | `StatusTag` | `badge` / `tag`(按 §3.3) | div + dot + text |
81
+
82
+ **严禁反模式**:
83
+
84
+ - 单体语义等价时仍按概念名拼装(例:明明有 `empty` 偏写 `<div className="flex flex-col items-center"><Icon><span>暂无数据</span></div>`)
85
+ - 把"最小拼装"理解为"多原子捆绑就行",而不是先**穷尽 89 件单体**
41
86
 
42
87
  ---
43
88
 
@@ -51,9 +96,10 @@ ui 原子组件最小拼装 (兜底)
51
96
  ### 1.1 选型铁律
52
97
 
53
98
  1. **优先 biz-ui 实物层** — 已封装变体 + 文案规范,但**注意 opentrek 当前仅 2 个实物**。
54
- 2. **biz-ui 无实物 → ui 实现层**89 个原子件覆盖绝大部分场景。
55
- 3. **ui 仍无 §5 拼凑配方** ui 多个原子件最小组合(不私造)。
56
- 4. **禁止**自造同名组件(违反 reuse-first,详见 §0)。
99
+ 2. **biz-ui 无实物 → ui 单体精确名匹配**按组件名 / 显式语义直查 `find_components`。
100
+ 3. **精确名未命中 → ui 单体语义近似扫描**(见 §0.4) 89 件里找等价单体直接用,**这一步不可跳**。
101
+ 4. **单体彻底无等价 §5 多原子最小拼装** — 仅作为单体穷尽后的兜底。
102
+ 5. **禁止**自造同名组件(违反 reuse-first,详见 §0)。
57
103
 
58
104
  ### 1.2 实时校验
59
105
 
@@ -151,6 +197,8 @@ ui 原子组件最小拼装 (兜底)
151
197
  枚举值 8~30 → Select
152
198
  枚举值 > 30 / 需搜索 → Combobox(= ui command)
153
199
  多选 → MultiSelect / Checkbox
200
+ 数值(整数/小数/金额)→ InputNumber(带 min/max/step/precision)
201
+ 数值范围可视化 → Slider(仅用于资源配比/阈值的拖拽式选择)
154
202
  日期 → DatePicker / DateRangePicker
155
203
  富文本 → Textarea / RichEditor
156
204
  文件 → Upload
@@ -237,7 +285,8 @@ ui 原子组件最小拼装 (兜底)
237
285
  通用结构性规则 → 见 [checklist.md](./checklist.md)(C1-C12 / I1-I4)。本文件特有的"选型决策"自检:
238
286
 
239
287
  - [ ] 已先用 `find_components` 验证组件存在性(不靠默认)
240
- - [ ] biz-ui 命中失败 → 改用 ui 原子件,按 §5.2 配方拼装并加注释
288
+ - [ ] biz-ui 命中失败 → **先按 §0.4 扫所有 ui 单体找语义近似替代**,单体覆盖时直接采用,未直接跳到 §5 拼装
289
+ - [ ] 单体彻底无等价时 → §5 拼装代码必加注释 `// 已扫尽 89 件 ui 单体无语义等价 → 拼装`
241
290
  - [ ] 反馈 / 确认场景按容量选 Dialog / Sheet / Drawer / Popover
242
291
  - [ ] 容器层级 ≤ 3,弹窗最多 2 级,超过则跳转全页面
243
292
  - [ ] 卡片列表优先 biz-ui `list-card`,否则用 `card[] + grid` 拼
@@ -1,5 +1,8 @@
1
1
  # Foundations — Token 用法指南
2
2
 
3
+ > ⚠️ **何时读本文件**: [generation-flow.md](./generation-flow.md) Step 6(视觉填充)强制要求完整读取。
4
+ > 任何色彩、间距、字号、圆角、阴影、动效必须基于本文件的 Token 定义,不得凭记忆生成。
5
+
3
6
  > **核心原则**:所有视觉值必须来自 `@teamix-evo/tokens` 暴露的 CSS 变量;禁止硬编码颜色、间距、圆角、阴影、时长。
4
7
 
5
8
  ---