@lark-apaas/coding-steering 0.1.17 → 0.1.18-dev.2bb478f
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 +19 -21
- package/package.json +6 -6
- package/steering/design-html/skills/animated-video/SKILL.md +6 -4
- package/steering/design-html/skills/charts/SKILL.md +53 -10
- package/steering/design-html/skills/{data-report → data-viz}/SKILL.md +69 -11
- package/steering/design-html/skills/frontend-design/SKILL.md +36 -34
- package/steering/design-html/skills/hi-fi-design/SKILL.md +4 -2
- package/steering/design-html/skills/interactive-prototype/SKILL.md +39 -4
- package/steering/design-html/skills/mini-game/SKILL.md +71 -0
- package/steering/design-html/skills/mini-game/references/three-js.md +54 -0
- package/steering/design-html/skills/preflight/SKILL.md +51 -0
- package/steering/design-html/skills/preflight/scripts/probe.sh +108 -0
- package/steering/design-html/skills/slide-deck/SKILL.md +165 -0
- package/steering/design-html/skills/{visual-exposure → visual-report}/SKILL.md +30 -6
- package/steering/design-html/skills/wireframe/SKILL.md +7 -5
- package/steering/nestjs-react-fullstack/skills_common/trigger-guide/SKILL.md +180 -0
- package/steering/nestjs-react-fullstack/{skills/trigger-guide/SKILL.md → skills_common/trigger-guide/references/trigger-lifecycle.md} +11 -162
- package/steering/design-html/skills/make-a-deck/SKILL.md +0 -125
package/README.md
CHANGED
|
@@ -2,23 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
Stack-specific steering content for [miaoda coding](https://code.byted.org/apaas/miaoda-coding) templates.
|
|
4
4
|
|
|
5
|
-
Consumed by [miaoda-cli](https://code.byted.org/apaas/miaoda-cli)
|
|
5
|
+
Consumed by [miaoda-cli](https://code.byted.org/apaas/miaoda-cli) during `miaoda skills sync` (including `app init`). It is **not a runtime dependency** — no entry in the user project's `package.json`.
|
|
6
6
|
|
|
7
7
|
## Layout
|
|
8
8
|
|
|
9
9
|
```
|
|
10
10
|
steering/
|
|
11
|
-
├── _common/
|
|
12
|
-
│ └── skills/ # cross-stack shared skills
|
|
13
11
|
├── <stack>/
|
|
14
|
-
│ ├── tech.md #
|
|
15
|
-
│ ├──
|
|
16
|
-
│
|
|
17
|
-
│
|
|
12
|
+
│ ├── tech.md # optional, stack overview
|
|
13
|
+
│ ├── skills_common/<id>/SKILL.md # both local and sandbox; copied first
|
|
14
|
+
│ ├── skills/<id>/SKILL.md # sandbox-only; copied after common
|
|
15
|
+
│ └── skills_local/<id>/SKILL.md # local-only; copied after common
|
|
18
16
|
└── ...
|
|
19
17
|
```
|
|
20
18
|
|
|
21
|
-
Top-level directory names
|
|
19
|
+
Top-level directory names are stack IDs — discovery is by directory convention, with no central manifest.
|
|
22
20
|
|
|
23
21
|
## Supported stacks
|
|
24
22
|
|
|
@@ -31,7 +29,7 @@ vice versa). Current state:
|
|
|
31
29
|
| `vite-react` | React + Vite SPA | ✅ | `plugin-guide`, `react-three-fiber` | [`coding-template-vite-react`](../../templates/vite-react) |
|
|
32
30
|
| `html` | 妙搭 html,带 devserver | ✅ | `rich-interactive-design` | [`coding-template-html`](../../templates/html) |
|
|
33
31
|
| `nestjs-react-fullstack` | NestJS + React 全栈 | — | `authn`/`authz`/`feishu`/`plugin`/`devops`/`trigger`/`user-*` … + `skills_local/` (`code-fix`, `coding-guide`) | [`coding-template-nestjs-react-fullstack`](../../templates/nestjs-react-fullstack) |
|
|
34
|
-
| `design-html` | **无构建**纯静态 HTML
|
|
32
|
+
| `design-html` | **无构建**纯静态 HTML 托管(源码即产物) | — | _(占位,待补)_ | [`coding-template-design-html`](../../templates/design-html) |
|
|
35
33
|
| `design-stack` | **带构建**的 design / 创意栈(有工具链,区别于 buildless 的 `design-html`) | — | _(占位,待补)_ | _(暂无)_ |
|
|
36
34
|
|
|
37
35
|
`design-html` 与 `design-stack` 是两个**有意分开**的 design 栈:前者无构建、纯静态托管;
|
|
@@ -41,20 +39,20 @@ vice versa). Current state:
|
|
|
41
39
|
|
|
42
40
|
## Sync mapping (executed by miaoda-cli)
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
|---|---|
|
|
46
|
-
| `steering/<stack>/tech.md` | `.agent/steering/tech.md` |
|
|
47
|
-
| `steering/<stack>/skills/<id>/**` | `.agent/steering/skills/<id>/**` |
|
|
48
|
-
| `steering/<stack>/skills_local/<id>/**` | `.agent/steering/skills/<id>/**` (local-dev sync only) |
|
|
49
|
-
| `steering/_common/skills/<id>/**` | `.agent/steering/skills/<id>/**` |
|
|
42
|
+
`MIAODA_DEP_CACHE_DIR` selects the source mode; `--local` selects only the output layout. Do not use a sandbox environment plus `--local` as evidence for either supported flow.
|
|
50
43
|
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
| Source in this package | Local output (`MIAODA_DEP_CACHE_DIR` empty + `--local`) | Sandbox output (`MIAODA_DEP_CACHE_DIR` non-empty, no `--local`) |
|
|
45
|
+
| ---------------------------------------- | ------------------------------------------------------- | --------------------------------------------------------------- |
|
|
46
|
+
| `steering/<stack>/skills_common/<id>/**` | `.agents/skills/<id>/**` | `.agent/skills/steering/<stack>/skills/<id>/**` |
|
|
47
|
+
| `steering/<stack>/skills_local/<id>/**` | Same local path, copied after common. | Not copied. |
|
|
48
|
+
| `steering/<stack>/skills/<id>/**` | Not copied. | Same sandbox path, copied after common. |
|
|
53
49
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
50
|
+
For a duplicated skill ID, the copy order is:
|
|
51
|
+
|
|
52
|
+
- Local: `skills_common → skills_local`; the local variant wins.
|
|
53
|
+
- Sandbox: `skills_common → skills`; the sandbox variant wins.
|
|
54
|
+
|
|
55
|
+
Put a guide in `skills_common/<id>/SKILL.md` when it must reach both supported modes. Keep a same-name `skills/` or `skills_local/` copy only when a deliberate mode-specific override is required.
|
|
58
56
|
|
|
59
57
|
## Writing rules
|
|
60
58
|
|
package/package.json
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lark-apaas/coding-steering",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18-dev.2bb478f",
|
|
4
4
|
"description": "Stack-specific steering content for miaoda-coding templates",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"steering"
|
|
8
8
|
],
|
|
9
|
-
"scripts": {
|
|
10
|
-
"lint:md": "markdownlint 'steering/**/*.md' --ignore 'steering/**/skills/**' --ignore 'steering/**/skills_common/**' --ignore 'steering/**/skills_local/**'"
|
|
11
|
-
},
|
|
12
9
|
"devDependencies": {
|
|
13
10
|
"markdownlint-cli": "^0.47.0"
|
|
14
11
|
},
|
|
@@ -20,5 +17,8 @@
|
|
|
20
17
|
"miaoda",
|
|
21
18
|
"coding-steering"
|
|
22
19
|
],
|
|
23
|
-
"license": "MIT"
|
|
24
|
-
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"lint:md": "markdownlint 'steering/**/*.md' --ignore 'steering/**/skills/**' --ignore 'steering/**/skills_common/**' --ignore 'steering/**/skills_local/**'"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: animated-video
|
|
3
3
|
description: Use when creating animated videos, motion graphics, product walkthroughs, or visual storytelling with timeline-based playback. 触发词:animation, video, motion, 动画, 视频, 动效, 产品演示, 演示动画, walkthrough
|
|
4
|
-
|
|
5
|
-
-
|
|
4
|
+
metadata:
|
|
5
|
+
display-names:
|
|
6
|
+
zh-CN: 动画视频
|
|
7
|
+
en-US: Animated Video
|
|
6
8
|
---
|
|
7
9
|
|
|
8
10
|
# Animated video
|
|
9
11
|
|
|
10
|
-
Create an animated video or motion design piece rendered as an HTML page. Build a timeline-based animation with smooth transitions. Design frame-by-frame sequences with playback controls (play/pause, scrubber). Focus on visual storytelling
|
|
12
|
+
Create an animated video or motion design piece rendered as an HTML page. Build a timeline-based animation with smooth transitions. Design frame-by-frame sequences with playback controls (play/pause, scrubber). Focus on visual storytelling. Export-ready at a fixed aspect ratio (16:9 or 9:16). If you need to know the position of an element (eg to move a cursor or character between elements) use refs to grab the position.
|
|
11
13
|
|
|
12
14
|
START by calling `copy_starter_component` with `kind: "animations.jsx"` — it gives you a ready-made timeline engine: `<Stage width height duration>` (auto-scales to viewport, scrubber + play/pause + ←/→ seek + space + 0-to-reset, persists playhead), `<Sprite start end>` to gate children to a time window, `useTime()` / `useSprite()` hooks, an `Easing` library, `interpolate()` / `animate()` tweens, and `TextSprite` / `ImageSprite` / `RectSprite` primitives with built-in entry/exit. Read the file after copying and build YOUR scenes by composing Sprites inside a Stage; only fall back to Popmotion (https://sf3-scmcdn-cn.feishucdn.com/obj/feishu-static/miaoda/coding-unpkg-sdk/popmotion@11.0.5/dist/popmotion.min.js) if the starter genuinely can't do what you need.
|
|
13
15
|
|
|
14
|
-
Animations are complex code! Make reusable JSX components for each visual element and each scene.
|
|
16
|
+
Animations are complex code! Make reusable JSX components for each visual element and each scene. Every moment gets ONE definition; sprite-local times and offsets derive from it, never stored separately. The failure: `cardSelectStart = 1.2` inside a scene while the cursor holds `{ t: 9.2 }` for the same beat. Timing shared with nothing else — entry stagger, easing durations — stays local.
|
|
15
17
|
|
|
16
18
|
Animation tips:
|
|
17
19
|
- Storytelling is KEY! Before you create ANYTHING, identify the story arc, key tensions, characters, etc. Align on the message you want to convey. Run it by the user.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: charts
|
|
3
3
|
description: "基于 ECharts 的数据可视化,用于浏览器直出 HTML。当需要创建图表、仪表盘或数据可视化时使用。触发词:chart, ECharts, 图表, 可视化, visualization, 饼图, 柱状图, 折线图, 数据图表, 甘特图, 热力图, 数据展示, dashboard, 仪表盘, 数据看板"
|
|
4
|
-
|
|
5
|
-
-
|
|
4
|
+
metadata:
|
|
5
|
+
display-names:
|
|
6
|
+
zh-CN: 图表
|
|
7
|
+
en-US: Charts
|
|
6
8
|
---
|
|
7
9
|
|
|
8
10
|
# 图表
|
|
@@ -46,7 +48,7 @@ available-agents:
|
|
|
46
48
|
|
|
47
49
|
5. **编写 ECharts 代码。** 挂载模式和 API 约束见下方技术参考。
|
|
48
50
|
|
|
49
|
-
6. **自检。**
|
|
51
|
+
6. **自检。** 按文末清单逐项检查你写出的 option 代码(源码级自查,不用打开浏览器截图)。然后回到视觉编码步骤:这套配置渲染出来的图表是否真的表达了你想表达的信息?颜色编码与仪表盘其他部分是否一致?
|
|
50
52
|
|
|
51
53
|
## 图表类型映射
|
|
52
54
|
|
|
@@ -75,6 +77,44 @@ available-agents:
|
|
|
75
77
|
- **表达覆盖**:把用户需求拆成需要被回答的信息关系;每个被承诺的关系都要有对应的图表、表格、矩阵或文字证据承载。不要用少量通用指标和默认图表替代所有分析任务。
|
|
76
78
|
- **小容器防崩**:小尺寸图表优先用 bar / line / number strip。饼图、雷达图、词云和外部标签很容易挤压重叠;空间不足时换图表类型,而不是缩小到不可读。
|
|
77
79
|
|
|
80
|
+
## 窄屏适配
|
|
81
|
+
|
|
82
|
+
图表出现在报表或看板中时,移动端(≤768px)的容器宽度可能压到 300px 以下。盲目把桌面端图表原样塞进窄容器,会导致 axis label 堆叠、legend 遮盖绘图区、饼图标签溢出。以下是在窄屏容器中保证可读性的规则:
|
|
83
|
+
|
|
84
|
+
### 布局容器
|
|
85
|
+
|
|
86
|
+
报表中承载图表的网格必须在窄屏时折叠为单列。写多列网格时,用 `auto-fit` + `minmax()` 让浏览器自动折叠,或配合 `@media` 断点显式切换:
|
|
87
|
+
|
|
88
|
+
```css
|
|
89
|
+
/* 自动折叠:每列最小 320px,不够就换行 */
|
|
90
|
+
.chart-grid {
|
|
91
|
+
display: grid;
|
|
92
|
+
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
|
93
|
+
gap: 16px;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* 或显式断点 */
|
|
97
|
+
@media (max-width: 768px) {
|
|
98
|
+
.chart-grid { grid-template-columns: 1fr; }
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
不要写死 `grid-template-columns: 1.2fr 2fr` 而不提供窄屏回退——390px 视口下,1.2fr 只有 146px,放不下任何图表。
|
|
103
|
+
|
|
104
|
+
### ECharts option 适配
|
|
105
|
+
|
|
106
|
+
在窄容器(宽度 <400px)中调整 ECharts option:
|
|
107
|
+
|
|
108
|
+
- **legend**:改为 `orient: 'horizontal'` + `type: 'scroll'`,放在图表底部(`bottom: 0`),不要放在侧面挤占绘图区。
|
|
109
|
+
- **grid**:增大 `left` / `right` 留白到 `'12%'` 以上,防止 axis label 被裁切。
|
|
110
|
+
- **x 轴 label**:长文本加 `axisLabel: { rotate: 30, interval: 0 }` 或截断 formatter;分类超过 8 个时用 `interval: 'auto'` 让 ECharts 自动跳标签。
|
|
111
|
+
- **tooltip**:窄屏下 tooltip 容易超出视口,设 `confine: true`。
|
|
112
|
+
- **图表类型降级**:桌面端的并排双图在移动端改为上下堆叠;桌面端的 Pie 在容器宽度 <250px 时考虑改为横向 Bar。
|
|
113
|
+
|
|
114
|
+
### 容器尺寸监听
|
|
115
|
+
|
|
116
|
+
用 `ResizeObserver` 而非 `window.resize` 监听图表容器(见下方「技术参考 · 挂载」的封装代码)。当网格从双列折叠为单列时,window 尺寸不变但容器变宽,`resize` 事件不触发,图表不会重绘。
|
|
117
|
+
|
|
78
118
|
## 技术参考
|
|
79
119
|
|
|
80
120
|
### 加载 ECharts
|
|
@@ -92,23 +132,24 @@ available-agents:
|
|
|
92
132
|
<script>
|
|
93
133
|
const chart = echarts.init(document.getElementById('chart'));
|
|
94
134
|
chart.setOption({ /* ... */ });
|
|
95
|
-
|
|
135
|
+
new ResizeObserver(() => chart.resize()).observe(document.getElementById('chart'));
|
|
96
136
|
</script>
|
|
97
137
|
```
|
|
98
138
|
|
|
99
139
|
### 挂载——React 封装
|
|
100
140
|
|
|
101
|
-
定义一次,复用。**不要**添加 echarts-for-react
|
|
141
|
+
定义一次,复用。**不要**添加 echarts-for-react。用 `ResizeObserver` 而非 `window.resize` 监听容器尺寸变化(见「窄屏适配」说明)。
|
|
102
142
|
|
|
103
143
|
```jsx
|
|
104
144
|
function EChart({ option, style }) {
|
|
105
145
|
const ref = React.useRef(null);
|
|
106
146
|
React.useEffect(() => {
|
|
107
|
-
const
|
|
147
|
+
const el = ref.current;
|
|
148
|
+
const chart = echarts.init(el);
|
|
108
149
|
chart.setOption(option);
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
return () => {
|
|
150
|
+
const ro = new ResizeObserver(() => chart.resize());
|
|
151
|
+
ro.observe(el);
|
|
152
|
+
return () => { ro.disconnect(); chart.dispose(); };
|
|
112
153
|
}, [option]);
|
|
113
154
|
return <div ref={ref} style={{ width: '100%', minHeight: 300, ...style }} />;
|
|
114
155
|
}
|
|
@@ -139,7 +180,7 @@ Object.assign(window, { EChart });
|
|
|
139
180
|
| 6 | Funnel label 被隐藏或位置不在内部 | `label: { show: true, position: 'inside' }` |
|
|
140
181
|
| 7 | 容器高度 <300px | `min-height: 300px` |
|
|
141
182
|
| 8 | 单张图表中分类色(每项一个色相)>8 种 | 聚合或分组 |
|
|
142
|
-
| 9 | Pie
|
|
183
|
+
| 9 | Pie / 环形图的分类或数值只能靠 tooltip 读到——用了外部引导线标签(`position` 为 `'outside'` 或缺失),或干脆 `label: { show: false }` 且既无图例也无中心标注 | 分类 + 数值必须**静态可读**(tooltip 不算,图表常被导出 / 截图当静态图看)。任选其一:inside 标签标注 `name` + 百分比(扇区够大时)、图例映射色 → 分类、或环形图中心标注关键数值。禁止外部引导线标签(`position: 'outside'` 易重叠 / 裁切),也禁止只靠 tooltip 承载分类 / 数值 |
|
|
143
184
|
| 10 | Pie 设置了 `itemStyle` | 完全移除 |
|
|
144
185
|
| 11 | 任何 series 设置了 `label.color` | 禁止设置;由 theme 控制 |
|
|
145
186
|
| 12 | `label.formatter` 使用字符串模板 | 改用回调:`formatter: (params) => ...` |
|
|
@@ -150,6 +191,8 @@ Object.assign(window, { EChart });
|
|
|
150
191
|
| 17 | 双 Y 轴零点未对齐 | 匹配 `\|min\| / max` 比例 |
|
|
151
192
|
| 18 | 图表 series 或容器使用阴影/发光效果 | 移除 `shadowBlur`、`shadowColor`、容器 `box-shadow`,改用线宽、透明度、注释或面积大小表达层级 |
|
|
152
193
|
| 19 | 图表或标签挤压、重叠、被容器裁切 | 增大容器、减少标签、改用 tooltip / inside label,或换成更稳的图表类型 |
|
|
194
|
+
| 20 | 图表容器的父级网格在窄屏(≤768px)下没有折叠为单列 | 用 `auto-fit + minmax(320px, 1fr)` 或 `@media` 断点,保证每个图表容器至少 320px 宽 |
|
|
195
|
+
| 21 | 使用 `window.addEventListener('resize', ...)` 监听图表尺寸 | 改用 `ResizeObserver`——网格列折叠时 window 尺寸不变但容器变宽,`resize` 事件不触发 |
|
|
153
196
|
|
|
154
197
|
### 不建议
|
|
155
198
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: data-
|
|
3
|
-
description: "
|
|
4
|
-
|
|
5
|
-
-
|
|
2
|
+
name: data-viz
|
|
3
|
+
description: "数据可视化设计。从数据分析到版面规划、信息层级组织,适用于用户有数据文件或明确指标,需要产出结构化报表、看板或可视化页面的场景。图表绘制部分由 charts skill 承担。触发词:数据可视化, 数据报表, 数据看板, 数据分析报表, BI, 经营报表, 指标看板, 周报, 月报, 数据大盘, KPI, 报表设计, data visualization, data report, dashboard report, analytics report"
|
|
4
|
+
metadata:
|
|
5
|
+
display-names:
|
|
6
|
+
zh-CN: 数据可视化
|
|
7
|
+
en-US: Data Visualization
|
|
6
8
|
---
|
|
7
9
|
|
|
8
|
-
#
|
|
10
|
+
# 数据可视化
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
你是数据可视化设计者。你的工作是把原始数据变成一份读者能直接用来做判断的可视化页面——不只是画几张图,而是回答"这份数据在说什么、读者应该关注什么"。
|
|
11
13
|
|
|
12
14
|
报表的价值不在图表数量,而在信息层级:读者能在 5 秒内抓到主要结论,30 秒内理解支撑证据,需要时能下钻到明细。
|
|
13
15
|
|
|
@@ -17,7 +19,9 @@ available-agents:
|
|
|
17
19
|
|
|
18
20
|
布局必须比普通上下堆叠更丰富。先根据数据任务选择版式骨架,再写代码:监控型、复盘型、诊断型、对比型、明细型、汇报型可以有完全不同的扫描路径。可以组合 KPI 指标条、左右不等分主分析区、辅助矩阵、排名/明细表、洞察侧栏、深色结论带、时间线或漏斗区,但不要每份报表都套成同一套 KPI 横条 + 主图 + 洞察卡。不要把每个章节都做成同宽标题加一张满宽卡片;核心模块占更大面积,支撑模块用不同宽度、密度和位置服务它。
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
报表不是产品原型。内容型或分析型交付服务阅读和决策,不默认生成多页面后台导航、可下拉应用名、无意义返回按钮或设置菜单。标题、范围、口径、结论、图表、洞察和明细都是可用的信息部件,不是每份报表都必须同时出现的固定章节。
|
|
23
|
+
|
|
24
|
+
看板中的筛选器、标签页切换(如"今日/近7天/近30天"、"库存量/库存金额"、"30天/90天")、下拉选择等控件如果出现在页面上,必须用 JavaScript 实现真实的切换逻辑——点击后切换数据视图、过滤图表或改变显示内容。不实现功能的控件不得使用 `<button>`、`cursor:pointer` 或 active/hover 样式暗示可点击;纯标注用 `<span>` 或静态文字呈现。
|
|
21
25
|
|
|
22
26
|
不要让页面全是文字,也不要把所有章节都做成同一种"结论 + 指标 + 图表 + 洞察"结构。长材料先判断每段内容在当前报表里的作用:它是在给背景、定义口径、证明结论、展示变化、比较对象、解释异常、列明细,还是提出行动。每段只选择最适合的表达方式,可以是短结论、关键数字、对比、时间顺序、表格、矩阵、引用、图表、注释或截图。重要内容不能被塞进附录或角落;如果一个章节是汇报目标的核心,就给它相称的版面面积和区别于其他章节的版式处理。
|
|
23
27
|
|
|
@@ -48,16 +52,23 @@ available-agents:
|
|
|
48
52
|
|
|
49
53
|
产出:维度-指标清单,以及一句话叙事重点。
|
|
50
54
|
|
|
55
|
+
**数据忠实度约束。** 在此步完成后,明确标注哪些指标可以直接从源数据计算、哪些缺少必要数据(如历史期、目标值、预算基线)。后续步骤中:
|
|
56
|
+
|
|
57
|
+
- 可直接计算的指标:使用真实值。
|
|
58
|
+
- 源数据不含的派生指标(同比/环比变化率、完成率、差额等需要两期或多源数据而只有单期的):不编造数值,用"—"占位或省略该指标。
|
|
59
|
+
- 超出数据时间范围的外推值:不补齐,图表只覆盖数据实际跨度。
|
|
60
|
+
- 确需补充示例数据时:必须在页面上用视觉标记(虚线边框、"示例数据"标签、灰色斜体)明确区分。
|
|
61
|
+
|
|
51
62
|
### 3. 报表规划
|
|
52
63
|
|
|
53
64
|
在写代码之前,先确定报表由哪些组件构成:
|
|
54
65
|
|
|
55
|
-
- **视觉方向**:参考 `frontend-design`
|
|
66
|
+
- **视觉方向**:参考 `frontend-design` 的方法先定主题世界、受众姿态、材料、配色逻辑和签名元素。例如环境数据可以像研究观测页,销售经营可以像运营战情室,财务/管理指标可以像管理层简报。风格必须服务数据可信度,不要套通用科技蓝或泛白卡。
|
|
56
67
|
- **阅读路径**:先判断读者是要快速扫现状、追异常、看趋势、比较对象、查明细还是读复盘。不同任务对应不同起手式,不要默认都从 KPI 卡开始。
|
|
57
68
|
- **候选部件**:标题 / 范围 / 口径、摘要、KPI、主图表、辅助图表、文字洞察、明细表、时间线、矩阵、截图或注释都只是候选。需要哪个用哪个,不要为了"完整"把它们凑齐。
|
|
58
69
|
- **核心承载**:只给真正承载核心问题的模块更大面积。核心可能是一张趋势图、一张排名表、一段异常解释、一个流程漏斗,也可能是一组明细,不固定。
|
|
59
70
|
- **版式差异**:为不同信息角色安排不同形态,例如紧凑指标条、宽图、窄侧栏、表格区、注释带、对比矩阵或分段背景。避免每个章节都重复同一张满宽白卡。
|
|
60
|
-
- **布局骨架**:明确每个模块的相对面积和扫描路径,例如 `1.2fr 2fr`、`1fr 1.6fr`、`repeat(4,1fr)`、`auto 1fr`
|
|
71
|
+
- **布局骨架**:明确每个模块的相对面积和扫描路径,例如 `1.2fr 2fr`、`1fr 1.6fr`、`repeat(4,1fr)`、`auto 1fr` 等混合栅格。多列网格必须提供窄屏回退(`auto-fit + minmax()` 或 `@media` 断点),不要写死 fr 比例而不处理移动端——详见下方「移动端适配」。
|
|
61
72
|
|
|
62
73
|
组件取舍由读者任务、数据复杂度和材料内容决定。
|
|
63
74
|
|
|
@@ -76,18 +87,59 @@ available-agents:
|
|
|
76
87
|
- 布局按数据叙事组织,不按"先放所有图再放文字"组织。
|
|
77
88
|
- 顺序跟随读者任务:监控型可以先给状态概览,诊断型可以先给异常和原因链,对比型可以先给对象矩阵,复盘型可以先给时间线,明细型可以先给可查表格。
|
|
78
89
|
- 同一页面内至少使用两种不同的版式关系:例如 KPI 横条 + 左右不等分主图 + 双列洞察 + 表格/结论带。避免所有模块都是同尺寸白卡片上下排列。
|
|
79
|
-
- 内容块采用平面化处理:优先用 `border:1px solid
|
|
90
|
+
- 内容块采用平面化处理:优先用 `border:1px solid ...`、浅底色、分隔线、色条(仅当颜色编码真实分类 / 状态)、编号、标签和表格行背景;内容卡片和图表容器默认不加 `box-shadow`。
|
|
80
91
|
- 图表旁边应有短洞察、口径或排名摘要,不要让图表孤零零占满整行。
|
|
81
92
|
- 文字用于解释图表看不出的原因、口径、异常和行动建议,不重复图表标题。
|
|
82
93
|
- 表格用于精确查数和比较对象,不要把长表伪装成密集柱状图。
|
|
83
94
|
- KPI 用于概览,不要把每个字段都做成指标卡。
|
|
84
95
|
- 没有真实依据时不编造结论;可写"待补充口径"或使用中性描述。
|
|
96
|
+
- 页面中每个数值必须可溯源:源数据直读、或从源数据可验证计算得出。缺少计算所需数据时(如同比需要上期数据但只有本期),用"—"占位或省略,不编造。
|
|
97
|
+
- 所有视觉上暗示可交互的控件(标签页、筛选器、按钮、下拉、日期切换)必须绑定真实 JS 逻辑。不实现切换功能就不画成可点击样式。
|
|
85
98
|
|
|
86
99
|
产出:完整报表页面。
|
|
87
100
|
|
|
101
|
+
### 5.5 移动端适配
|
|
102
|
+
|
|
103
|
+
报表在桌面端的复杂网格不会自动适配移动端。写完桌面布局后,必须为 ≤768px 视口补充响应式处理:
|
|
104
|
+
|
|
105
|
+
**页面基础**:HTML 必须包含 `<meta name="viewport" content="width=device-width, initial-scale=1">`,否则移动浏览器用 980px 默认视口渲染再缩小,所有字都变成蚊子大小。
|
|
106
|
+
|
|
107
|
+
**模块折叠策略**:
|
|
108
|
+
|
|
109
|
+
- **KPI 指标条**:桌面端横排 4 个时,移动端折叠为 2×2 网格。用 `repeat(auto-fit, minmax(160px, 1fr))` 自动处理,或 `@media (max-width: 768px)` 显式切到两列。
|
|
110
|
+
- **主分析区(左右不等分)**:`1.2fr 2fr` 或 `auto 1fr` 这类侧栏 + 主区布局,移动端必须折叠为单列——侧栏内容移到主区上方或下方。
|
|
111
|
+
- **并列图表**:两图并排在移动端改为上下堆叠,每个图表独占一行。图表容器的窄屏处理由 charts skill 的「窄屏适配」规则覆盖。
|
|
112
|
+
- **明细表格**:宽表在窄屏下加 `overflow-x: auto` 让表格可横向滚动,不要压缩列宽到不可读。
|
|
113
|
+
- **洞察侧栏 / 注释带**:移动端折叠到对应图表下方,不要浮动遮盖内容。
|
|
114
|
+
|
|
115
|
+
**断点写法**(二选一):
|
|
116
|
+
|
|
117
|
+
```css
|
|
118
|
+
/* 方式 A:auto-fit 自动折叠 */
|
|
119
|
+
.report-grid {
|
|
120
|
+
display: grid;
|
|
121
|
+
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
|
122
|
+
gap: 16px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* 方式 B:显式断点 */
|
|
126
|
+
.report-layout {
|
|
127
|
+
display: grid;
|
|
128
|
+
grid-template-columns: 1.2fr 2fr;
|
|
129
|
+
gap: 24px;
|
|
130
|
+
}
|
|
131
|
+
@media (max-width: 768px) {
|
|
132
|
+
.report-layout {
|
|
133
|
+
grid-template-columns: 1fr;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**字号底线**:移动端正文不低于 14px,KPI 数字不低于 20px,图表标题不低于 13px。
|
|
139
|
+
|
|
88
140
|
### 6. 自检
|
|
89
141
|
|
|
90
|
-
|
|
142
|
+
读一遍自己写出的代码(源码级自查),逐项验证以下几点:
|
|
91
143
|
|
|
92
144
|
- 报表是否回答了步骤 1 确定的核心问题。
|
|
93
145
|
- 信息层级是否清晰(读者能在 5 秒内抓到主要结论)。
|
|
@@ -99,5 +151,11 @@ available-agents:
|
|
|
99
151
|
- 文字洞察是否与图表数据互相支撑。
|
|
100
152
|
- 图表部分是否通过了 charts skill 的自检清单。
|
|
101
153
|
- 口径和单位是否全报表一致。
|
|
154
|
+
- 页面中展示的每个数值是否可溯源到用户提供的数据;同比/环比/完成率等派生指标是否有对应的基准数据支撑,没有的是否已用"—"占位而非编造。
|
|
155
|
+
- 所有视觉上可点击的控件(标签页、筛选器、按钮、下拉)是否都绑定了真实 JS 逻辑,点击后确实切换数据或视图;没有功能的元素是否已改为静态文字样式。
|
|
156
|
+
- HTML 是否包含 `<meta name="viewport" content="width=device-width, initial-scale=1">`。
|
|
157
|
+
- 多列网格是否提供了窄屏回退(`auto-fit + minmax()` 或 `@media` 断点),在 390px 视口下是否折叠为单列且无横向滚动。
|
|
158
|
+
- 宽表格是否有 `overflow-x: auto` 容器包裹。
|
|
159
|
+
- 移动端字号是否达到底线(正文 ≥14px、KPI 数字 ≥20px、图表标题 ≥13px)。
|
|
102
160
|
|
|
103
161
|
产出:确认或修正。
|
|
@@ -1,67 +1,69 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: frontend-design
|
|
3
|
-
description:
|
|
4
|
-
|
|
5
|
-
-
|
|
3
|
+
description: 为设计确立独特、有意图的视觉方向的指引——配色、字体与美学选择不带模板化默认的痕迹。适用于各类媒介(deck、报告、UI、原型),不限于 Web UI。
|
|
4
|
+
metadata:
|
|
5
|
+
display-names:
|
|
6
|
+
zh-CN: 创意设计
|
|
7
|
+
en-US: Creative Design
|
|
6
8
|
---
|
|
7
9
|
|
|
8
10
|
# Frontend Design
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
以一家小型设计工作室的设计主管身份来做这件事——这家工作室以让每位客户拥有绝不会被认错的视觉形象而闻名。这位客户已经否掉过几版感觉模板化的提案,他们付费买的是一个鲜明的观点:针对这份 brief 做出深思熟虑、有主张的配色、字体与版式选择,并承担一次你能说清理由的真正的美学冒险。
|
|
11
13
|
|
|
12
|
-
##
|
|
14
|
+
## 让设计扎根于主题
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
如果 brief 没有钉死产品或主题是什么,动手设计前先自己钉死:点出一个具体的主题、它的受众、这个页面唯一要完成的任务,并明确说出你的选择。如果你的记忆里有关于用户偏好的信息、关于他们正在构建什么的上下文、或你以往做过的设计——把它们当作线索用起来。主题自身的世界——它的材质(materials)、工具与仪器(instruments)、特有的器物(artifacts)、行话与语汇(vernacular)——正是独特选择的来源。全程用 brief 的真实内容与题材来构建。
|
|
15
17
|
|
|
16
|
-
##
|
|
18
|
+
## 视觉方向
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
在选定颜色或组件之前,先在思考中定下方向。填满四个槽位——每一个都要取自*这个*主题:
|
|
19
21
|
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
22
|
+
- **世界(World)**——这个页面属于哪个世界?去主题自己的世界里找:它的材质、工具与仪器、特有的器物、行话与语汇。
|
|
23
|
+
- **材质(Materials)**——哪些真实存在的材质表面(surfaces)与印记(marks)属于那个世界?先把主题自带的一一列出来,别一上来就用通用的。
|
|
24
|
+
- **配色(Palette)**——哪些颜色承担语义或品牌职责,哪些是中性的支撑色,哪一个唯一的强调色赢得注意力?
|
|
25
|
+
- **签名元素(Signature)**——整个页面靠它被记住的那一个手法。它必须只可能属于这个主题;一个换到下份 brief 也能复用的签名元素,是默认值,不是选择。
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
风格不是版式排完后再涂上去的装饰。这个方向决定字体排印、间距、图表处理、图像质感、章节节奏、边框、图标风格,以及哪些组件值得强调。
|
|
26
28
|
|
|
27
|
-
##
|
|
29
|
+
## 设计原则
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
对于网页设计,hero 区就是全页的论点。开场就亮出主题世界里最具特征的东西,形式因主题而定:一句大标题、一张图、一段动画、一个实时 demo、一个交互瞬间。选择要经过深思:「大数字 + 小标签 + 辅助统计数据 + 渐变点缀」是模板答案,只有当它确实是最佳选项时才用。
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
字体排印承载页面的性格。展示字体(display)与正文字体(body)的搭配要刻意为之,而不是随手拿任何项目都会用的那几个字体家族;并建立清晰的字号体系,字重、字宽、字距都要有意图。让字体处理本身成为设计中令人记住的一部分,而不是承载内容的中性载体。
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
结构即信息。结构件——编号、眉标、分隔线、标签——应当编码内容中真实存在的信息,而不是装饰内容。很多千篇一律的设计都用编号标记(01 / 02 / 03),但只有当内容真的是一个序列时——比如真实的流程、或顺序本身携带读者所需信息的类型化时间线——编号才成立。在采用编号标记这类选择之前,先质疑它们是否真的说得通。
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
有意识地运用动效。想清楚动画是否、以及在哪里能服务主题:页面加载序列、滚动触发的揭示、hover 微交互、环境氛围。一个经过编排的时刻通常比散落的零星特效更有力;按视觉方向的需要来选。但有时少即是多——多余的动画会加重「这个设计是 AI 生成的」的观感。
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
让复杂度匹配愿景。极繁方向需要精雕细琢的执行;极简方向需要间距、字体与细节上的精准。优雅就是把选定的愿景执行到位。
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
认真对待文字内容。设计 brief 往往不含真实内容,文案要由你来写。文案带来的模板感不亚于设计本身。更多指引见下文关于写作的章节。
|
|
40
42
|
|
|
41
|
-
##
|
|
43
|
+
## 流程:头脑风暴、探索、规划、评审、构建、再评审
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
先校准现状:当下的 AI 生成设计集中在四种长相上:(1) 暖奶油色背景(接近 #F4F1EA)+ 高对比衬线展示字体 + 陶土色(terracotta)强调色;(2) 近黑背景 + 单一亮色强调——酸性绿(acid green)或朱红(vermilion);(3) 大报(broadsheet)式版面——发丝线(hairline rules)、零 border-radius、报纸般的密集分栏;(4) 深色底「科技感」版面——紫蓝渐变、发光光晕(glow)、半透明玻璃拟态(glassmorphism)卡片,科技 / AI / 数据类 brief 上尤其高发。四者对某些 brief 都站得住脚,但它们是默认值而非选择,而且不看主题就冒出来。凡是 brief 钉死了视觉方向的地方,严格照办——brief 自己的话始终优先,包括它点名要这四种长相之一的时候。凡是 brief 留出自由度的维度,别把这份自由花在这四个默认值上。就像受雇的人类设计师一样,往往要在「做自己擅长的」与「把每个项目当作试验和学习的机会」之间小心权衡。
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
分两遍做。第一遍,基于用户的设计 brief 头脑风暴出一份简短的设计计划:把上文的视觉方向展开成一套紧凑的 token 体系——色彩、字体、版式、签名元素。色彩:用 4–6 个命名的 hex 值描述配色。字体:至少两种角色的字体(一款有性格、克制使用的展示字体,一款与之互补的正文字体,必要时再加一款用于图注或数据的功能字体)。版式:一个版式概念,用一句话的文字描述加 ASCII 线框图来构思和比较。签名元素:这个页面将被记住的那个唯一独特元素,以恰当的方式体现 brief。
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
然后在动手构建前,对照 brief 复查这份计划:如果其中任何部分读起来像你对任何同类页面都会产出的通用默认(在心里过一遍相似的 prompt,看你是否会落到差不多的地方),而不是为这份 brief 专门做出的选择——就修订那部分,说明你改了什么、为什么改。只有在确认设计计划具备相对独特性之后,才开始写代码,严格遵循修订后的计划,让每一个颜色和字体决策都从计划中推导出来。
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
写代码时,注意组织好 CSS 选择器的优先级(specificity)。很容易写出相互抵消的 CSS 类(尤其是 `.section` 这类分区级选择器与 `.cta` 这类元素级选择器之间)。区块之间的 padding/margin 上经常出这种问题。
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
尽量把这些规划与迭代放在思考中完成,只在你有较高把握能让用户眼前一亮时,才把想法拿给用户看。
|
|
52
54
|
|
|
53
|
-
##
|
|
55
|
+
## 克制与自我评审
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
把大胆花在一个地方。让签名元素成为唯一被记住的东西,它周围的一切保持安静、克制,砍掉任何不服务于 brief 的装饰。不冒险本身也可能是一种冒险!默默守住质量底线,不必声张:响应式适配到移动端、键盘焦点可见、尊重 reduced motion。边构建边评审自己的作品——读你写出的代码,在脑子里过一遍它渲染成什么样。想想香奈儿的忠告:出门前照照镜子,摘掉一件配饰。人类创作者有记忆,总在尝试新东西;如果你有地方快速记下自己试过什么,会对后续迭代有帮助。
|
|
56
58
|
|
|
57
|
-
##
|
|
59
|
+
## 再谈设计中的写作
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
文字出现在设计里只有一个理由:让设计更易理解,从而更易使用。文字是设计材料,不是装饰。对文案投入的心思,要和对间距、色彩投入的一样多。落笔之前,先问这个设计需要说什么、怎么说最能帮人在这段体验里找到方向。
|
|
60
62
|
|
|
61
|
-
|
|
63
|
+
站在屏幕另一侧的最终用户角度来写。以人们能控制、能认出的东西命名,绝不以系统的实现方式命名。用户管理的是「通知」,不是「webhook 配置」。用平实的语言描述某物做什么,而不是推销它。具体始终胜过抖机灵。
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
默认使用主动语态。一个控件应当准确说明使用它时会发生什么:说 "Save changes",而不是 "Submit"。同一个动作在整条流程中保持同名:写着 "Publish" 的按钮,产生的 toast 就写 "Published"。界面的词汇表就是用户穿行产品时的路标。连贯与一致是人们认路的方式。
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
把失败与空态当作指路的时机,而不是渲染情绪的时机。解释出了什么问题、怎么修复,用界面的口吻而非某个人的口吻。错误提示不道歉,也绝不对发生了什么含糊其辞。空屏是一份行动邀请。
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
语域要像对话一样自然,并经过调校:动词平实、sentence case(句首大写)、没有废话,语气与品牌和受众匹配。让每个元素只做一件事:标签就是标注,示例就是演示,没有元素悄悄身兼二职。
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hi-fi-design
|
|
3
3
|
description: 用于创建高保真 UI mockup、设计探索,或带多种变体的视觉原型。触发词:mockup, hi-fi, prototype, UI design, 高保真, 设计稿, 原型, 界面设计, 视觉设计, 设计方案
|
|
4
|
-
|
|
5
|
-
-
|
|
4
|
+
metadata:
|
|
5
|
+
display-names:
|
|
6
|
+
zh-CN: 高保真设计
|
|
7
|
+
en-US: Hi-Fi Design
|
|
6
8
|
---
|
|
7
9
|
|
|
8
10
|
# 高保真设计
|
|
@@ -1,8 +1,43 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: interactive-prototype
|
|
3
|
-
description:
|
|
4
|
-
|
|
5
|
-
-
|
|
3
|
+
description: 创建具备真实交互的可运行应用原型。触发词:interactive prototype, 交互原型, 可交互原型, 动态原型, 原型演示, 交互演示, working app
|
|
4
|
+
metadata:
|
|
5
|
+
display-names:
|
|
6
|
+
zh-CN: 交互原型
|
|
7
|
+
en-US: Interactive Prototype
|
|
6
8
|
---
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
# 交互原型
|
|
11
|
+
|
|
12
|
+
创建一个完全可交互的原型,具备真实的状态管理和页面切换。用 React 的 useState/useEffect 实现动态行为。包含悬停状态、点击交互、表单验证、动画过渡和多步导航流程。用起来要像真正能运行的应用,而不是静态效果图。
|
|
13
|
+
|
|
14
|
+
## 响应式适配
|
|
15
|
+
|
|
16
|
+
先判断 brief 的目标场景,走不同策略:
|
|
17
|
+
|
|
18
|
+
**面向终端用户的产品**(官网、营销页、C 端应用、展示型页面)——必须适配移动端。用 `@media (max-width: 768px)` 做断点,375px 宽度下无水平滚动、无内容不可读、无元素互相遮挡:
|
|
19
|
+
|
|
20
|
+
- **侧边栏**:窄屏默认收起,汉堡按钮切换;展开时 `position: fixed` + 半透明遮罩覆盖内容,不挤压主区域。
|
|
21
|
+
- **顶部导航**:导航项超出视口宽度时折叠为汉堡菜单,不允许换行堆叠或水平溢出。
|
|
22
|
+
- **网格与卡片**:用 CSS Grid `auto-fit` / `minmax()` 或 Flexbox `flex-wrap`,窄屏自动堆叠为单列;卡片内数字和文字不因容器变窄而截断。
|
|
23
|
+
- **固定定位元素**:浮动按钮、悬浮面板等 `position: fixed/absolute` 元素用 `right: 16px` 等安全边距约束在视口内,不允许超出屏幕边缘。
|
|
24
|
+
|
|
25
|
+
**面向桌面的场景**(管理后台、内部工具、数据密集型仪表盘)——不需要重排为移动端布局,但必须设 `min-width`(通常 1024px–1200px),窄于此宽度时整体水平滚动,而不是让布局被挤压变形。
|
|
26
|
+
|
|
27
|
+
brief 未指明时默认按终端用户产品处理。
|
|
28
|
+
|
|
29
|
+
## 宣告可升级为全栈应用
|
|
30
|
+
|
|
31
|
+
宿主为交互原型提供「升级为全栈应用」入口,把纯前端原型转成带服务端的真实应用。入口是否出现,取决于原型有没有向父窗口宣告:
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
function announceUpgrade() {
|
|
35
|
+
window.parent.postMessage({ type: 'miaoda:upgrade:available', kind: 'interactive-prototype' }, '*');
|
|
36
|
+
}
|
|
37
|
+
announceUpgrade();
|
|
38
|
+
// 宿主在 iframe 'load' 时重置能力声明,脚本早于 load 执行时补一次
|
|
39
|
+
if (document.readyState !== 'complete') window.addEventListener('load', announceUpgrade, { once: true });
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- 重复宣告无副作用;宁可多发,也不要因时序错过让入口不出现。
|
|
43
|
+
- 只宣告,不实现:原型侧不写升级逻辑,转全栈由宿主发起。
|