wucaishi-generative-react-skill 0.1.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 +51 -0
- package/SKILL.md +196 -0
- package/bin/install.mjs +114 -0
- package/package.json +27 -0
- package/scripts/check_component_name_exists.mjs +187 -0
- package/scripts/check_h5_font_sizes.mjs +85 -0
- package/scripts/check_h5_vw_units.mjs +62 -0
- package/subskills/build-version-confirm-zh/SKILL.md +93 -0
- package/subskills/html-template-to-react-components-zh/SKILL.md +134 -0
- package/subskills/html-template-to-react-components-zh/scripts/analyze_template_pair.mjs +377 -0
- package/subskills/html-template-to-react-components-zh/scripts/validate_component_contract.mjs +217 -0
- package/subskills/react-component-spec-zh/SKILL.md +601 -0
- package/subskills/upload-aliyun-oss-zh/SKILL.md +145 -0
- package/subskills/upload-aliyun-oss-zh/agents/openai.yaml +7 -0
- package/subskills/upload-aliyun-oss-zh/scripts/upload_dist_to_aliyun_oss.mjs +640 -0
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: react-component-spec-zh
|
|
3
|
+
description: 当父 skill `component-package-workflow-zh` 处理生成、编写、修改、编辑或重构 React 组件任务时使用。用于约束 React 组件在生成和编辑过程中的职责划分、Props 设计、交互状态边界、状态管理、副作用处理、样式组织、H5 移动端适配、375 设计稿基准、截图参考生成、styled-components 约定、`schema.ts` 与 `manifest.json` 产出要求及可访问性要求。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# React 组件规范 Skill
|
|
7
|
+
|
|
8
|
+
这个 Skill 用于在 React 项目中生成、编写、修改、编辑或重构组件代码。它描述的是通用的 React 组件规范,重点服务于“生成组件”和“编辑已有组件”这两类任务;其中样式实现必须使用 `styled-components`,这不是可选偏好,而是本 Skill 的硬性要求。
|
|
9
|
+
|
|
10
|
+
除非用户明确要求偏离,否则默认按本规范执行,并使用中文输出说明。
|
|
11
|
+
|
|
12
|
+
## 适用场景
|
|
13
|
+
|
|
14
|
+
当用户出现以下意图时触发:
|
|
15
|
+
|
|
16
|
+
- 要你“写一个 React 组件”
|
|
17
|
+
- 要你“生成一个 React 组件”
|
|
18
|
+
- 要你“补全一个 React 组件”
|
|
19
|
+
- 要你“修改一个 React 组件”
|
|
20
|
+
- 要你“编辑一个 React 组件”
|
|
21
|
+
- 要你“生成 React 组件规范”
|
|
22
|
+
- 要你“重构 React 组件”
|
|
23
|
+
- 要你“统一 React 组件代码风格”
|
|
24
|
+
|
|
25
|
+
这个 Skill 主要用于组件代码的实际产出与变更,不以“单独写规范文档”或“纯 review”作为第一目标。即使用户没有显式提到规范,只要任务是生成或编辑 React 组件,也应默认遵循本 Skill。
|
|
26
|
+
|
|
27
|
+
如果用户只是要一个非常小的临时 demo,也尽量遵守本规范,但可以适度简化目录要求。
|
|
28
|
+
但只要组件会被复用、会进入正式代码库,仍应优先采用下面定义的目录结构,而不是只留下一个孤立的 `tsx` 文件。
|
|
29
|
+
|
|
30
|
+
## 默认假设
|
|
31
|
+
|
|
32
|
+
如果用户没有额外说明,默认按以下方式实现:
|
|
33
|
+
|
|
34
|
+
- React 函数组件
|
|
35
|
+
- TypeScript
|
|
36
|
+
- 使用具名 `Props` 类型
|
|
37
|
+
- 使用语义化 HTML
|
|
38
|
+
- 业务逻辑与样式逻辑分层
|
|
39
|
+
- 交互状态与业务动作边界清晰
|
|
40
|
+
- 样式技术必须使用 `styled-components`
|
|
41
|
+
- 正式组件默认支持 H5 移动端适配
|
|
42
|
+
- H5 组件默认以 `375px` 宽度设计稿为视觉基准
|
|
43
|
+
- 生成组件时默认包含 `schema.ts`
|
|
44
|
+
- 生成组件时默认包含 `manifest.json`
|
|
45
|
+
|
|
46
|
+
即使项目里已经混用了其他样式方案,只要当前任务受本 Skill 约束,组件产出仍应收敛到 `styled-components`;不要继续沿用 CSS Modules、Less、Sass、Emotion 或内联样式作为最终实现。
|
|
47
|
+
|
|
48
|
+
## styled-components 强制规则
|
|
49
|
+
|
|
50
|
+
- 当任务触发本 Skill 时,组件样式必须使用 `styled-components`。
|
|
51
|
+
- 这条规则同时适用于新增组件、编辑组件和重构组件。
|
|
52
|
+
- 除非用户明确要求偏离并接受代价,否则不要改用其他样式方案。
|
|
53
|
+
- 如果现有组件使用的是其他样式方案,本次改动涉及样式层时,应优先把改动范围内的实现迁移或收敛到 `styled-components`。
|
|
54
|
+
|
|
55
|
+
## 依赖检查与安装
|
|
56
|
+
|
|
57
|
+
在开始编写或修改组件前,先检查项目是否已经安装 `styled-components`。
|
|
58
|
+
|
|
59
|
+
- 先读取 `package.json`,并结合锁文件判断项目正在使用的包管理器。
|
|
60
|
+
- 如果已经安装 `styled-components`,直接按项目现有版本继续实现。
|
|
61
|
+
- 如果没有安装,先安装 `styled-components`,再开始组件实现。
|
|
62
|
+
- TypeScript 项目如果当前所用 `styled-components` 版本不自带类型,补齐与该版本匹配的类型包,例如 `@types/styled-components`。
|
|
63
|
+
- 安装时优先跟随项目现有包管理器,不要擅自切换。
|
|
64
|
+
|
|
65
|
+
常用安装命令示例:
|
|
66
|
+
|
|
67
|
+
- `pnpm add styled-components`
|
|
68
|
+
- `yarn add styled-components`
|
|
69
|
+
- `npm install styled-components`
|
|
70
|
+
- `bun add styled-components`
|
|
71
|
+
|
|
72
|
+
## 工作方式
|
|
73
|
+
|
|
74
|
+
处理任务时,按下面顺序思考:
|
|
75
|
+
|
|
76
|
+
1. 明确组件职责和边界。
|
|
77
|
+
2. 先检查项目是否已安装 `styled-components`;若未安装,先完成安装。
|
|
78
|
+
3. 判断这是“对外复用组件”还是“局部私有子组件”,先确定目录结构与文件拆分。
|
|
79
|
+
4. 先设计组件 API,再安排内部状态。
|
|
80
|
+
5. 生成组件时同步定义或更新 `schema.ts` 与 `manifest.json`,先明确组件的结构化输入边界和组件包元信息,再落实现代码。
|
|
81
|
+
6. 区分哪些是业务 props,哪些是仅服务样式的实现细节。
|
|
82
|
+
7. 如果用户提供截图,先识别截图中的组件边界、视觉结构、可变内容和交互,再落到 Props、schema 与样式实现。
|
|
83
|
+
8. 如果组件面向 H5,默认按移动端优先和 `375px` 设计稿基准实现,并保证小屏不溢出。
|
|
84
|
+
9. 优先复用已有组件和基础样式能力。
|
|
85
|
+
10. 保持组件层、样式层、schema 层、辅助函数层清晰。
|
|
86
|
+
11. 输出代码时优先保证可读性、可维护性以及代码、`schema.ts`、`manifest.json` 一致性。
|
|
87
|
+
|
|
88
|
+
当任务是生成或编辑 React 组件时,应把本 Skill 视为默认执行规范,而不是可选参考。也就是说,组件代码的结构、命名、状态设计、样式边界和输出方式都应优先服从本 Skill。
|
|
89
|
+
|
|
90
|
+
## 生成与编辑要求
|
|
91
|
+
|
|
92
|
+
### 生成组件时
|
|
93
|
+
|
|
94
|
+
- 先确定组件职责,再设计 `Props`。
|
|
95
|
+
- 先保证 API 清晰,再补全内部实现。
|
|
96
|
+
- 默认直接产出符合规范的最终代码,而不是只给思路。
|
|
97
|
+
- 如果用户没有限制,默认输出可落地的 TypeScript React 函数组件实现。
|
|
98
|
+
- 开始实现前先确认项目已安装 `styled-components`;若缺失,先安装再继续。
|
|
99
|
+
- 先按本 Skill 判断组件文件结构;默认直接在组件包的 `src` 目录下创建组件文件,不额外新建 `components/` 或同名组件子目录。
|
|
100
|
+
- 生成组件时默认同时创建 `schema.ts` 和 `manifest.json`,不要只生成视图文件。
|
|
101
|
+
- `schema.ts` 用于声明组件的结构化内容或配置输入约束,字段、必填项、默认值语义要与组件实现保持一致。
|
|
102
|
+
- `manifest.json` 用于声明组件包元信息。若组件包内已有既有 `manifest.json`,优先在原位置更新;若当前不存在,默认在 `src/manifest.json` 创建。
|
|
103
|
+
- `manifest.json` 默认至少包含:组件包名称、描述、使用场景、组件接收参数 `Props`、来源、边界与限制。
|
|
104
|
+
- 样式必须按 `styled-components` 组织,不能因为项目里已有其他样式方案就改用别的实现。
|
|
105
|
+
- 对外复用组件默认至少补齐主文件、样式文件、导出文件、`schema.ts` 和 `manifest.json`。
|
|
106
|
+
- 面向 H5 或参考移动端截图生成时,默认按移动端优先、`375px` 设计稿基准和响应式约束实现,不能只生成桌面可用的静态布局。
|
|
107
|
+
- 面向 H5 的组件在首次创建 `ComponentName.styles.ts` 时必须直接使用 `vw()` 换算函数编写视觉尺寸,不允许先写普通 `px` 再计划后续转换。
|
|
108
|
+
|
|
109
|
+
### 编辑组件时
|
|
110
|
+
|
|
111
|
+
- 优先保留原有组件对外 API 的稳定性,除非用户明确要求修改。
|
|
112
|
+
- 先识别当前组件的问题点,再做最小必要改动。
|
|
113
|
+
- 不要为了“更规范”而无谓重写整个组件。
|
|
114
|
+
- 若发现现有实现偏离本 Skill,尤其是未使用 `styled-components`,应在修改中顺手收敛,但避免引入破坏性变更。
|
|
115
|
+
- 若发现组件文件结构明显混乱,例如导出、样式、类型都堆在一个文件里,应在不破坏导入路径的前提下收敛到本 Skill 定义的文件结构。
|
|
116
|
+
- 若本次改动影响组件的数据输入结构、字段含义、必填关系、枚举范围或默认值语义,必须同步更新 `schema.ts` 与 `manifest.json` 中的 `Props` 信息。
|
|
117
|
+
- 若本次改动影响组件名称、描述、使用场景、来源或边界与限制,必须同步更新 `manifest.json`。
|
|
118
|
+
- 若当前组件缺少 `schema.ts` 或 `manifest.json`,且任务语义属于正式组件生成或长期维护组件改造,应优先补齐,而不是继续放任缺失。
|
|
119
|
+
- 编辑目标应优先聚焦:可读性、职责清晰、状态收敛、样式边界、可访问性和可维护性。
|
|
120
|
+
|
|
121
|
+
### 输出原则
|
|
122
|
+
|
|
123
|
+
- 默认输出可以直接替换或新增到项目中的代码。
|
|
124
|
+
- 如有必要,再补充一小段中文说明,解释关键取舍。
|
|
125
|
+
- 如果做了兼容性保留或 API 保留,要明确说明原因。
|
|
126
|
+
- 如果新增或修改了 `schema.ts`,要说明它与组件实现之间的对应关系。
|
|
127
|
+
- 如果新增或修改了 `manifest.json`,要说明元信息来源,以及它与组件实现、`Props` 和来源字段之间的对应关系。
|
|
128
|
+
|
|
129
|
+
## Manifest 同步要求
|
|
130
|
+
|
|
131
|
+
- 组件任务默认要检查 `manifest.json`,不能因为用户没提就直接跳过。
|
|
132
|
+
- 如果组件包中已经存在 `manifest.json`,优先沿用原路径更新;如果不存在,默认创建 `src/manifest.json`。
|
|
133
|
+
- `manifest.json` 默认至少包含以下字段:
|
|
134
|
+
- `name`:组件包名称
|
|
135
|
+
- `description`:组件包描述
|
|
136
|
+
- `usageScenarios`:使用场景
|
|
137
|
+
- `props`:组件接收参数 `Props`
|
|
138
|
+
- `source`:来源
|
|
139
|
+
- `limitations`:边界与限制
|
|
140
|
+
- `props` 字段应与组件当前对外 `Props` 保持一致;至少反映参数名、类型、是否必填、默认值语义和用途说明。
|
|
141
|
+
- 发布到平台的 `manifest.json.name` 必须使用 `<中文场景或模板>_<中文组件名>_<english_component_code>`,例如 `会议总结_一句话看懂_meeting_minutes_summary`;不要只填写纯英文机器名。
|
|
142
|
+
- `manifest.json.packageName` 如存在,必须等于 `package.json.name`,并使用 `english_component_code` 转成 kebab-case 的机器名,例如 `meeting-minutes-summary`。
|
|
143
|
+
- 当某个 prop 的默认值是数组或对象时,组件本地 demo 可以直接使用数组或对象;但组件运行时必须兼容平台回传的 JSON 字符串默认值,先解析为目标数组或对象再渲染,确保本地默认显示与远程发布后的默认显示一致。
|
|
144
|
+
- `manifest.json` 中数组或对象类型的 `default` 可以保留结构化值;上传发布脚本会在提交平台前把这类 `default` 转成 JSON 字符串,避免平台保存为空字符串。不要为了平台保存限制而让组件实现只支持字符串。
|
|
145
|
+
- 发布到平台的 `manifest.json.props` 必须只包含业务可配置字段,且每一项都必须显式提供 `default`。不要把 `className`、`style`、受控状态字段(如 `open`、`collapsed`)或函数回调字段(如 `onOpenChange`、`onCollapsedChange`、任意 `onXxx`)放进平台 manifest;这些字段可以保留在 TypeScript Props 中供代码调用,但不属于平台编辑器配置项。
|
|
146
|
+
- 对数组或对象 props,组件实现必须同时兼容 `undefined`、`null`、结构化数组/对象和 JSON 字符串。不要直接对外部传入值调用 `.filter`、`.map` 或访问对象字段;应先用 `Array.isArray(...)`、JSON 解析和默认值兜底得到安全值,再渲染。
|
|
147
|
+
- `source` 字段应与当前组件包来源信息保持一致;如果项目对来源地址已有固定格式,优先沿用现有格式。
|
|
148
|
+
- `manifest.json` 中的名称、描述、使用场景、边界与限制应与组件当前真实能力一致,不要复制过时描述。
|
|
149
|
+
- 如果本次改动只涉及内部实现且不影响对外信息,也要完成检查,再决定 `manifest.json` 是否无需更新。
|
|
150
|
+
|
|
151
|
+
推荐结构示例:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"name": "hero-banner",
|
|
156
|
+
"description": "用于页面首屏展示标题、描述和行动按钮的横幅组件。",
|
|
157
|
+
"usageScenarios": [
|
|
158
|
+
"营销活动页首屏展示",
|
|
159
|
+
"品牌专题页关键信息呈现"
|
|
160
|
+
],
|
|
161
|
+
"props": [
|
|
162
|
+
{
|
|
163
|
+
"name": "title",
|
|
164
|
+
"type": "string",
|
|
165
|
+
"required": true,
|
|
166
|
+
"description": "主标题内容"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"name": "ctaText",
|
|
170
|
+
"type": "string",
|
|
171
|
+
"required": false,
|
|
172
|
+
"description": "按钮文案",
|
|
173
|
+
"default": "立即查看"
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"source": "https://prism-stone-hangzhou.oss-accelerate.aliyuncs.com/wucaishi/h5/components/interview-voice-note-card/1.0.0/index.js",
|
|
177
|
+
"limitations": [
|
|
178
|
+
"不适合承载超过两个主操作按钮",
|
|
179
|
+
"标题过长时需要调用方自行控制文案长度"
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## 核心规范
|
|
185
|
+
|
|
186
|
+
### 1. 组件职责
|
|
187
|
+
|
|
188
|
+
- 一个组件只处理一个清晰的 UI 职责。
|
|
189
|
+
- 容器逻辑、数据获取、复杂副作用尽量放在上层或自定义 Hook。
|
|
190
|
+
- 展示组件优先保持纯净,减少与外部系统直接耦合。
|
|
191
|
+
- 当一个组件同时承担布局、交互、数据转换和样式控制时,应考虑拆分。
|
|
192
|
+
|
|
193
|
+
拆分信号:
|
|
194
|
+
|
|
195
|
+
- JSX 分支过多
|
|
196
|
+
- 组件状态与样式状态混杂
|
|
197
|
+
- 重复结构或重复样式片段频繁出现
|
|
198
|
+
- 同时存在多个不相关交互逻辑
|
|
199
|
+
- 业务逻辑、展示逻辑、副作用逻辑缠绕在一起
|
|
200
|
+
|
|
201
|
+
### 2. 文件与命名
|
|
202
|
+
|
|
203
|
+
- 组件文件默认直接放在组件包的 `src` 目录下。
|
|
204
|
+
- 除非用户明确要求,否则不要额外创建 `components/`、`ComponentName/` 等子目录层级。
|
|
205
|
+
- 组件主文件名与组件名保持一致,使用 PascalCase。
|
|
206
|
+
- 样式文件默认命名为 `ComponentName.styles.ts`。
|
|
207
|
+
- schema 文件默认命名为 `schema.ts`。
|
|
208
|
+
- 类型文件默认命名为 `ComponentName.types.ts`。
|
|
209
|
+
- 样式组件、子组件、辅助组件命名同样使用 PascalCase。
|
|
210
|
+
- 组件名应体现结构或业务语义,如 `UserCard`、`ProductPanel`、`FilterActions`。
|
|
211
|
+
- 事件处理函数使用 `handleXxx`。
|
|
212
|
+
- Hook 使用 `useXxx`。
|
|
213
|
+
- 布尔值使用 `is`、`has`、`can`、`should` 前缀。
|
|
214
|
+
|
|
215
|
+
#### 组件文件结构
|
|
216
|
+
|
|
217
|
+
默认把组件包的 `src` 目录作为组件的基本交付位置,而不是在 `src` 下再额外套一层 `components/` 或 `ComponentName/` 子目录。只要组件会被复用、会长期维护、会进入共享 UI 层或业务组件层,就应在 `src` 根目录直接补齐主文件、样式文件、`schema.ts`、`manifest.json` 和导出文件。
|
|
218
|
+
|
|
219
|
+
对外复用组件默认目录模板如下:
|
|
220
|
+
|
|
221
|
+
```text
|
|
222
|
+
src/
|
|
223
|
+
index.ts
|
|
224
|
+
ComponentName.tsx
|
|
225
|
+
ComponentName.styles.ts
|
|
226
|
+
schema.ts
|
|
227
|
+
manifest.json
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
各文件职责如下:
|
|
231
|
+
|
|
232
|
+
- `index.ts`:`src` 根目录唯一的公开出口。默认用 `export { default } from "./ComponentName";` 暴露组件,并按需具名导出类型、schema 等;不要在业务代码里绕过它直接从深层文件导入。
|
|
233
|
+
- `ComponentName.tsx`:组件主实现文件。默认使用 `export default` 导出组件本身;负责结构、行为、状态编排和样式组件装配,不要把大量样式定义直接堆在这里。
|
|
234
|
+
- `ComponentName.styles.ts`:组件样式文件。负责 `styled-components` 定义、样式片段和少量样式变体映射。
|
|
235
|
+
- `schema.ts`:组件输入 schema 文件。负责声明组件内容或配置数据的结构约束,并保持与组件实现、字段语义一致。导出命名默认使用与组件语义一致的 `lowerCamelCase + Schema`,例如 `heroSchema`、`textBlockSchema`。
|
|
236
|
+
- `manifest.json`:组件包元信息文件。负责声明组件包名称、描述、使用场景、`Props`、来源和边界与限制,并保持与组件实现和外部说明一致。
|
|
237
|
+
|
|
238
|
+
复杂组件可在默认模板基础上按需扩展,例如:
|
|
239
|
+
|
|
240
|
+
```text
|
|
241
|
+
src/
|
|
242
|
+
index.ts
|
|
243
|
+
ComponentName.tsx
|
|
244
|
+
ComponentName.styles.ts
|
|
245
|
+
schema.ts
|
|
246
|
+
manifest.json
|
|
247
|
+
ComponentName.types.ts
|
|
248
|
+
hooks.ts
|
|
249
|
+
utils.ts
|
|
250
|
+
constants.ts
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
扩展文件使用规则:
|
|
254
|
+
|
|
255
|
+
- `schema.ts`:生成组件时默认必备,不作为可随手省略的可选文件。除非用户明确要求做纯一次性临时片段,否则应补齐。
|
|
256
|
+
- `manifest.json`:生成组件时默认必备,不作为可随手省略的可选文件。除非用户明确要求做纯一次性临时片段,否则应补齐。
|
|
257
|
+
- `ComponentName.types.ts`:当 props、内部数据结构或导出类型已经明显变复杂,影响主文件可读性时再拆出;不要为了“看起来规范”而机械拆分简单类型。
|
|
258
|
+
- `hooks.ts`:仅在该组件存在局部复用的自定义 Hook 时创建;不要把一次性逻辑强行抽到这里。
|
|
259
|
+
- `utils.ts`:仅放与该组件强相关、且不适合作为通用工具沉到共享层的纯函数。
|
|
260
|
+
- `constants.ts`:仅放该组件私有的枚举、映射、默认值或 key 常量;避免把少量字面量也拆成独立文件。
|
|
261
|
+
|
|
262
|
+
#### 目录结构强制规则
|
|
263
|
+
|
|
264
|
+
- 对外复用组件默认直接放在 `src` 根目录,不额外创建 `components/`、`ComponentName/` 等子目录。
|
|
265
|
+
- 默认必须有 `index.ts`,并由它以默认导出方式暴露组件,不要让外部直接 import 深层实现文件。
|
|
266
|
+
- 默认必须有主文件 `ComponentName.tsx`,且组件本身默认使用 `export default`。
|
|
267
|
+
- 只要组件不是极小型临时私有组件,默认必须有 `ComponentName.styles.ts`,不要长期把样式和实现全部挤在一个文件里。
|
|
268
|
+
- 生成组件时默认必须有 `schema.ts`;如果没有生成,必须有明确且合理的任务级原因。
|
|
269
|
+
- 生成组件时默认必须有 `manifest.json`;如果没有生成,必须有明确且合理的任务级原因。
|
|
270
|
+
|
|
271
|
+
#### 可以简化的场景
|
|
272
|
+
|
|
273
|
+
- 仅在父组件内部使用、生命周期很短、逻辑非常简单的私有子组件,可以不单独建目录。
|
|
274
|
+
- 这种私有子组件可以与父组件同目录,甚至同文件,但前提是不会削弱可读性。
|
|
275
|
+
- 即便允许简化,也不要把本应独立复用的组件伪装成“临时子组件”来逃避目录规范。
|
|
276
|
+
|
|
277
|
+
### 3. Props 设计
|
|
278
|
+
|
|
279
|
+
- 组件 API 应优先表达业务意图,而不是暴露样式实现细节。
|
|
280
|
+
- 业务 props 和样式实现 props 要有边界。
|
|
281
|
+
- 避免向外暴露过多仅服务样式的配置项。
|
|
282
|
+
- 谨慎使用 `any`、`object`、`Function`。
|
|
283
|
+
- 回调统一使用 `onXxx` 命名。
|
|
284
|
+
- 可选 props 要有明确语义和默认值策略。
|
|
285
|
+
- 能通过组合解决的问题,优先组合而不是堆配置开关。
|
|
286
|
+
- 交互回调统一使用 `onXxx` 或 `onXxxChange` 命名,不要用模糊的 `callback`、`handle`、`fn`。
|
|
287
|
+
- 组件支持受控和非受控两种用法时,Props 命名应清晰区分,例如 `open`/`defaultOpen`/`onOpenChange`。
|
|
288
|
+
|
|
289
|
+
推荐示例:
|
|
290
|
+
|
|
291
|
+
```tsx
|
|
292
|
+
type ButtonProps = {
|
|
293
|
+
children: React.ReactNode;
|
|
294
|
+
variant?: "primary" | "secondary";
|
|
295
|
+
isLoading?: boolean;
|
|
296
|
+
onClick?: () => void;
|
|
297
|
+
};
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### 4. 交互设计与状态边界
|
|
301
|
+
|
|
302
|
+
当组件存在点击、展开、收起、切换、轮播、弹层、选中、播放、复制、跳转、吸底操作等交互时,必须先明确交互状态归属,再实现 UI。
|
|
303
|
+
|
|
304
|
+
- 组件自己负责 UI 状态和展示反馈,业务动作通过 Props 回调交给调用方。
|
|
305
|
+
- 纯 UI 状态可以由组件内部维护,例如展开/收起、当前 tab、当前轮播项、弹层开关。
|
|
306
|
+
- 涉及业务结果、跳转、提交、埋点、接口请求的动作必须通过 Props 回调暴露给调用方,不要在组件内部写死。
|
|
307
|
+
- 可控状态使用 `value`、`activeKey`、`open`、`current` 等 props,并提供 `onChange`、`onActiveKeyChange`、`onOpenChange`、`onCurrentChange` 等回调。
|
|
308
|
+
- 非可控状态可以提供 `defaultValue`、`defaultActiveKey`、`defaultOpen`、`defaultCurrent`。
|
|
309
|
+
- 不要同时让内部状态和外部 props 互相抢控制权;同一个状态要么受控,要么非受控并以默认值初始化。
|
|
310
|
+
- 交互元素必须使用语义化标签,例如按钮用 `button`,链接或跳转入口可用 `a` 或由调用方处理点击回调。
|
|
311
|
+
- 移动端交互不能依赖 hover;点击区域不小于 `44px`。
|
|
312
|
+
- 加载态、禁用态、错误态、空态要有明确视觉反馈,禁用态必须阻止对应交互。
|
|
313
|
+
- 如果交互会改变组件内容结构、可配置字段或回调能力,必须同步更新 `schema.ts` 和 `manifest.json` 的 Props 描述。
|
|
314
|
+
|
|
315
|
+
截图或需求中出现交互但规则不明确时,优先用中文反问:
|
|
316
|
+
|
|
317
|
+
- 这个按钮点击后是跳转、提交,还是触发外部回调?
|
|
318
|
+
- 这个区域是否可以展开或收起,默认状态是什么?
|
|
319
|
+
- 切换、轮播、播放是否需要自动执行,是否允许用户手动控制?
|
|
320
|
+
- 是否需要禁用态、加载态、错误态或空态?
|
|
321
|
+
- 交互状态由组件自己维护,还是由外部传入控制?
|
|
322
|
+
|
|
323
|
+
推荐示例:
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
type ExpandableCardProps = {
|
|
327
|
+
title: string;
|
|
328
|
+
open?: boolean;
|
|
329
|
+
defaultOpen?: boolean;
|
|
330
|
+
onOpenChange?: (open: boolean) => void;
|
|
331
|
+
onActionClick?: () => void;
|
|
332
|
+
};
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### 5. 状态管理
|
|
336
|
+
|
|
337
|
+
- 能从 props 或现有状态推导的值,不再重复存 state。
|
|
338
|
+
- 只保存最小必要状态。
|
|
339
|
+
- 不要为了驱动样式而额外制造冗余 state。
|
|
340
|
+
- UI 状态如 `isOpen`、`isActive`、`isLoading` 应有清晰来源。
|
|
341
|
+
- 多个状态联动明显时,优先统一建模。
|
|
342
|
+
- 受控 props 传入时,以外部值为准;非受控场景只用 `defaultXxx` 初始化内部状态。
|
|
343
|
+
|
|
344
|
+
避免:
|
|
345
|
+
|
|
346
|
+
- 用 state 缓存派生值
|
|
347
|
+
- 用 effect 同步 props 到 state
|
|
348
|
+
- 一个组件堆积大量零散 `useState`
|
|
349
|
+
- 在组件内部写死跳转、接口请求、埋点等业务动作
|
|
350
|
+
|
|
351
|
+
### 6. 副作用与 Hook
|
|
352
|
+
|
|
353
|
+
- `useEffect` 仅用于副作用,不处理纯计算。
|
|
354
|
+
- 视觉变化优先通过 props 和状态推导,不要通过 effect 间接驱动。
|
|
355
|
+
- 复杂交互逻辑或订阅逻辑抽到自定义 Hook。
|
|
356
|
+
- 事件、定时器、订阅必须成对清理。
|
|
357
|
+
|
|
358
|
+
判断原则:
|
|
359
|
+
|
|
360
|
+
- 纯计算:放组件内部
|
|
361
|
+
- 交互响应:放事件函数
|
|
362
|
+
- 外部系统同步:放 `useEffect`
|
|
363
|
+
|
|
364
|
+
### 7. JSX 与渲染
|
|
365
|
+
|
|
366
|
+
- JSX 负责表达结构和语义。
|
|
367
|
+
- 不要把大量样式判断直接塞进 JSX 的 `style` 或复杂 class 拼接里。
|
|
368
|
+
- 复杂分支应放进子组件、映射配置或样式辅助函数。
|
|
369
|
+
- JSX 中的业务判断不要和样式判断高度缠绕。
|
|
370
|
+
- 提前 return 处理空态、异常态、加载态,让主渲染路径保持清晰。
|
|
371
|
+
|
|
372
|
+
### 8. 样式组织
|
|
373
|
+
|
|
374
|
+
- 样式实现必须采用 `styled-components`。
|
|
375
|
+
- 不要因为项目已有其他明确方案,就改用其他样式技术替代本 Skill 的要求。
|
|
376
|
+
- 样式定义尽量靠近组件,但要避免把大量样式细节直接堆进 JSX。
|
|
377
|
+
- 对外复用组件默认拆出 `ComponentName.styles.ts`;只有极小型私有子组件才允许长期同文件组织。
|
|
378
|
+
- 重复样式片段优先抽成稳定的样式函数、映射或复用片段。
|
|
379
|
+
- 面向 H5 的样式文件创建时必须先定义 `vw()` 换算函数,再编写组件样式;字体、间距、宽高、圆角、图标、图片尺寸等视觉尺寸首次落码就应使用 `vw()`。
|
|
380
|
+
- 不允许把 `px` 作为临时实现再二次转换为 `vw`;生成的第一版代码就必须满足 H5 vw 单位约束。
|
|
381
|
+
|
|
382
|
+
### 9. H5 移动端适配
|
|
383
|
+
|
|
384
|
+
正式组件默认具备 H5 移动端适配能力,不需要用户额外声明。移动端适配不是把桌面布局整体缩小,而是根据内容结构重排、收敛和约束。
|
|
385
|
+
|
|
386
|
+
- 默认支持 `320px` 到桌面宽度的连续响应式布局,重点检查 `320px`、`375px`、`390px`、`414px`、`430px`、`768px`、`1024px`。
|
|
387
|
+
- 组件外层默认 `width: 100%`,由父容器控制实际展示宽度;组件自身不得制造页面级横向滚动。
|
|
388
|
+
- 不使用无约束的大固定宽度;固定尺寸必须配合 `max-width: 100%`、百分比、flex/grid 或断点规则。
|
|
389
|
+
- 多列、左右分栏、横向排列结构在小屏下应自动改为单列、纵向堆叠或可用的横向滚动区域。
|
|
390
|
+
- 文本、按钮、标签、卡片内容不得在移动端溢出父容器;长文本要有换行、省略或合理的内容约束。
|
|
391
|
+
- 交互元素触控区域不小于 `44px`,不能依赖 hover 展示核心信息或核心操作。
|
|
392
|
+
- 图片、视频、图表等媒体内容必须使用响应式容器,避免撑破布局。
|
|
393
|
+
- 底部固定操作、吸底按钮或全屏容器需要考虑安全区,可使用 `env(safe-area-inset-bottom)`。
|
|
394
|
+
- H5 视觉尺寸默认按 `375px` 设计稿换算为 `vw`,并结合 media query、container query、flex/grid 保证结构可用。
|
|
395
|
+
- 不应为了响应式向外暴露 `isMobile`、`screenType` 等样式实现 props,除非存在真实业务差异。
|
|
396
|
+
|
|
397
|
+
### 10. 375 设计稿基准与 vw 尺寸单位
|
|
398
|
+
|
|
399
|
+
生成 H5 React 组件时,默认以 `375px` 宽度设计稿为视觉基准,并采用 `vw` 方案还原不同手机宽度下的视觉比例。用户明确给出其他设计稿宽度或单位方案时,以用户说明为准。
|
|
400
|
+
|
|
401
|
+
- 设计稿中的尺寸默认按 `375px` 画布理解,换算公式为:`设计稿 px / 375 * 100vw`。
|
|
402
|
+
- 面向 H5 的 `ComponentName.styles.ts` 必须在文件顶部定义局部换算函数,避免在样式里散落手算小数:
|
|
403
|
+
|
|
404
|
+
```ts
|
|
405
|
+
const vw = (px: number) => `${(px / 375) * 100}vw`;
|
|
406
|
+
const fluidFont = (px: number, min = px, max = px) =>
|
|
407
|
+
`clamp(${min}px, ${vw(px)}, ${max}px)`;
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
- 字体、间距、宽高、圆角、图标、图片尺寸等 H5 视觉尺寸默认使用 `vw` 换算,以保持不同手机宽度下的比例一致。
|
|
411
|
+
- 字体尺寸必须使用有边界的 `fluidFont()` 或等价 `clamp()` 表达,不允许在 `font-size` 中直接裸用 `vw()` 或无上限 `vw`,避免桌面预览、宽容器或不同设备下字体异常放大。
|
|
412
|
+
- 组件外层仍应使用 `width: 100%`、flex/grid、百分比和 `max-width` 控制结构,不要只靠 `vw` 堆固定布局。
|
|
413
|
+
- `px` 只保留给不应缩放或缩放后会失真的细节,例如 `1px` 边框、最小点击热区兜底、阴影细节、极细分割线。
|
|
414
|
+
- 触控区域以视觉尺寸按 `vw` 还原时,仍要保证可点击性;必要时使用 `min-height: 44px` 或额外 padding 兜底。
|
|
415
|
+
- 对桌面预览或超宽容器,应给组件容器设置合理 `max-width`,避免 `vw` 随浏览器宽度无限放大。
|
|
416
|
+
- 如果组件需要在非手机容器中复用,应优先用外层容器限制宽度,例如 `max-width: 430px; margin: 0 auto;`,再在内部使用 `vw`。
|
|
417
|
+
- 内容区域可按设计稿安全边距换算,例如 `24px` 写为 `6.4vw`,但必须保证小屏不溢出。
|
|
418
|
+
- 如果用户未说明单位偏好,H5 组件默认采用 `375px` 设计稿 + `vw` 换算方案。
|
|
419
|
+
- 生成或修改完成后必须检查源码,H5 视觉尺寸不应大量残留普通 `px`;只允许 `1px` 边框、`max-width`、`min-height: 44px` 等明确例外。
|
|
420
|
+
- 推荐执行父 Skill 脚本校验单位,例如 `node .agents/skills/component-package-workflow-zh/scripts/check_h5_vw_units.mjs 组件包/src`;校验失败时必须先修复普通视觉 `px`,再交付。
|
|
421
|
+
|
|
422
|
+
### 11. 基于截图生成组件
|
|
423
|
+
|
|
424
|
+
当用户提供截图作为参考生成 React 组件时,必须先把截图转化为明确的组件信息,再开始实现。截图是视觉和结构参考,不能替代组件职责、Props 设计、schema 与 H5 适配规则。
|
|
425
|
+
|
|
426
|
+
处理顺序:
|
|
427
|
+
|
|
428
|
+
1. 识别截图中的组件边界:判断截图是完整页面、页面局部模块,还是单个组件;如果截图中包含多个模块,应先确认本次要生成哪一个组件。
|
|
429
|
+
2. 提取视觉结构:识别标题、正文、图片、按钮、标签、列表、价格、状态、角标、图标等元素,并判断上下结构、左右结构、卡片结构、宫格结构、浮层结构等布局关系。
|
|
430
|
+
3. 推导 Props:不把截图里的静态内容硬编码死;将可变内容抽象为 Props,例如 `title`、`description`、`imageUrl`、`items`、`buttonText`、`status`;重复结构优先抽象为数组数据。
|
|
431
|
+
4. 按 H5 设计稿基准实现:默认截图来自 `375px` 移动端设计稿或移动端截图,组件以移动端优先实现,小屏宽度下必须避免横向溢出。
|
|
432
|
+
5. 补齐 `schema.ts` 和 `manifest.json`:`schema.ts` 反映从截图中抽象出的结构化数据;`manifest.json` 说明组件来源于截图参考,并描述适用场景和限制。
|
|
433
|
+
|
|
434
|
+
#### 截图字体还原规则
|
|
435
|
+
|
|
436
|
+
基于截图生成 H5 组件时,必须先完成字体规格提取,再实现样式。字体规格不能凭感觉放大,也不能只通过 `vw` 自动缩放。
|
|
437
|
+
|
|
438
|
+
- 先确认截图对应的 CSS 设计稿宽度;如果用户未说明,默认按 `375px` CSS 画布理解。
|
|
439
|
+
- 不得直接把截图图片像素当作 CSS px。截图原图可能是 `375px`、`750px`、`1125px` 或其他倍图,必须先归一化。
|
|
440
|
+
- 字号归一化公式:`cssFontPx = 截图测得文字像素高度 * 设计稿CSS宽度 / 截图图片实际宽度`。
|
|
441
|
+
- 实现前必须整理文字规格表,至少包含:元素、内容示例、推导字号、字重、行高、备注。
|
|
442
|
+
- 组件样式里的 `font-size` 必须来源于文字规格表;如果无法可靠测量,应使用保守默认值,并在说明中标出推断依据。
|
|
443
|
+
- `font-size` 不允许裸用无边界 `vw()`;默认使用 `fluidFont(px)` 或等价 `clamp(最小px, vw值, 最大px)`。
|
|
444
|
+
- 如果追求截图 1:1 稳定还原,默认使用固定边界:`font-size: ${fluidFont(14)};`,即 `clamp(14px, 3.733vw, 14px)`。
|
|
445
|
+
- 如果需要小屏略缩放、大屏不放大,允许使用窄范围边界:`font-size: ${fluidFont(14, 13, 15)};`。
|
|
446
|
+
- 除非截图测量表或用户明确要求,辅助信息默认 `10-12px`,正文默认 `13-15px`,按钮/标签默认 `12-15px`,模块标题默认 `16-20px`,大标题默认 `20-24px`。
|
|
447
|
+
- 单个组件内字号层级不应过多;通常控制在 3 到 5 档,避免同类文本字号不稳定。
|
|
448
|
+
- 生成后必须在 `375px` 宽度预览下复核文字大小、行高和层级是否接近截图;如果文字明显偏大,优先下调字号和行高,而不是压缩容器或减少间距。
|
|
449
|
+
- 推荐执行父 Skill 脚本校验字体尺寸,例如 `node .agents/skills/component-package-workflow-zh/scripts/check_h5_font_sizes.mjs 组件包/src`;校验失败时必须先修复裸 `vw` 字体或异常大字号,再交付。
|
|
450
|
+
|
|
451
|
+
信息不足且会影响实现时,优先用中文反问:
|
|
452
|
+
|
|
453
|
+
- 截图是要完整生成,还是只生成其中某个模块?
|
|
454
|
+
- 是否需要接近 1:1 还原视觉?
|
|
455
|
+
- 设计稿基准是否为 `375px`?
|
|
456
|
+
- 哪些内容后续需要通过 Props 动态传入,哪些是固定文案?
|
|
457
|
+
- 是否有点击、跳转、展开、轮播、吸底等交互?
|
|
458
|
+
- 是否需要兼容微信 WebView、移动 Safari、Android Chrome 或安全区?
|
|
459
|
+
|
|
460
|
+
如果用户已经明确“照着截图生成一个 H5 组件”,默认按 `375px` 设计稿、移动端优先、结构化 Props、`styled-components`、`schema.ts`/`manifest.json` 同步和截图视觉近似还原执行。
|
|
461
|
+
|
|
462
|
+
### 12. styled-components 约定
|
|
463
|
+
|
|
464
|
+
- 仅用于样式控制、且不应透传到 DOM 的属性,使用 transient props,也就是 `$` 前缀。
|
|
465
|
+
- 避免把样式控制 props 直接挂到原生元素上,造成无效 DOM 属性警告。
|
|
466
|
+
- 对调用方暴露的业务 props 与内部样式 props 可以分层转换。
|
|
467
|
+
- 重复样式片段可通过 `css` 辅助函数抽取。
|
|
468
|
+
- 大量视觉值不要在组件内无序散落,避免重复和难以维护的硬编码。
|
|
469
|
+
|
|
470
|
+
推荐示例:
|
|
471
|
+
|
|
472
|
+
```tsx
|
|
473
|
+
type ButtonRootProps = {
|
|
474
|
+
$variant: "primary" | "secondary";
|
|
475
|
+
$isLoading: boolean;
|
|
476
|
+
};
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
推荐做法:
|
|
480
|
+
|
|
481
|
+
- 外层组件接收 `variant`
|
|
482
|
+
- 内部样式组件接收 `$variant`
|
|
483
|
+
|
|
484
|
+
### 13. 样式逻辑控制
|
|
485
|
+
|
|
486
|
+
- 样式条件分支应尽量收敛,避免一个样式块内嵌太多条件。
|
|
487
|
+
- 多状态组合复杂时,优先提取样式函数或变体映射。
|
|
488
|
+
- 变体优先通过 `variant`、`size` 这类有限集合表达。
|
|
489
|
+
- 不要堆叠大量布尔开关制造不可维护的样式分支。
|
|
490
|
+
|
|
491
|
+
推荐思路:
|
|
492
|
+
|
|
493
|
+
- 用联合类型表达变体
|
|
494
|
+
- 用映射对象统一管理变体样式
|
|
495
|
+
- 用复用片段封装重复状态
|
|
496
|
+
|
|
497
|
+
### 14. 可访问性
|
|
498
|
+
|
|
499
|
+
- 语义优先,按钮用 `button`,链接用 `a`。
|
|
500
|
+
- 不要为了方便套样式就把交互元素写成 `div`。
|
|
501
|
+
- focus 样式不能被无意移除。
|
|
502
|
+
- 表单控件要有标签和可读名称。
|
|
503
|
+
- 禁用态、加载态、错误态要让用户可感知。
|
|
504
|
+
- 交互控件要支持键盘访问和可读名称;不能用无语义元素伪装按钮或链接。
|
|
505
|
+
|
|
506
|
+
### 15. TypeScript 约定
|
|
507
|
+
|
|
508
|
+
- 默认优先 TypeScript。
|
|
509
|
+
- 组件 props、样式 props、主题相关类型要清晰。
|
|
510
|
+
- 样式 prop 类型尽量精确,不要写成模糊字符串。
|
|
511
|
+
- 避免使用 `as any` 掩盖类型问题。
|
|
512
|
+
- 对变体和尺寸优先使用联合类型。
|
|
513
|
+
|
|
514
|
+
## 推荐实现模式
|
|
515
|
+
|
|
516
|
+
推荐把业务组件 props 与内部样式 props 分层:
|
|
517
|
+
|
|
518
|
+
```tsx
|
|
519
|
+
type ButtonProps = {
|
|
520
|
+
variant?: "primary" | "secondary";
|
|
521
|
+
isLoading?: boolean;
|
|
522
|
+
children: React.ReactNode;
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
type ButtonRootProps = {
|
|
526
|
+
$variant: "primary" | "secondary";
|
|
527
|
+
$isLoading: boolean;
|
|
528
|
+
};
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
这样可以避免 DOM 污染,同时让样式层表达更明确。
|
|
532
|
+
|
|
533
|
+
## 组件落地清单
|
|
534
|
+
|
|
535
|
+
当任务是“新增一个正式组件”时,默认按下面清单检查是否交付完整:
|
|
536
|
+
|
|
537
|
+
- 是否直接在 `src` 目录下创建了组件主文件、样式文件、schema
|
|
538
|
+
- 是否包含 `index.ts`
|
|
539
|
+
- 是否在 `index.ts` 中以默认导出方式暴露组件
|
|
540
|
+
- 是否包含 `ComponentName.tsx`
|
|
541
|
+
- 是否包含 `ComponentName.styles.ts`
|
|
542
|
+
- 是否仅在有明确必要时才新增 `types.ts`、`hooks.ts`、`utils.ts`、`constants.ts`
|
|
543
|
+
- 是否按 H5 移动端优先和 `375px` 设计稿基准处理布局与尺寸
|
|
544
|
+
- H5 视觉尺寸源码是否实际使用 `vw` 换算,而不是仍然大量写死普通 `px`
|
|
545
|
+
- H5 字体尺寸是否使用 `fluidFont()` 或等价 `clamp()`,避免裸 `vw` 字号在宽屏下放大
|
|
546
|
+
- 是否在 `320px`、`375px`、`390px`、`414px`、`430px`、`768px`、`1024px` 等宽度下布局可用
|
|
547
|
+
- 是否避免移动端横向滚动、固定大宽度、固定高度裁切和长文本溢出
|
|
548
|
+
- 是否保证按钮、链接等触控区域不小于 `44px`
|
|
549
|
+
- 是否避免 hover-only 交互
|
|
550
|
+
- 如果基于截图生成,是否把截图内容抽象为 Props、schema 与 manifest 信息,而不是硬编码静态页面
|
|
551
|
+
- 如果基于截图生成,是否先整理文字规格表,并按截图宽度归一化字号、字重和行高
|
|
552
|
+
|
|
553
|
+
如果最终没有采用这套目录结构,应明确说明原因,例如“这是一次性私有子组件”或“当前项目已有统一且不冲突的组件组织方式”。
|
|
554
|
+
|
|
555
|
+
## Review 清单
|
|
556
|
+
|
|
557
|
+
评审时优先检查:
|
|
558
|
+
|
|
559
|
+
- 组件职责是否单一
|
|
560
|
+
- Props API 是否清晰
|
|
561
|
+
- 业务 props 与内部样式 props 是否边界清晰
|
|
562
|
+
- 交互状态归属是否明确,受控/非受控 Props 是否一致
|
|
563
|
+
- 业务动作是否通过 `onXxx` 回调暴露,而不是在组件内部写死
|
|
564
|
+
- 是否正确使用 transient props
|
|
565
|
+
- 是否存在冗余 state
|
|
566
|
+
- 是否滥用 `useEffect`
|
|
567
|
+
- JSX 是否清晰
|
|
568
|
+
- 可访问性是否达标
|
|
569
|
+
- H5 移动端是否可用,是否符合 `375px` 设计稿基准
|
|
570
|
+
- H5 视觉尺寸是否实际落成 `vw`,普通 `px` 是否仅用于允许的例外
|
|
571
|
+
- H5 字体是否有明确边界,`font-size` 是否避免裸用无上限 `vw`
|
|
572
|
+
- 是否存在无约束固定宽度、内容溢出、横向滚动或移动端不可点击问题
|
|
573
|
+
- 截图参考生成时,Props、schema、manifest 是否与截图抽象出的动态内容一致
|
|
574
|
+
- 截图参考生成时,字号是否来自文字规格表,是否避免超过截图实测或默认字号范围
|
|
575
|
+
|
|
576
|
+
## 明确禁止的反模式
|
|
577
|
+
|
|
578
|
+
- 使用 `any` 掩盖类型问题
|
|
579
|
+
- 在受本 Skill 约束的组件里继续使用 `styled-components` 之外的样式方案作为最终实现
|
|
580
|
+
- 直接把样式控制 props 透传到 DOM
|
|
581
|
+
- 用 effect 驱动本可直接推导的视觉变化
|
|
582
|
+
- 在组件内部写死跳转、接口请求、埋点等业务动作
|
|
583
|
+
- 同一个交互状态同时由内部 state 和外部 props 抢控制权
|
|
584
|
+
- 用非语义元素伪装交互控件且缺少键盘与可访问性支持
|
|
585
|
+
- 大量硬编码颜色、间距、字号
|
|
586
|
+
- 把 `375px` 设计稿尺寸无约束地照搬成固定 `px`,导致小屏溢出
|
|
587
|
+
- 口头声明使用 `vw`,但源码中的字体、间距、宽高、圆角等视觉尺寸仍大量使用普通 `px`
|
|
588
|
+
- 为移动端适配向外暴露 `isMobile`、`screenType` 等纯样式实现 props
|
|
589
|
+
- 依赖 hover 展示核心内容或核心操作
|
|
590
|
+
- 基于截图生成时只硬编码静态页面,不抽象可变数据和 Props
|
|
591
|
+
- 一个样式块塞满不可维护的条件判断
|
|
592
|
+
- 用多个布尔值堆出复杂变体系统
|
|
593
|
+
- 用无语义 `div` 承担按钮行为
|
|
594
|
+
- 只因“看起来能复用”就过度抽象
|
|
595
|
+
|
|
596
|
+
## 输出风格要求
|
|
597
|
+
|
|
598
|
+
- 所有规范说明、代码解释、review 反馈使用中文。
|
|
599
|
+
- 输出的 React 组件必须遵循本 Skill;若无额外说明,样式实现必须使用 `styled-components`,且缺依赖时先安装再实现。
|
|
600
|
+
- 如果项目已有既有规范,优先贴合不与本 Skill 冲突的部分;凡与 `styled-components` 强制要求冲突时,以本 Skill 为准。
|
|
601
|
+
- 当用户需求与规范冲突时,先满足需求,同时指出偏离点和潜在代价。
|