@teamix-evo/skills 0.3.0 → 0.4.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 (66) hide show
  1. package/manifest.json +61 -45
  2. package/package.json +2 -2
  3. package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/SKILL.md +18 -18
  4. package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/checklist.md +2 -2
  5. package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/reuse-first.md +25 -17
  6. package/src/teamix-evo-code-uni-manager/SKILL.md +95 -0
  7. package/src/teamix-evo-code-uni-manager/api-layering.md +370 -0
  8. package/src/teamix-evo-code-uni-manager/checklist.md +193 -0
  9. package/src/teamix-evo-code-uni-manager/error-and-loading.md +389 -0
  10. package/src/teamix-evo-code-uni-manager/file-structure.md +339 -0
  11. package/src/teamix-evo-code-uni-manager/forms-and-validation.md +459 -0
  12. package/src/teamix-evo-code-uni-manager/reuse-first.md +188 -0
  13. package/src/teamix-evo-code-uni-manager/routing-and-codesplit.md +450 -0
  14. package/src/teamix-evo-code-uni-manager/testing.md +396 -0
  15. package/src/teamix-evo-design-opentrek/SKILL.md +71 -0
  16. package/src/teamix-evo-design-opentrek/boundaries.md +513 -0
  17. package/src/teamix-evo-design-opentrek/brand.md +154 -0
  18. package/src/teamix-evo-design-opentrek/checklist.md +83 -0
  19. package/src/teamix-evo-design-opentrek/components.md +245 -0
  20. package/src/teamix-evo-design-opentrek/flows.md +51 -0
  21. package/src/teamix-evo-design-opentrek/foundations.md +271 -0
  22. package/src/teamix-evo-design-opentrek/generation-flow.md +185 -0
  23. package/src/teamix-evo-design-opentrek/patterns/dashboard.md +31 -0
  24. package/src/teamix-evo-design-opentrek/patterns/detail-page.md +202 -0
  25. package/src/teamix-evo-design-opentrek/patterns/form-page.md +289 -0
  26. package/src/teamix-evo-design-opentrek/patterns/list-page.md +334 -0
  27. package/src/teamix-evo-design-opentrek/patterns/page-types.md +154 -0
  28. package/src/teamix-evo-design-opentrek/philosophy.md +96 -0
  29. package/src/teamix-evo-design-opentrek/rules/README.md +39 -0
  30. package/src/teamix-evo-design-opentrek/rules/boundaries.rules.json +391 -0
  31. package/src/teamix-evo-design-uni-manager/SKILL.md +73 -0
  32. package/src/teamix-evo-design-uni-manager/boundaries.md +564 -0
  33. package/src/teamix-evo-design-uni-manager/brand.md +202 -0
  34. package/src/teamix-evo-design-uni-manager/checklist.md +115 -0
  35. package/src/teamix-evo-design-uni-manager/components.md +254 -0
  36. package/src/teamix-evo-design-uni-manager/flows.md +63 -0
  37. package/src/teamix-evo-design-uni-manager/foundations.md +258 -0
  38. package/src/teamix-evo-design-uni-manager/generation-flow.md +194 -0
  39. package/src/teamix-evo-design-uni-manager/patterns/dashboard.md +95 -0
  40. package/src/teamix-evo-design-uni-manager/patterns/detail-page.md +224 -0
  41. package/src/teamix-evo-design-uni-manager/patterns/form-page.md +329 -0
  42. package/src/teamix-evo-design-uni-manager/patterns/list-page.md +356 -0
  43. package/src/teamix-evo-design-uni-manager/patterns/page-types.md +165 -0
  44. package/src/teamix-evo-design-uni-manager/philosophy.md +106 -0
  45. package/src/teamix-evo-design-uni-manager/rules/README.md +49 -0
  46. package/src/teamix-evo-design-uni-manager/rules/boundaries.rules.json +418 -0
  47. package/src/teamix-evo-manage/SKILL.md +281 -0
  48. package/skills/teamix-evo-design-rules/SKILL.md +0 -86
  49. package/skills/teamix-evo-design-rules/boundaries.md +0 -89
  50. package/skills/teamix-evo-design-rules/checklist.md +0 -108
  51. package/skills/teamix-evo-design-rules/generation-flow.md +0 -142
  52. package/skills/teamix-evo-design-rules/prompts/page-design.md +0 -148
  53. package/skills/teamix-evo-design-rules-opentrek/SKILL.md +0 -48
  54. package/skills/teamix-evo-design-rules-opentrek/brand-rules.md +0 -74
  55. package/skills/teamix-evo-design-rules-uni-manager/SKILL.md +0 -51
  56. package/skills/teamix-evo-design-rules-uni-manager/ai-scenarios.md +0 -51
  57. package/skills/teamix-evo-design-rules-uni-manager/command-center.md +0 -108
  58. package/skills/teamix-evo-design-rules-uni-manager/danger-ops.md +0 -87
  59. package/skills/teamix-evo-manage/SKILL.md +0 -178
  60. package/skills/teamix-evo-ui-upgrade/SKILL.md +0 -75
  61. /package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/api-layering.md +0 -0
  62. /package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/error-and-loading.md +0 -0
  63. /package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/file-structure.md +0 -0
  64. /package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/forms-and-validation.md +0 -0
  65. /package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/routing-and-codesplit.md +0 -0
  66. /package/{skills/teamix-evo-coding-conventions → src/teamix-evo-code-opentrek}/testing.md +0 -0
