@teamix-evo/skills 0.3.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.
- package/README.md +7 -3
- package/manifest.json +63 -46
- package/package.json +3 -3
- package/src/teamix-evo-code-opentrek/SKILL.md +94 -0
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/api-layering.md +8 -5
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/checklist.md +4 -2
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/error-and-loading.md +38 -25
- package/src/teamix-evo-code-opentrek/file-structure.md +282 -0
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/forms-and-validation.md +14 -12
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/reuse-first.md +27 -17
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/routing-and-codesplit.md +23 -21
- package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/testing.md +32 -28
- package/src/teamix-evo-code-uni-manager/SKILL.md +97 -0
- package/src/teamix-evo-code-uni-manager/api-layering.md +372 -0
- package/src/teamix-evo-code-uni-manager/checklist.md +195 -0
- package/src/teamix-evo-code-uni-manager/error-and-loading.md +391 -0
- package/src/teamix-evo-code-uni-manager/file-structure.md +341 -0
- package/src/teamix-evo-code-uni-manager/forms-and-validation.md +461 -0
- package/src/teamix-evo-code-uni-manager/reuse-first.md +190 -0
- package/src/teamix-evo-code-uni-manager/routing-and-codesplit.md +452 -0
- package/src/teamix-evo-code-uni-manager/testing.md +398 -0
- package/src/teamix-evo-design-opentrek/SKILL.md +64 -0
- package/src/teamix-evo-design-opentrek/boundaries.md +533 -0
- package/src/teamix-evo-design-opentrek/brand.md +154 -0
- package/src/teamix-evo-design-opentrek/checklist.md +85 -0
- package/src/teamix-evo-design-opentrek/components.md +294 -0
- package/src/teamix-evo-design-opentrek/flows.md +51 -0
- package/src/teamix-evo-design-opentrek/foundations.md +274 -0
- package/src/teamix-evo-design-opentrek/generation-flow.md +243 -0
- package/src/teamix-evo-design-opentrek/patterns/color-mapping.md +96 -0
- package/src/teamix-evo-design-opentrek/patterns/dashboard.md +33 -0
- package/src/teamix-evo-design-opentrek/patterns/detail-page.md +203 -0
- package/src/teamix-evo-design-opentrek/patterns/form-page.md +292 -0
- package/src/teamix-evo-design-opentrek/patterns/list-page.md +367 -0
- package/src/teamix-evo-design-opentrek/patterns/page-types.md +159 -0
- package/src/teamix-evo-design-opentrek/patterns/sidebar.md +122 -0
- package/src/teamix-evo-design-opentrek/philosophy.md +98 -0
- package/src/teamix-evo-design-opentrek/rules/README.md +39 -0
- package/src/teamix-evo-design-opentrek/rules/boundaries.rules.json +391 -0
- package/src/teamix-evo-design-uni-manager/SKILL.md +64 -0
- package/src/teamix-evo-design-uni-manager/boundaries.md +567 -0
- package/src/teamix-evo-design-uni-manager/brand.md +202 -0
- package/src/teamix-evo-design-uni-manager/checklist.md +115 -0
- package/src/teamix-evo-design-uni-manager/components.md +257 -0
- package/src/teamix-evo-design-uni-manager/flows.md +63 -0
- package/src/teamix-evo-design-uni-manager/foundations.md +261 -0
- package/src/teamix-evo-design-uni-manager/generation-flow.md +230 -0
- package/src/teamix-evo-design-uni-manager/patterns/dashboard.md +97 -0
- package/src/teamix-evo-design-uni-manager/patterns/detail-page.md +253 -0
- package/src/teamix-evo-design-uni-manager/patterns/form-page.md +366 -0
- package/src/teamix-evo-design-uni-manager/patterns/list-page.md +389 -0
- package/src/teamix-evo-design-uni-manager/patterns/page-types.md +167 -0
- package/src/teamix-evo-design-uni-manager/philosophy.md +108 -0
- package/src/teamix-evo-design-uni-manager/rules/README.md +49 -0
- package/src/teamix-evo-design-uni-manager/rules/boundaries.rules.json +418 -0
- package/src/teamix-evo-manage/SKILL.md +289 -0
- package/skills/teamix-evo-coding-conventions/SKILL.md +0 -92
- package/skills/teamix-evo-coding-conventions/file-structure.md +0 -273
- package/skills/teamix-evo-design-rules/SKILL.md +0 -86
- package/skills/teamix-evo-design-rules/boundaries.md +0 -89
- package/skills/teamix-evo-design-rules/checklist.md +0 -108
- package/skills/teamix-evo-design-rules/generation-flow.md +0 -142
- package/skills/teamix-evo-design-rules/prompts/page-design.md +0 -148
- package/skills/teamix-evo-design-rules-opentrek/SKILL.md +0 -48
- package/skills/teamix-evo-design-rules-opentrek/brand-rules.md +0 -74
- package/skills/teamix-evo-design-rules-uni-manager/SKILL.md +0 -51
- package/skills/teamix-evo-design-rules-uni-manager/ai-scenarios.md +0 -51
- package/skills/teamix-evo-design-rules-uni-manager/command-center.md +0 -108
- package/skills/teamix-evo-design-rules-uni-manager/danger-ops.md +0 -87
- package/skills/teamix-evo-manage/SKILL.md +0 -178
- package/skills/teamix-evo-ui-upgrade/SKILL.md +0 -75
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# 自检清单 · OpenTrek
|
|
2
|
+
|
|
3
|
+
> AI 生成 / 翻新页面后**必须**逐项对照本清单。规则细节看 [boundaries.md](./boundaries.md),本文件只列"要检查什么"。
|
|
4
|
+
>
|
|
5
|
+
> **强制项(12)必须 100% 通过**;**建议项(5)至少 4 项通过**。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 强制项(12)
|
|
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
|
+
| 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] |
|
|
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` 类时务必核对。
|
|
27
|
+
>
|
|
28
|
+
> **强制项 #13([ADR 0025](../../../../../docs/adr/0025-component-props-explicit-declaration.md))**:组件 `Props` interface 必须**显式声明所有可配置 prop**,带中文 JSDoc(由 `pnpm gen:meta` 提取生成 meta.md props 表)。**禁止**空 extends 透传(如 `interface FooProps extends ComponentPropsWithoutRef<typeof Primitive.Root> {}`)— 会导致 meta props 表为空、Storybook controls 缺数据源、AI 生成代码无法读取支持的 prop。**数据录入类组件**(Checkbox/Switch/Select/Input/Slider 等)必须暴露至少一对受控套:`value` + `onChange`(或 Radix 命名 `onCheckedChange` / `onValueChange`)+ `defaultValue` / `defaultChecked`,业务侧能用受控模式跑通。
|
|
29
|
+
|
|
30
|
+
[F1]: ./boundaries.md
|
|
31
|
+
[ADR0023]: ../../../../../docs/adr/0023-cursor-pointer-explicit-in-component-source.md
|
|
32
|
+
[ADR0027]: ../../../../../docs/adr/0027-component-visual-token-alignment.md
|
|
33
|
+
[S1]: ./boundaries.md
|
|
34
|
+
[S2]: ./boundaries.md
|
|
35
|
+
[S5]: ./boundaries.md
|
|
36
|
+
[S6]: ./boundaries.md
|
|
37
|
+
[S7]: ./boundaries.md
|
|
38
|
+
[S8]: ./boundaries.md
|
|
39
|
+
[C1-C12]: ./boundaries.md
|
|
40
|
+
[C7-C12]: ./boundaries.md
|
|
41
|
+
[I1-I2]: ./boundaries.md
|
|
42
|
+
[philosophy]: ./philosophy.md
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 建议项(5)
|
|
47
|
+
|
|
48
|
+
- 💡 11. 列表页空数据有 `<Empty>` + 主操作入口("创建第一个 X")
|
|
49
|
+
- 💡 12. 表单字段 > 6 时用 `<Card>` 分组或 Steps 分步
|
|
50
|
+
- 💡 13. 按钮文案:动宾 ≤ 5 字("创建实例");危险用明确名词 + 动作("永久删除");不写"OK / 确认" — 详见 [brand.md §文案语气](./brand.md#文案语气)
|
|
51
|
+
- 💡 14. ID / Hash / 路径用 `font-mono` + 复制按钮
|
|
52
|
+
- 💡 15. 操作 ≤ 200ms 反馈:loading / Toast / 状态变化
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 自检报告模板
|
|
57
|
+
|
|
58
|
+
```markdown
|
|
59
|
+
## 自检报告 — <页面名>
|
|
60
|
+
|
|
61
|
+
### 强制项(10/10 通过)✅
|
|
62
|
+
|
|
63
|
+
- [x] 1. 无硬编码色值
|
|
64
|
+
- [x] 2. 状态用 Badge / 语义 token
|
|
65
|
+
- [x] 3. 间距用 gap
|
|
66
|
+
- [x] 4. className 不覆盖颜色
|
|
67
|
+
- [x] 5. 复合组件结构完整
|
|
68
|
+
- [x] 6. 专用组件(Badge/Skeleton/Empty/Separator/Alert/Toast)
|
|
69
|
+
- [x] 7. 图标 data-icon
|
|
70
|
+
- [x] 8. 无 z-index / dark: 覆盖
|
|
71
|
+
- [x] 9. 条件类名用 cn()
|
|
72
|
+
- [x] 10. 危险操作二次确认
|
|
73
|
+
|
|
74
|
+
### 建议项(4/5 通过)✅
|
|
75
|
+
|
|
76
|
+
- [x] 11. 空状态
|
|
77
|
+
- [x] 12. 字段分组
|
|
78
|
+
- [x] 13. 按钮文案合规
|
|
79
|
+
- [ ] 14. 长字符串 mono — 第 N 行 ID 未应用 font-mono
|
|
80
|
+
- [x] 15. 操作反馈
|
|
81
|
+
|
|
82
|
+
### 修正建议
|
|
83
|
+
|
|
84
|
+
- 第 N 行:`<span>{order.id}</span>` → `<span className="font-mono">{order.id}</span>` + `<CopyButton />`
|
|
85
|
+
```
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# Components — 选型决策与组合规则
|
|
2
|
+
|
|
3
|
+
> ⚠️ **Prerequisites**: 你必须已完成 [generation-flow.md](./generation-flow.md) Step 1–3(已确定页面类型 + 子类型 + 区域骨架)后才能读本文件。
|
|
4
|
+
> 若未完成前置步骤,请先返回 [generation-flow.md](./generation-flow.md) 从 Step 1 开始。
|
|
5
|
+
|
|
6
|
+
> **本文档只回答"用什么组件、怎么搭配",不写具体 Props / Examples / import 路径。**
|
|
7
|
+
> 组件 API、Props、示例代码通过 MCP `get_component_meta` 实时查询;可用列表通过 `list_components` / `find_components` 查询。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 0. 组件查不到时的兜底铁律(最高优先)
|
|
12
|
+
|
|
13
|
+
> **本节规则优先级高于本文件其余所有条款,违反此节即视为违反 reuse-first 原则(见 `teamix-evo-code-opentrek/reuse-first.md`)。**
|
|
14
|
+
|
|
15
|
+
### 0.1 触发场景
|
|
16
|
+
|
|
17
|
+
调用 `list_components` / `find_components` 命中失败、或本文件提到的组件名(例如 `SearchCombo` / `ContextSwitcher` / `ItemCard` / `CardGrid` / `CardActionBar`)在 `@teamix-evo/biz-ui` 中无实物时。
|
|
18
|
+
|
|
19
|
+
### 0.2 四步处置法
|
|
20
|
+
|
|
21
|
+
1. **不要自造同名组件入 `src/components/`** — 即使本文件提到该组件名,也必须先确认实物存在。
|
|
22
|
+
2. **优先扫所有 ui 单体找语义等价**(见 §0.4) — 在 `@teamix-evo/ui` 约 89 个原子件中用 `find_components` 模糊搜 + 按七类法分类筛,找功能 / 结构等价的**单体**直接用。**这一步不可跳**。
|
|
23
|
+
3. **单体彻底无等价 → 才用 ui 多原子最小拼装**(参见本文件 §3 决策树和 §5 拼凑配方)。
|
|
24
|
+
4. **在响应中显式声明替代关系**,例如:
|
|
25
|
+
|
|
26
|
+
> `// SearchCombo 暂未实物化 → ui filter-bar 单体语义等价 → 直接采用` > `// 或:// SearchCombo 暂未实物化 → 89 件单体扫尽无等价 → Input + Select + Button 最小拼装`
|
|
27
|
+
|
|
28
|
+
### 0.3 兜底优先序
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
biz-ui 实物组件(优先)
|
|
32
|
+
↓ 未命中
|
|
33
|
+
ui 原子 — 精确名匹配(dialog→Dialog / button→Button…)
|
|
34
|
+
↓ 未命中
|
|
35
|
+
ui 原子 — 语义近似单体替代(扫所有 89 件,见 §0.4) ← 关键档:穷尽前不允许进下一档
|
|
36
|
+
↓ 仍未命中
|
|
37
|
+
ui 多原子最小拼装(万不得已,注释声明)
|
|
38
|
+
↓ 仍无法表达
|
|
39
|
+
跳转 patterns/*.md 找页面级模板
|
|
40
|
+
↓ 仍无法表达
|
|
41
|
+
回报用户:缺组件 + 已尝试单体扫描记录 + 拼装方案
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**永远不要**:
|
|
45
|
+
|
|
46
|
+
- 在 `src/components/` 下新增与 biz-ui 同名的"私有版本"
|
|
47
|
+
- 用 antd / arco / chakra 等其它库填补缺口
|
|
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 件单体**
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 1. 双层组件架构(实物归属)
|
|
90
|
+
|
|
91
|
+
| 层级 | 来源 | 实物清单(截至当前 variant) |
|
|
92
|
+
| ------------------------------------------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
93
|
+
| **业务扩展层(biz-ui,opentrek variant)** | `@teamix-evo/biz-ui/opentrek` | 仅 2 个实物:`list-card`、`op-sidebar`。其余 `business/` 目录为文档草稿,**不可 import**。 |
|
|
94
|
+
| **ui 实现层(shadcn 原子)** | `@teamix-evo/ui` | ≈ 89 个原子/复合组件。包含 **PageHeader / Pagination / Steps / Tabs / Tooltip / DataTable / FilterBar / Combobox(=command) / AutoComplete / DatePicker / Drawer / Sheet / Dialog / AlertDialog / Card / Badge / Tag / Alert / Toast(sonner) / Form** 等高频件。 |
|
|
95
|
+
|
|
96
|
+
### 1.1 选型铁律
|
|
97
|
+
|
|
98
|
+
1. **优先 biz-ui 实物层** — 已封装变体 + 文案规范,但**注意 opentrek 当前仅 2 个实物**。
|
|
99
|
+
2. **biz-ui 无实物 → ui 单体精确名匹配** — 按组件名 / 显式语义直查 `find_components`。
|
|
100
|
+
3. **精确名未命中 → ui 单体语义近似扫描**(见 §0.4) — 在 89 件里找等价单体直接用,**这一步不可跳**。
|
|
101
|
+
4. **单体彻底无等价 → §5 多原子最小拼装** — 仅作为单体穷尽后的兜底。
|
|
102
|
+
5. **禁止**自造同名组件(违反 reuse-first,详见 §0)。
|
|
103
|
+
|
|
104
|
+
### 1.2 实时校验
|
|
105
|
+
|
|
106
|
+
任何组件名引用前必须用 `find_components(name)` 验证存在性,**不要相信本文档中"组件名"的存在性默认**(biz-ui 处于持续物化中,本文档可能滞后)。
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 2. 必备组件 — 每个页面都需要
|
|
111
|
+
|
|
112
|
+
| 组件 | 实际归属 | 何时使用 | 备注 |
|
|
113
|
+
| -------------- | -------- | ---------------- | ---------------------------------------------------------- |
|
|
114
|
+
| **PageHeader** | ui | 所有页面必需 | L1 用 title 模式、L2 用 breadcrumb 模式(二选一,不并存) |
|
|
115
|
+
| **op-sidebar** | biz-ui | TWO_COL 布局必需 | 含顶部 Logo + 产品名;768px 以下自动折叠为抽屉 |
|
|
116
|
+
| **Button** | ui | 所有交互页面 | 主操作 ≤ 1 个(Primary);次要 Secondary;危险 Destructive |
|
|
117
|
+
|
|
118
|
+
> `op-sidebar` 是 opentrek variant 唯一的导航实物组件。如需顶部栏 / 横向布局 → 用 ui `navigation-menu` + `app` 组合。
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 3. 选型决策树
|
|
123
|
+
|
|
124
|
+
### 3.1 反馈与确认 — Dialog vs Sheet vs Drawer vs Popover
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
需要用户做出决定 / 阻塞主流程?
|
|
128
|
+
├─ 是 → 用 Dialog
|
|
129
|
+
│ ├─ 简单确认(删除/退出)→ AlertDialog
|
|
130
|
+
│ └─ 复杂表单(< 8 字段)→ Dialog
|
|
131
|
+
└─ 否
|
|
132
|
+
├─ 临时编辑/筛选(侧边滑出)→ Sheet
|
|
133
|
+
├─ 多级下探查看(侧边可叠层)→ Drawer
|
|
134
|
+
├─ 内容预览/上下文操作(小气泡)→ Popover
|
|
135
|
+
└─ 仅展示信息(鼠标悬浮)→ Tooltip
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**容量决策**:
|
|
139
|
+
|
|
140
|
+
- 字段 ≥ 8 个 / 内容超过 1 屏 → **跳转 FormPage**(不要塞进 Dialog)
|
|
141
|
+
- 字段 4~8 个 → Sheet(侧边可保留上下文)
|
|
142
|
+
- 字段 ≤ 4 个 → Dialog
|
|
143
|
+
- **任务层级 ≤ 3 层**(Teamix-UI 容器规范)— 超过则强制跳页
|
|
144
|
+
|
|
145
|
+
### 3.2 容器选型 — 操作型 vs 展示型
|
|
146
|
+
|
|
147
|
+
> 来源:Teamix-UI 容器规范。
|
|
148
|
+
|
|
149
|
+
| 类别 | 容器 | 何时使用 |
|
|
150
|
+
| ---------- | ----------------------------------------------- | ------------------------------------------------ |
|
|
151
|
+
| **操作型** | 全页面(FormPage) | 字段多 / 步骤多 / 需要持久 URL |
|
|
152
|
+
| **操作型** | 弹窗模态(Dialog) | 阻塞主流程的简短确认或表单;最多 2 级,不再深入 |
|
|
153
|
+
| **操作型** | 气泡(Popconfirm) | 二次确认(删除/解绑),轻量提示 |
|
|
154
|
+
| **展示型** | 全页面(DetailPage) | 完整信息查看,路由可分享 |
|
|
155
|
+
| **展示型** | 抽屉非模态(Sheet) | 不阻塞主流程,可保留上下文(如侧栏 Detail) |
|
|
156
|
+
| **展示型** | 抽屉模态(Drawer) | 多级下探查看(如资源 → 子资源 → 配置),逐层推出 |
|
|
157
|
+
| **展示型** | 弹窗模态(Dialog) | 一次性展示重要信息 |
|
|
158
|
+
| **展示型** | 卡片(Card) | 同级信息分组;卡片之间间距 16px |
|
|
159
|
+
| **展示型** | 通知反馈(Toast/Sonner / Alert / Notification) | 瞬时反馈 / 页面级横幅 / 系统通知 |
|
|
160
|
+
|
|
161
|
+
### 3.3 状态展示 — Badge vs Tag vs Alert
|
|
162
|
+
|
|
163
|
+
| 组件 | 用途 | 容器 |
|
|
164
|
+
| ------------------ | -------------------------------- | ------------------- |
|
|
165
|
+
| **Badge** | 状态标记(启用/停用、成功/失败) | 表格列、详情字段 |
|
|
166
|
+
| **Tag** | 业务分类(标签、关键字) | 多个并列时使用 |
|
|
167
|
+
| **Alert** | 页面级提示(操作结果、系统通知) | 页面顶部、Form 顶部 |
|
|
168
|
+
| **Toast / Sonner** | 瞬时反馈(保存成功) | 全局浮层 |
|
|
169
|
+
|
|
170
|
+
**铁律**:状态颜色用 `bg-{success|warning|destructive|info}/10` 而非 `bg-red-500`(参见 `boundaries.md` S8)。
|
|
171
|
+
|
|
172
|
+
### 3.4 数据展示 — Table vs DataTable vs Card vs List
|
|
173
|
+
|
|
174
|
+
```text
|
|
175
|
+
数据量 ≤ 50 / 列数 ≤ 6 → Table
|
|
176
|
+
数据量 > 50 / 列数 > 6 → DataTable(含虚拟滚动 + 排序 + 列控制)
|
|
177
|
+
卡片化展示(含图片/丰富信息)→ list-card(biz-ui 实物)或 Card[] + Grid 拼装
|
|
178
|
+
简单单列列表 → 普通 div + map(不必造组件)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**列上限**:建议表格 ≤ 6 列,超过用 DataTable 的列控制(参见 `patterns/list-page.md`)。
|
|
182
|
+
|
|
183
|
+
### 3.5 导航 — Tabs vs Sidebar vs Breadcrumb vs Steps
|
|
184
|
+
|
|
185
|
+
| 场景 | 组件 | 归属 |
|
|
186
|
+
| ------------------- | ------------------------------------ | ------ |
|
|
187
|
+
| 详情页内子模块切换 | **Tabs** | ui |
|
|
188
|
+
| 同级页面切换 | **op-sidebar** | biz-ui |
|
|
189
|
+
| 父子页面层级 | **Breadcrumb**(由 PageHeader 内置) | ui |
|
|
190
|
+
| 多步流程 | **Steps** | ui |
|
|
191
|
+
| 步骤数 ≤ 3 且无依赖 | 不用 Steps,用单页 Form | — |
|
|
192
|
+
|
|
193
|
+
### 3.6 输入控件 — Input vs Select vs Combobox
|
|
194
|
+
|
|
195
|
+
```text
|
|
196
|
+
枚举值 ≤ 7 → RadioGroup(一屏可见)
|
|
197
|
+
枚举值 8~30 → Select
|
|
198
|
+
枚举值 > 30 / 需搜索 → Combobox(= ui command)
|
|
199
|
+
多选 → MultiSelect / Checkbox
|
|
200
|
+
数值(整数/小数/金额)→ InputNumber(带 min/max/step/precision)
|
|
201
|
+
数值范围可视化 → Slider(仅用于资源配比/阈值的拖拽式选择)
|
|
202
|
+
日期 → DatePicker / DateRangePicker
|
|
203
|
+
富文本 → Textarea / RichEditor
|
|
204
|
+
文件 → Upload
|
|
205
|
+
自动补全 → AutoComplete
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 4. 复合组件结构铁律
|
|
211
|
+
|
|
212
|
+
> **完整规则在 `boundaries.md` C1-C12,此处仅列高频项**
|
|
213
|
+
|
|
214
|
+
| 组件 | 必备子结构 | 缺失后果 |
|
|
215
|
+
| ---------- | ------------------------------------------------------------------- | ------------------ |
|
|
216
|
+
| **Dialog** | `DialogHeader > DialogTitle` 必须存在 | 屏幕阅读器无法识别 |
|
|
217
|
+
| **Sheet** | `SheetHeader > SheetTitle` 必须存在 | 同上 |
|
|
218
|
+
| **Form** | `FormField > FormItem > FormLabel + FormControl + FormMessage` 全套 | 无错误提示渲染 |
|
|
219
|
+
| **Tabs** | `TabsTrigger` 必须在 `TabsList` 内 | 渲染异常 |
|
|
220
|
+
| **Select** | `SelectTrigger > SelectValue` + `SelectContent > SelectItem` | 无法触发 |
|
|
221
|
+
| **Card** | `CardHeader > CardTitle` + `CardContent` | 字号 / 间距错乱 |
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## 5. 业务扩展层(候补)— 实物 vs 概念 + 拼凑配方
|
|
226
|
+
|
|
227
|
+
> opentrek variant 当前**只有 2 个**实物业务组件:`list-card`、`op-sidebar`。
|
|
228
|
+
> 以下表格区分"已实物化"与"概念占位(用 ui 拼装)"。
|
|
229
|
+
|
|
230
|
+
### 5.1 已实物化(直接使用)
|
|
231
|
+
|
|
232
|
+
| 组件 | 用途 | 归属 |
|
|
233
|
+
| -------------- | --------------------------------- | --------------- |
|
|
234
|
+
| **list-card** | 列表页卡片化展示(替代 ItemCard) | biz-ui/opentrek |
|
|
235
|
+
| **op-sidebar** | 主导航侧栏 | biz-ui/opentrek |
|
|
236
|
+
|
|
237
|
+
### 5.2 概念占位(按配方拼装)
|
|
238
|
+
|
|
239
|
+
> 这些是 design 语义概念,**不是**可 import 的组件。出现下表名称时按"拼装配方"使用 ui 原子件。
|
|
240
|
+
|
|
241
|
+
| 概念 | 拼装配方(ui 原子件) | 触发场景 |
|
|
242
|
+
| ------------------- | --------------------------------------------------------------------------------- | ---------------------------- |
|
|
243
|
+
| **SearchCombo** | `Input + Select + Button` 或直接用 `filter-bar` | 列表页头部筛选 + 搜索 |
|
|
244
|
+
| **ContextSwitcher** | `dropdown-menu + avatar`(顶部)或 `command + popover`(带搜索) | 多租户 / 多环境 / 多项目切换 |
|
|
245
|
+
| **ItemCard** | `card`(CardHeader + CardContent + CardFooter);首选 biz-ui `list-card` 已实物化 | 卡片化数据项 |
|
|
246
|
+
| **CardGrid** | `grid` + `card[]`(Tailwind grid-cols-N + gap-4) | 卡片网格列表 |
|
|
247
|
+
| **CardActionBar** | `card` 的 Footer 内放 `button[]`(主 + 次 + 危险) | 卡片底部操作区 |
|
|
248
|
+
|
|
249
|
+
**使用要求**:
|
|
250
|
+
|
|
251
|
+
- 拼装时遵守 §3 决策树和 `boundaries.md` 复合结构铁律(C1-C12)。
|
|
252
|
+
- 拼装代码中必须加注释 `// {Concept} 暂未实物化 → ui 原子件拼装`。
|
|
253
|
+
- 严禁在 `src/components/` 下新建同名文件"沉淀"该拼装,否则违反 §0 兜底铁律。
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 6. 图标 (Icons)
|
|
258
|
+
|
|
259
|
+
> **完整规则见 [`boundaries.md` I1-I4](./boundaries.md#i1-i4--图标规则)** — I1 data-icon 定位、I2 不设尺寸类、I3 作为组件对象传递、I4 按 iconLibrary 导入。
|
|
260
|
+
|
|
261
|
+
仅补充组件选型相关:**状态图标**统一选用 lucide-react 的 Check / X / AlertTriangle / Info(成功 / 失败 / 警告 / 信息)。
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 7. 与 MCP 工具的协作
|
|
266
|
+
|
|
267
|
+
```text
|
|
268
|
+
当 AI 决定使用某组件后:
|
|
269
|
+
├── 通过 list_components({ status: "stable" }) 确认组件可用
|
|
270
|
+
├── 通过 get_component_meta("dialog") 获取:
|
|
271
|
+
│ - Props 完整签名(required / optional / default)
|
|
272
|
+
│ - 子组件层级(DialogHeader/Footer/Title/...)
|
|
273
|
+
│ - 标准用法 Example
|
|
274
|
+
│ - 常见错误(compositionPitfalls)
|
|
275
|
+
├── 通过 find_components("filter") 模糊搜索(不确定名称时)
|
|
276
|
+
└── 通过 tokens_get() 获取最新 token 别名(颜色/间距/圆角)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**约束**:在 skill 中**不写**具体 import 路径与 Props 示例 —— 这些由 MCP runtime 提供,避免 skill 与组件库版本错位。
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## 8. 选型自检
|
|
284
|
+
|
|
285
|
+
通用结构性规则 → 见 [checklist.md](./checklist.md)(C1-C12 / I1-I4)。本文件特有的"选型决策"自检:
|
|
286
|
+
|
|
287
|
+
- [ ] 已先用 `find_components` 验证组件存在性(不靠默认)
|
|
288
|
+
- [ ] biz-ui 命中失败 → **先按 §0.4 扫所有 ui 单体找语义近似替代**,单体覆盖时直接采用,未直接跳到 §5 拼装
|
|
289
|
+
- [ ] 单体彻底无等价时 → §5 拼装代码必加注释 `// 已扫尽 89 件 ui 单体无语义等价 → 拼装`
|
|
290
|
+
- [ ] 反馈 / 确认场景按容量选 Dialog / Sheet / Drawer / Popover
|
|
291
|
+
- [ ] 容器层级 ≤ 3,弹窗最多 2 级,超过则跳转全页面
|
|
292
|
+
- [ ] 卡片列表优先 biz-ui `list-card`,否则用 `card[] + grid` 拼
|
|
293
|
+
- [ ] 表格 ≤ 6 列,超过改 DataTable + 列控制
|
|
294
|
+
- [ ] 不存在的组件**绝不**自造,**绝不**写"假设有 X"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Flows — 用户旅程
|
|
2
|
+
|
|
3
|
+
> **页间流转视图见 [`patterns/page-types.md §6 页间流转`](./patterns/page-types.md#6-页间流转)** — 包含后台主流转图、流转设计规则、资源生命周期、CRUD 流转速查。本文档只承载"四条核心用户旅程"的编织视角。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 四条核心旅程速查 + 设计要点
|
|
8
|
+
|
|
9
|
+
### A · 资源查找与操作
|
|
10
|
+
|
|
11
|
+
`Sidebar → ListPage(SearchCombo) → 行内操作 → 反馈(Toast / AlertDialog → Toast) → 状态自动刷新`
|
|
12
|
+
|
|
13
|
+
- 搜索框必须保留焦点
|
|
14
|
+
- 危险操作的 AlertDialog 必须列出**资源标识**与**影响范围**
|
|
15
|
+
|
|
16
|
+
### B · 资源创建
|
|
17
|
+
|
|
18
|
+
`ListPage → FormPage(分组 + 实时校验) → 提交 → 列表(顶部)`
|
|
19
|
+
|
|
20
|
+
- blur 校验单字段,submit 校验全部
|
|
21
|
+
- 失败**不清空表单**,错误定位到字段
|
|
22
|
+
- 长表单(> 10 字段)必须有"保存草稿"
|
|
23
|
+
- 创建成功落点优先返回列表,编辑成功优先停留原页
|
|
24
|
+
|
|
25
|
+
### C · 异常处理
|
|
26
|
+
|
|
27
|
+
`Dashboard(StatCard) → ListPage(?status=error) → DetailPage(明细+日志) → AlertDialog 修复 → Toast`
|
|
28
|
+
|
|
29
|
+
- 异常数字必须是**可点击的钻取入口**
|
|
30
|
+
- LogViewer 默认定位到异常时间点 ± 5 分钟
|
|
31
|
+
- 修复操作必须显示**预期影响范围**
|
|
32
|
+
|
|
33
|
+
### D · 批量操作
|
|
34
|
+
|
|
35
|
+
`Checkbox 选 → BulkActionBar → AlertDialog(列出受影响资源) → 进度 → Toast(成功 N / 失败 M)`
|
|
36
|
+
|
|
37
|
+
- BulkActionBar 浮动在表格底部
|
|
38
|
+
- AlertDialog 必须列出至少前 5 条受影响资源
|
|
39
|
+
- 部分失败时,失败项显示"重试"按钮
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 2. 流转自检
|
|
44
|
+
|
|
45
|
+
- [ ] 任意页面都能通过面包屑 / Esc 返回上一级
|
|
46
|
+
- [ ] ListPage 的筛选条件持久化到 URL Params(刷新 / 分享 / 返回保留)
|
|
47
|
+
- [ ] FormPage 未保存离开有 Dialog 确认
|
|
48
|
+
- [ ] 危险操作的 Dialog 列出影响范围与资源清单
|
|
49
|
+
- [ ] 成功 / 失败页面都有"下一步"按钮(无死胡同)
|
|
50
|
+
- [ ] 批量操作进度可见、部分失败可重试
|
|
51
|
+
- [ ] 异常数字是可点击的钻取入口(Dashboard → ListPage 预筛选)
|