@@ -0,0 +1,289 @@
1
+ # Form Page — 表单页模式
2
+
3
+ > **触发**:用户描述含"新建/创建/编辑/修改/复制/填写"。
4
+ > **核心特征**:用户输入数据 + 字段校验 + 提交。
5
+ > **页面级别**:L2(面包屑模式 PageHeader,自动继承 Sidebar)。弹窗表单 = L0。
6
+
7
+ ---
8
+
9
+ ## 1. 子类型识别
10
+
11
+ | 子类型 | 关键词 | 差异特征 |
12
+ | ------------ | -------------------- | ---------------------------------------------------------- |
13
+ | **新建表单** | "新建"/"创建"/"新增" | 字段为空,标题"新建 XX",保存返回列表 |
14
+ | **编辑表单** | "编辑"/"修改" | 字段填充数据,标题"编辑 XX",保存返回原页 |
15
+ | **复制新建** | "复制"/"克隆" | 字段预填源数据(ID 除外),标题"复制新建 XX",保存返回列表 |
16
+
17
+ ### FormPage vs Wizard 区分
18
+
19
+ | 场景 | 类型 | 判断依据 |
20
+ | -------------------------- | ---------- | ------------------------ |
21
+ | 字段无顺序依赖,一次填写 | FormPage | 单页表单 |
22
+ | 步骤间有顺序依赖,逐步完成 | WizardPage | 多步流程,Steps |
23
+
24
+ > Wizard 是独立页面类型,不是 FormPage 子类型。
25
+
26
+ ---
27
+
28
+ ## 2. 布局模式(三选一)
29
+
30
+ ### 2.1 SINGLE_COL(默认)
31
+
32
+ ```text
33
+ ┌────────────────────────────────────────┐
34
+ │ PageHeader: 新建实例 │
35
+ │ │
36
+ │ FieldGroup │
37
+ │ Field [实例名称 *] │
38
+ │ Field [地域 ▼] │
39
+ │ Field [可用区 ▼] │
40
+ │ Field [实例规格 * ▼] │
41
+ │ │
42
+ │ ───────────────────────── │
43
+ │ SubmitBar [取消] [确定] │ ← justify-end
44
+ └────────────────────────────────────────┘
45
+ ```
46
+
47
+ ### 2.2 TWO_COL(多字段并排)
48
+
49
+ ```text
50
+ FieldGroup
51
+ ┌─ 列 1 ──────┐ ┌─ 列 2 ──────┐
52
+ │ 用户名 * │ │ 邮箱 * │
53
+ │ 角色 * │ │ 状态 │
54
+ │ 部门 │ │ 手机号 │
55
+ └─────────────┘ └─────────────┘
56
+ SubmitBar [取消] [保存]
57
+ ```
58
+
59
+ ### 2.3 SECTION(分区表单)
60
+
61
+ ```text
62
+ Card[FieldGroup ─ 基本信息]
63
+ 实例名称 *
64
+ 类型 * [自研 ○ MySQL ○ PostgreSQL]
65
+
66
+ Card[FieldGroup ─ 网络配置]
67
+ 地域 * / VPC * / 交换机 *
68
+
69
+ Card[FieldGroup ─ 存储配置]
70
+ 存储空间 * / 备份策略
71
+
72
+ SubmitBar [取消] [创建]
73
+ ```
74
+
75
+ **何时分区**:字段 > 10 / 业务概念分组明显 / 含可选高级配置。
76
+
77
+ ---
78
+
79
+ ## 3. 必需组件
80
+
81
+ | 组件 | 位置 | 说明 |
82
+ | --------------------- | ------ | ------------------------------------- |
83
+ | **PageHeader** | top | 面包屑模式(L2 页面) |
84
+ | **Form / FieldGroup** | center | 表单容器,**禁止**用 div + space-y-\* |
85
+ | **SubmitBar** | bottom | 提交操作栏,居右排列 |
86
+
87
+ **框架级**(自动继承):Sidebar、Breadcrumb。
88
+
89
+ ---
90
+
91
+ ## 4. SubmitBar / Footer 规则
92
+
93
+ ### 4.1 智能定位
94
+
95
+ - Footer **从滚动区域移出**,作为 Card 的直接子元素
96
+ - Card:`flex flex-col max-h-[calc(100vh-48px)]`
97
+ - 内容区:`flex-1 overflow-y-auto min-h-0`
98
+ - Footer:`flex-shrink-0 z-10 bg-card border-t`
99
+
100
+ ### 4.2 行为
101
+
102
+ | 场景 | Card 高度 | Footer |
103
+ | ----------- | ------------------------ | ------------------------ |
104
+ | 内容 < 视口 | 自适应 | 跟随内容自然展示 |
105
+ | 内容 > 视口 | max-h:calc(100vh - 48px) | 固定底部,悬浮于表单上方 |
106
+
107
+ ### 4.3 按钮顺序(从左到右)
108
+
109
+ - `[取消]` → `[上一步]`(Wizard 中)→ `[下一步 / 提交 / 保存]`
110
+ - 主按钮始终在最右侧(Primary)
111
+ - 容器 `justify-end`
112
+
113
+ ---
114
+
115
+ ## 5. 字段控件选型
116
+
117
+ > **枚举数量阈值规则(≤7 RadioGroup / 8-30 Select / >30 Combobox)见 [components.md §3.5 输入控件](../components.md#35-输入控件--input-vs-select-vs-combobox)**。本节只列表单页专属补充字段。
118
+
119
+ | 字段类型 | 组件 | 说明 |
120
+ | ------------- | ---------------------------- | ------------------------ |
121
+ | 布尔(设置) | Switch | "启用 X" 类开关 |
122
+ | 布尔(表单) | Checkbox | 协议确认 |
123
+ | 单选(2~5 项) | ToggleGroup | 类型选择(可视化优于下拉) |
124
+ | 验证码 | InputOTP | 短信 / 邮箱 OTP |
125
+ | 范围数值 | Slider | 资源配比 / 阈值 |
126
+ | 输入 + 按钮 | InputGroup | 复制、单位切换 |
127
+ | 文件上传 | FileUpload | 单 / 多文件 |
128
+ | 日期 / 时间 | DatePicker / DateRangePicker | — |
129
+
130
+ ---
131
+
132
+ ## 6. 字段校验规则
133
+
134
+ ### 6.1 触发时机
135
+
136
+ | 场景 | 触发 |
137
+ | ---------- | ---------------- |
138
+ | 单字段格式 | blur(失焦) |
139
+ | 必填检查 | submit(提交时) |
140
+ | 跨字段联动 | change(实时) |
141
+ | 后端校验 | submit 提交后 |
142
+
143
+ ### 6.2 视觉反馈
144
+
145
+ - 错误:`data-invalid` 在 Field 上、`aria-invalid` 在控件上 → 红色边框 + FormMessage 错误描述
146
+ - 必填:label 后置 `*` 红色标记
147
+ - 字段说明优先 Tooltip(避免行内增加阅读负担)
148
+ - 提交失败:聚焦第一个错误字段
149
+
150
+ ### 6.3 长表单分组
151
+
152
+ - 单组字段 ≤ 6
153
+ - > 10 字段必须分区或分步
154
+ - 分区用 Card 内嵌 FieldGroup
155
+
156
+ ---
157
+
158
+ ## 7. 提交交互
159
+
160
+ ### 7.1 操作流
161
+
162
+ | 操作 | 触发 | 前置 | 反馈 |
163
+ | ---------------- | ------------ | ------------ | -------------------------------- |
164
+ | 保存 | 点[确定] | 本地校验通过 | 校验 → 提交 → Toast「保存成功」 |
165
+ | 保存失败 | 后端返回错误 | — | 字段标红 + Toast 错误 + 留在表单 |
166
+ | 取消(无未保存) | 点[取消] | — | 直接离开 |
167
+ | 取消(有未保存) | 点[取消] | — | Dialog 确认离开 |
168
+ | 返回(面包屑) | 点击父级 | 有未保存内容 | Dialog 确认 |
169
+
170
+ ### 7.2 异步提交
171
+
172
+ | 类型 | UI | 反馈 |
173
+ | ------------ | ----------------------- | ----------------------------------- |
174
+ | 同步(快速) | 按钮 disabled + Spinner | Toast 结果 |
175
+ | 异步(耗时) | 不阻塞 | Toast「提交成功,后台处理中」+ 轮询 |
176
+
177
+ ### 7.3 操作确认分级
178
+
179
+ | 级别 | 适用 |
180
+ | ---------------- | ---------------- |
181
+ | 一级(可逆) | 保存(校验通过) |
182
+ | 二级(有未保存) | 取消/离开 |
183
+
184
+ ---
185
+
186
+ ## 8. shadcn 表单组合契约
187
+
188
+ > 表单**组合层面**的本地约定。视觉/全局规则参见 [boundaries.md FF1-FF4](../boundaries.md#ff1-ff4--表单专属硬约束)(色块、必填、Card 嵌套、错误文案) + [boundaries.md S2](../boundaries.md#error-s2--不用-space-x---space-y--改用-flex--gap-) (gap 替代 space-y) + [boundaries.md F8](../boundaries.md#error-f8--禁止在-dialogtitle-中加图标--scope-dialog) (DialogTitle 无图标) + [boundaries.md F9](../boundaries.md#error-f9--弹窗确定按钮禁止加-disabled-禁用态--scope-dialog) (提交按钮无 disabled)。
189
+
190
+ - **FC1 表单布局**:`FieldGroup` + `Field`,**禁止** `<div>` + `space-y-*`(并见 S2)
191
+ - **FC2 InputGroup 内子件**:`InputGroupInput` / `InputGroupTextarea`,不用原始 `Input`
192
+ - **FC3 输入 + 按钮**:`InputGroup` + `InputGroupAddon`
193
+ - **FC4 2~5 选项**:`ToggleGroup`,**禁止**循环 `Button` 手动 active
194
+ - **FC5 相关选项组**:`FieldSet` + `FieldLegend`
195
+ - **FC6 校验态**:`data-invalid` 在 `Field`、`aria-invalid` 在控件 (与 FF1 配合)
196
+ - **反馈**:`import { toast } from "sonner"` (并见 [boundaries.md C9](../boundaries.md#warn-c9--toast-用-sonner))
197
+
198
+ ---
199
+
200
+ ## 9. 嵌套约束
201
+
202
+ | 父子关系 | 状态 |
203
+ | --------------------------------------------------------------------------------- | --------------------------- |
204
+ | PageContainer → ContentWrapper → Card(白卡) → PageHeader / FieldGroup / SubmitBar | ALLOW |
205
+ | ContentWrapper → 业务组件(无 Card) | **FORBID** |
206
+ | Card → Card | **FORBID**(白卡单例) |
207
+ | Card(白卡) → Card(分区) | ALLOW(分区表单内嵌) |
208
+ | Card(分区) → FieldGroup | ALLOW |
209
+ | FieldGroup → Field | ALLOW |
210
+ | Field → Input / Select / Switch / ToggleGroup / Textarea | ALLOW |
211
+ | Field → InputGroup | ALLOW |
212
+ | Card → Form | **FORBID**(用 FieldGroup) |
213
+
214
+ ---
215
+
216
+ ## 10. 禁止项
217
+
218
+ | 禁项 | 原因 |
219
+ | --------------------------- | ----------------------------- |
220
+ | DataTable 在主内容区 | 关联数据用 Dialog + DataTable |
221
+ | Chart 在表单页 | 图表属 Dashboard |
222
+ | 内联 Input(不在 Field 内) | 必须 FieldGroup → Field 包装 |
223
+ | 原始 div 表单布局 | 用 FieldGroup + Field |
224
+ | 单页字段 > 15 不分组 | 分区或拆 Wizard |
225
+
226
+ ---
227
+
228
+ ## 11. 表单页特有自检
229
+
230
+ - [ ] PageHeader 用面包屑模式(L2 页面)
231
+ - [ ] 所有 Input 在 Field → FieldGroup 内(FC1)
232
+ - [ ] data-invalid + aria-invalid 双重声明(FC6)
233
+ - [ ] 控件按字段类型选型正确(2~5 选用 ToggleGroup,不循环 Button)
234
+ - [ ] SubmitBar 居右 + 按钮顺序:取消 → 上一步 → 主操作
235
+ - [ ] 长表单(> 10)分组或分区
236
+ - [ ] 异步提交:按钮 loading + Spinner
237
+ - [ ] 取消时未保存内容 Dialog 确认
238
+ - [ ] 编辑模式加载用 Skeleton
239
+ - [ ] Toast 用 sonner(C9),不用自定义全局通知
240
+
241
+ ---
242
+
243
+ ## 12. 《Teamix UI 表单设计规范》对齐 Checklist
244
+
245
+ > 详细说明见 [`packages/ui/AGENTS.md` 第六节](../../../../ui/AGENTS.md#六表单族硬规则formfieldfilter-barlabelinput)。本节只列 AI 写表单时的 yes/no 自检项。
246
+
247
+ ### 12.1 间距(11 条硬规则,§3.1)
248
+
249
+ - [ ] label → input 间距:垂直 4px / 水平 16px(由 `Field.orientation` 内置,**禁止**手写 `mt-*` / `gap-3` 覆盖)
250
+ - [ ] error → input:**0px**(`FieldError` 内置 `-mt-1`,防止抖动)
251
+ - [ ] description → input:4px(`FieldDescription` 默认)
252
+ - [ ] 组内行距 20px / 组间距 32px / 详情页 12px(`FieldGroup` / `FieldSection` / `density="detail"`)
253
+ - [ ] checkbox / radio / 文字链 横向:**16px**(`gap-4`,组件内置)
254
+ - [ ] icon 与文字 横向:**4px**(label 内 `文字 ⓘ *`,Label 组件内置)
255
+
256
+ ### 12.2 必填与 a11y(§一 + §六)
257
+
258
+ - [ ] `*` 后置:`<FormLabel required>` / `<FieldLabel required>`,**禁止**手写 `<span>* 邮箱</span>`
259
+ - [ ] input 同步 `aria-required="true"`,纯视觉 `*` 不替代屏幕阅读
260
+ - [ ] invalid 单一真值在 `<Field invalid>`,自动驱动 label 着色 + FieldError 可见 + 控件 ring,**不要**重复给控件传 `aria-invalid`
261
+
262
+ ### 12.3 输入域宽度(5 档,§七)
263
+
264
+ - [ ] 用 `Field.inputWidth="xs|s|m|l|xl"`(104/216/328/440/552px),**禁止**手写 `w-[328px]` 或 `style={{ width: 328 }}`
265
+ - [ ] 子控件用 `style={{ width: 'var(--field-input-width)' }}` 消费
266
+ - [ ] horizontal 模式 label 自动 `max-width = ⅓ 输入域宽`,超长 truncate(`FieldLabel` 内置)
267
+
268
+ ### 12.4 响应式(5 档断点,§4.1-4.2)
269
+
270
+ - [ ] 多栏筛选用 `FilterBarPanel responsiveColumns={{ base, xs, s, m, l, xl }}`,**禁止**手写媒体查询 / `lg:grid-cols-*`
271
+ - [ ] 单栏表单 < 432 自动改上下:`<Field orientation={{ base: 'vertical', xs: 'horizontal' }}>`
272
+ - [ ] 断点用 `useBreakpoint` + `pickByBreakpoint`(`@/hooks/use-breakpoint`),**禁止**手写 `useMediaQuery`
273
+
274
+ ### 12.5 按钮容器感知(§六)
275
+
276
+ - [ ] 用 `FormActions container="page|page-stepper|modal|drawer"` 一次性配齐 position/align/alignWithInput
277
+ - [ ] 决策口径:页面基础/分组 → `page` / 页面分步 → `page-stepper` / 弹窗 → `modal` / 抽屉 → `drawer`
278
+ - [ ] **禁止**裸 `<div className="flex gap-2 justify-end">` 写底部按钮
279
+
280
+ ### 12.6 内容截断三件套(§八)
281
+
282
+ - [ ] 横向宽度受限的字段值 / 长 label / 表格单元格用 `<Ellipsis>`,**禁止**手写 `truncate` + 独立 `<Tooltip>`
283
+ - [ ] 多行截断走 `<Ellipsis lines={2}>`,**禁止**手写 `-webkit-line-clamp`
284
+
285
+ ### 12.7 RHF vs Server Actions 流派(§6.1)
286
+
287
+ - [ ] 用 RHF + zod → 走 `Form / FormField / FormItem / FormLabel / FormMessage`(form 包,FormItem 内部就是 Field)
288
+ - [ ] Server Actions / 原生 form / 简单状态 → 走 `Field / FieldGroup / FieldLabel / FieldError`(field 包)
289
+ - [ ] **禁止**两套混用(Section / Actions 是 re-export 别名,选哪边都行,**不要交叉**)
@@ -0,0 +1,334 @@
1
+ # List Page — 列表页模式
2
+
3
+ > **触发**:用户描述含"列表/表格/查询/检索/卡片管理"。
4
+ > **核心特征**:多条结构化数据 + 搜索/筛选 + 分页。
5
+ > **页面级别**:L1(标题模式 PageHeader,自动继承 Sidebar)。
6
+
7
+ ---
8
+
9
+ ## 1. 子类型路由
10
+
11
+ | 子类型 | 关键词 | 布局 | 核心组件 |
12
+ | ------------------- | -------------------------------- | ----------------------------- | ----------------------------------- |
13
+ | **standard** | "列表"/"表格"/"查询" | TWO_COL | DataTable + Pagination |
14
+ | **l2-sidebar** | "分类"/"分组"/"左侧树" | TWO_COL + 内部 Sidebar(240px) | Sidebar + DataTable |
15
+ | **expandable** | "展开"/"子项"/"详情行" | TWO_COL | DataTable(行内展开) |
16
+ | **drawer** | "弹窗列表"/"选择器" | Drawer 内 | DataTable ⊂ Drawer |
17
+ | **pure-card** | "纯卡片"/"卡片管理"/"智能体列表" | SINGLE_COL | CardGrid + ItemCard + CardActionBar |
18
+ | **standard-card** | "卡片列表"/"分类卡片"/"资源卡片" | TWO_COL | Sidebar + CardGrid + ItemCard |
19
+ | **view-toggle** | "视图切换"/"列表卡片切换" | TWO_COL + ViewToggle | ViewToggle + DataTable/CardGrid |
20
+ | **advanced-filter** | "高级筛选"/"更多条件" | TWO_COL | AdvancedFilterPanel + DataTable |
21
+
22
+ ### 路由优先级
23
+
24
+ 1. "纯卡片"/"卡片管理" → pure-card
25
+ 2. "卡片列表"/"分类卡片"/"资源卡片" → standard-card
26
+ 3. "视图切换"/"列表卡片" → view-toggle
27
+ 4. "高级筛选" → advanced-filter
28
+ 5. "展开"/"子项" → expandable
29
+ 6. "分类"/"分组"/"左侧树" → l2-sidebar
30
+ 7. "弹窗列表"/"选择器" → drawer
31
+ 8. 默认 → standard
32
+
33
+ ---
34
+
35
+ ## 2. 标准结构
36
+
37
+ ```
38
+ ┌────────────────────────────────────────────┐
39
+ │ PageHeader: 标题模式 [新建] │ ← Header zone
40
+ ├────────────────────────────────────────────┤
41
+ │ ActionToolbar: 🔍 搜索 [筛选▼] [刷新] │ ← Toolbar zone
42
+ ├────────────────────────────────────────────┤
43
+ │ ▢ ID │ 状态 │ 创建时间 │ 操作 │ ← Main zone
44
+ │ ▢ ORD-001234 │ 进行中│ 2026-05-13│ ⋯ │
45
+ │ ▢ ORD-001235 │ 已完成│ 2026-05-12│ ⋯ │
46
+ ├────────────────────────────────────────────┤
47
+ │ [已选 2 项] 批量审批 / 批量导出 / 批量删除 │ ← BulkActionBar (按需)
48
+ ├────────────────────────────────────────────┤
49
+ │ ← 1 / 24 → [50/页 ▼] 共 1200条 │ ← Footer zone
50
+ └────────────────────────────────────────────┘
51
+ ```
52
+
53
+ ---
54
+
55
+ ## 3. 必需组件
56
+
57
+ | 组件 | 位置 | 说明 |
58
+ | ----------------------------- | ------- | ----------------------------------------------------------- |
59
+ | **PageHeader** | top | 标题模式(L1 页面);右侧主操作(如「新建」) |
60
+ | **ActionToolbar** | toolbar | 单行 flex(nowrap);左 actions + 中 SearchCombo + 右 tools |
61
+ | **DataTable** 或 **CardGrid** | main | 二选一,按子类型 |
62
+ | **Pagination** | footer | 默认 10 条/页(标准列表) / 12 条/页(卡片) |
63
+
64
+ **框架级**(自动继承,不在 skill 内声明):Sidebar。
65
+
66
+ ---
67
+
68
+ ## 4. SearchCombo 规范
69
+
70
+ > ListPage 顶部搜索 + 筛选的标准复合组件。**禁止**用 Input + Select 散件拼装。
71
+
72
+ ### 4.1 在 ActionToolbar 中的位置(硬约束)
73
+
74
+ - SearchCombo 是 ActionToolbar 的**直接子元素**,位于 `.left-actions` 之后、`.right-tools` 之前
75
+ - 与 `.left-actions` 间距 = **20px**
76
+
77
+ ### 4.2 结构
78
+
79
+ ```
80
+ [ 维度Select | 分隔线 | 搜索Input | 搜索Button(图标) ]
81
+ ```
82
+
83
+ - 容器统一 border + radius 6px + height 32px + min-width 200px
84
+ - 内部元素无独立边框
85
+
86
+ ### 4.3 交互规则
87
+
88
+ | 触发 | 行为 |
89
+ | ------------------------- | -------------------------------- |
90
+ | 切换维度 | input.value 清空 → input.focus() |
91
+ | 输入框回车 / 点击搜索按钮 | 执行搜索 → 重置到第 1 页 |
92
+ | 输入框 hover 显示 × | 清空输入 → 维度切回"全部" |
93
+ | 输入框为空时点搜索 | 清除当前条件 → 重置分页 |
94
+
95
+ ### 4.4 FilterTag 展示
96
+
97
+ - 已应用的搜索条件以 FilterTag 形式展示
98
+ - 单条 Tag 含 `label: value ×`
99
+ - 多条提供「清空全部」链接
100
+
101
+ ### 4.5 搜索维度配置示例
102
+
103
+ > 维度按业务上下文动态配置;默认含「全部」。
104
+
105
+ ```json
106
+ // 默认维度
107
+ [
108
+ { "label": "全部", "value": "all" },
109
+ { "label": "名称", "value": "name" },
110
+ { "label": "ID", "value": "id" }
111
+ ]
112
+
113
+ // ECS 实例列表示例
114
+ [
115
+ { "label": "全部", "value": "all" },
116
+ { "label": "实例 ID/名称", "value": "instance" },
117
+ { "label": "IP", "value": "ip" },
118
+ { "label": "标签", "value": "tag" }
119
+ ]
120
+ ```
121
+
122
+ ---
123
+
124
+ ## 5. DataTable 规则(核心)
125
+
126
+ ### 5.1 列元规则(每列必备)
127
+
128
+ | 规则 | 说明 |
129
+ | -------- | ------------------------------------- |
130
+ | 唯一 ID | 用于列宽 / 显隐持久化 |
131
+ | 显隐规则 | "始终显示" 或 "条件显示" + 触发条件 |
132
+ | 宽度定义 | 固定 px / 百分比 / minmax |
133
+ | 对齐方式 | left(默认)/ center / right |
134
+ | 排序能力 | 是否支持服务端排序 |
135
+ | 固定方向 | left(前缀列)/ right(操作列)/ none |
136
+ | 字体 | ID/IP/Hash 等机器列用 `font-mono` |
137
+
138
+ ### 5.2 列固定
139
+
140
+ - 左固定:Checkbox(48px) + ID/名称(20%)
141
+ - 右固定:操作列(140px)
142
+ - 固定列与滚动列交界处 `box-shadow: 1px 0 0 var(--border)`
143
+ - 固定列 `z-index: 10`,滚动列 `z-index: 1`
144
+
145
+ ### 5.3 行高
146
+
147
+ - 单行内容:56px
148
+ - 多行内容(如规格列):72px+
149
+
150
+ ### 5.4 选择框三态
151
+
152
+ | 状态 | 视觉 | 触发 |
153
+ | ------ | ---------------- | --------------- |
154
+ | 未选 ☐ | 默认 | — |
155
+ | 半选 ☐̲ | 当前页有部分选中 | 自动计算 |
156
+ | 全选 ☑ | 当前页全选 | 点表头 checkbox |
157
+
158
+ ### 5.5 行选择交互
159
+
160
+ - Checkbox:切换当前行
161
+ - 行点击(非操作区):跳转 DetailPage
162
+ - Shift+点击:范围选中
163
+ - Ctrl/Cmd+点击:切换单行
164
+ - 选中样式:背景 `bg-accent`(与 Checkbox 选中态一致)
165
+
166
+ ### 5.6 列宽拖拽
167
+
168
+ - 拖拽手柄置于列头右边界,宽 2px,`cursor: col-resize`
169
+ - 仅对 `visibility: always` 的列允许拖拽
170
+ - 最小宽度取列定义的 `minWidth`(无定义时默认 100px,状态/监控类窄列 80px)
171
+ - 最大宽度不超过表格宽度的 50%
172
+ - 拖拽过程对 `document.body` 加 `cursor: col-resize` + `user-select: none`,防鼠标越界丢失光标
173
+ - 拖拽结束写入 `localStorage`(key 命名 `columnWidths:{产品ID}`);初始化时读取恢复
174
+ - 列配置弹窗提供「恢复默认列宽」按钮,清 localStorage 后刷新
175
+
176
+ ### 5.7 列排序
177
+
178
+ - 表头右侧 `⇅` 图标(`text-tertiary`、12px)
179
+ - 升序 `↑` / 降序 `↓` 用 `primary` 色
180
+ - 点击循环:默认 → 升序 → 降序 → 默认
181
+ - 排序状态持久化到 `localStorage`
182
+
183
+ ### 5.8 文字换行
184
+
185
+ | 列类型 | 处理 |
186
+ | ------- | -------------------------------------------------- |
187
+ | ID / IP | `font-mono` + `word-break: break-all` + `truncate` |
188
+ | 规格 | 多行展示,不截断 |
189
+ | 标签 | 最多 3 个 + `+N`,不自动换行 |
190
+
191
+ ---
192
+
193
+ ## 6. 操作列规范(硬约束)
194
+
195
+ ### 6.1 结构
196
+
197
+ 操作列 = 主操作 + 分隔线 + 次要操作 + 分隔线 + 状态操作 + 分隔线 + 更多
198
+
199
+ | 元素 | 样式 | 禁用 |
200
+ | ------------------- | -------- | -------------------------------- |
201
+ | 主操作(管理/查看) | 链接样式 | — |
202
+ | `\|` 分隔线 | — | — |
203
+ | 次要操作 | 文字按钮 | `opacity-45 pointer-events-none` |
204
+ | 状态操作 | 下拉按钮 | 同上 |
205
+ | "..." 更多 | Dropdown | — |
206
+
207
+ ### 6.2 水平对齐(硬约束)
208
+
209
+ - `text-align: left`,**表头与表体均需显式声明**
210
+ - 表头「操作」左边缘 X = 表体「详情」链接左边缘 X
211
+ - ❌ 禁止操作列内容居中
212
+ - ❌ 禁止只在 `.col-action` 上设 text-align(部分浏览器会被覆盖)
213
+
214
+ ### 6.3 操作列行为映射
215
+
216
+ | 操作 | 触发 | 前置 | 二次确认 | 目标 | 返回行为 |
217
+ | --------- | -------- | ------------- | --------------- | ----------------- | ------------------------------------ |
218
+ | 查看/管理 | 点链接 | — | 否 | DetailPage | 返回列表保持筛选+分页 |
219
+ | 编辑 | 点按钮 | — | 否 | FormPage / Drawer | 保存成功返回列表 + Toast「保存成功」 |
220
+ | 删除 | 点按钮 | 资源已停止 | 是(三级 Dialog) | Dialog 确认 | 确认后刷新 + Toast「删除成功」 |
221
+ | 更多 | Dropdown | — | 按操作分级 | Dropdown 菜单 | 选择子操作 |
222
+
223
+ ---
224
+
225
+ ## 7. Card 内对齐规则(硬约束 — 最容易不稳定的点)
226
+
227
+ 水平 padding 分层模型:
228
+
229
+ - **Card.paddingX = 24px**:提供 Card 外缘 ↔ 非 Table 子组件的呼吸
230
+ - **Table 中间列 padding = 12px**(左右 12+12=24,列间 24px)
231
+ - **Table 首列 padding-left = 20px**(额外缩进)
232
+ - **Table 末列 padding-right = 20px**
233
+
234
+ | 组件 | 水平 padding | 起始 X |
235
+ | ------------------------------------------------------- | ------------------- | -------------- |
236
+ | Card 白卡容器 | **24px** | Card 外缘 |
237
+ | PageHeader / ActionToolbar / BulkActionBar / Pagination | **0** | Card 外缘 + 24 |
238
+ | Table 中间列 td | 12px | — |
239
+ | Table 首列 td | padding-left: 20px | Card 外缘 + 44 |
240
+ | Table 末列 td | padding-right: 20px | Card 右缘 - 44 |
241
+
242
+ ### 禁止项
243
+
244
+ - ❌ 在 PageHeader / ActionToolbar / Pagination 上重复设 paddingX(会与 Card.paddingX 叠加为 48px)
245
+ - ❌ Table 中间列 padding 不为 12px
246
+ - ❌ Table 首/末列 padding 不为 20px
247
+ - ❌ 用 `px-4` `px-6` 字面量 — 用 `px-3 first:pl-5 last:pr-5`
248
+ - ❌ 在 Card 与子组件间插入额外 paddingX 包裹层
249
+
250
+ ### 验证
251
+
252
+ 1. PageHeader / ActionToolbar / Pagination 起始 X = Card 左缘 + 24
253
+ 2. Table 首列 (checkbox) 内容 X = Card 左缘 + 44
254
+ 3. Table 相邻中间列内容间距 = 24
255
+
256
+ ---
257
+
258
+ ## 8. 状态-操作模式
259
+
260
+ ### 8.1 元规则
261
+
262
+ - 每个状态必须定义操作可用性矩阵
263
+ - 禁用样式统一 `opacity-45 pointer-events-none`
264
+ - 混合状态时批量按钮禁用,hover 提示原因
265
+ - 异步操作必须有 Toast + 列表刷新机制
266
+
267
+ ### 8.2 操作确认分级
268
+
269
+ | 级别 | 适用 | 确认方式 |
270
+ | -------------------- | -------------------- | --------------------- |
271
+ | **一级**(可逆) | 查看、编辑、远程连接 | 直接执行 |
272
+ | **二级**(影响状态) | 启动、停止、重启 | Dialog 确认 |
273
+ | **三级**(不可逆) | 删除 | Dialog + 输入确认文本 |
274
+
275
+ ### 8.3 异步反馈
276
+
277
+ | 操作 | Toast 文案 | 列表 |
278
+ | -------- | ------------------------- | ------------ |
279
+ | 状态变更 | "操作已提交" | 轮询状态 |
280
+ | 删除 | "删除已提交" | 移除行或刷新 |
281
+ | 批量 | "批量操作已提交,共 N 条" | 轮询 |
282
+
283
+ ### 8.4 页面间导航交互
284
+
285
+ - **操作列「查看/管理」** → DetailPage(页面跳转);面包屑返回,保持筛选+分页
286
+ - **操作列「编辑」** → FormPage 或 Drawer(跳转/侧滑);保存/取消返回列表,保存附 Toast
287
+ - **创建操作** → FormPage(页面跳转);创建成功/取消返回列表
288
+ - **搜索执行** → 当前列表(数据刷新);重置到第 1 页
289
+ - **筛选条件变更** → 当前列表(数据刷新);重置到第 1 页,保持筛选条件
290
+
291
+ ---
292
+
293
+ ## 9. 嵌套约束
294
+
295
+ | 父子关系 | 状态 |
296
+ | ----------------------------------------------------------------------------------------------- | ---------------------------- |
297
+ | PageContainer → ContentWrapper → Card(白卡容器) → PageHeader/ActionToolbar/DataTable/Pagination | ALLOW |
298
+ | ContentWrapper → 业务组件(无 Card 包裹) | **FORBID** |
299
+ | Card → Card | **FORBID**(白卡单例) |
300
+ | ActionToolbar → SearchCombo | ALLOW |
301
+ | CardGrid → ItemCard → CardActionBar | ALLOW |
302
+ | DataTable → Pagination | ALLOW |
303
+ | DataTable → Form | **FORBID**(用 Drawer 触发) |
304
+
305
+ ---
306
+
307
+ ## 10. 禁止项
308
+
309
+ | 禁项 | 原因 |
310
+ | ---------------------- | ----------------------------------- |
311
+ | Form 直接出现在内容区 | 应通过 Dialog/Drawer/FormPage 触发 |
312
+ | Chart 出现在标准列表 | 图表归属 Dashboard |
313
+ | 内联编辑 | 编辑必须通过 Drawer/Dialog/FormPage |
314
+ | 拖拽排序 | 表格数据为服务端排序 |
315
+ | 无限滚动 | B2B 管理场景需精确分页 |
316
+ | 悬浮操作栏 | 遮挡数据,可发现性差 |
317
+ | 右键菜单 | 移动端不兼容 |
318
+ | `hr` / section-divider | 间距通过 padding/margin 控制 |
319
+
320
+ ---
321
+
322
+ ## 11. 列表页特有自检
323
+
324
+ - [ ] PageHeader / ActionToolbar / DataTable / Pagination 嵌套结构正确
325
+ - [ ] Card 内统一左右 padding 24px(除 Table 列)
326
+ - [ ] 子类型组件正确(standard 用 DataTable,pure-card 用 CardGrid)
327
+ - [ ] SearchCombo 位置正确(间距 20px)
328
+ - [ ] 操作列水平对齐左对齐
329
+ - [ ] 状态-操作矩阵在所有状态下正确
330
+ - [ ] 二次确认按级别正确(启动/停止 = Dialog;删除 = 输入确认)
331
+ - [ ] 批量操作按钮:选中 ≥1 行显示,混合状态禁用
332
+ - [ ] 搜索:回车执行、维度切换清空、FilterTag 展示
333
+ - [ ] 分页:保持筛选 + "共 N 条"
334
+ - [ ] 边界:空数据 Empty + 加载 Loading + 错误 ErrorState