hd-garden 0.10.4 → 0.12.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/.agents/skills/garden-ui/SKILL.md +11 -10
- package/README.en.md +1 -1
- package/README.md +2 -2
- package/app/components/garden/GardenBlock.tsx +20 -4
- package/app/components/garden/blocks.tsx +6 -118
- package/app/globals.css +1 -0
- package/app/lib/garden-docs-meta.ts +5 -3
- package/app/lib/generated-content.ts +1 -1
- package/app/lib/i18n.ts +0 -6
- package/app/lib/remark-garden.mjs +61 -5
- package/app/styles/a2.css +25 -112
- package/app/styles/tokens.css +5 -0
- package/docs/handbook/ai-writing.md +3 -3
- package/docs/handbook/components/compose.md +134 -0
- package/docs/handbook/components/html.md +1 -1
- package/docs/handbook/components/image.md +1 -1
- package/docs/handbook/components/interactive.md +4 -1
- package/docs/handbook/components/link-card.md +1 -1
- package/docs/handbook/components.md +23 -35
- package/docs/handbook/design.md +25 -34
- package/docs/handbook/en/ai-writing.md +3 -3
- package/docs/handbook/en/components/compose.md +123 -0
- package/docs/handbook/en/components/html.md +1 -1
- package/docs/handbook/en/components/image.md +1 -1
- package/docs/handbook/en/components/interactive.md +4 -1
- package/docs/handbook/en/components.md +23 -36
- package/docs/handbook/en/design.md +25 -33
- package/docs/handbook/en/index.md +5 -5
- package/docs/handbook/en/reference/compose-icons.md +863 -0
- package/docs/handbook/en/reference/compose.md +177 -0
- package/docs/handbook/en/reference.md +3 -2
- package/docs/handbook/en/workflow.md +8 -6
- package/docs/handbook/index.md +5 -5
- package/docs/handbook/reference/compose-icons.md +863 -0
- package/docs/handbook/reference/compose.md +177 -0
- package/docs/handbook/reference.md +3 -2
- package/docs/handbook/workflow.md +8 -6
- package/editors/dist/typora/main.js +269 -241
- package/editors/dist/vscode/garden-ui-0.1.0.vsix +0 -0
- package/package.json +14 -2
- package/scripts/gen-compose-handbook.mjs +427 -0
- package/scripts/gen-compose-icons.mjs +236 -0
- package/scripts/handbook-allowlist.mjs +0 -8
- package/scripts/handbook-facts.mjs +6 -36
- package/scripts/ui-cli.mjs +5 -1
- package/templates/garden-blocks.md +34 -31
- package/templates/garden-snippets.plist +3 -8
- package/templates/skills-en/garden-ui/SKILL.md +11 -10
- package/ui/README.md +1 -0
- package/ui/compose/compose.css +1324 -0
- package/ui/compose/dil.mjs +443 -0
- package/ui/compose/examples.mjs +28 -0
- package/ui/compose/icons.mjs +774 -0
- package/ui/compose/index.mjs +8 -0
- package/ui/compose/markup.mjs +727 -0
- package/ui/compose/parse.mjs +28 -0
- package/ui/compose/render.mjs +385 -0
- package/ui/compose/tokens.mjs +50 -0
- package/ui/core/cli-locale.mjs +4 -0
- package/ui/core/fence.mjs +13 -1
- package/ui/core/fix-prompt.mjs +1 -0
- package/ui/core/garden-fence.mjs +4 -1
- package/ui/core/scan.mjs +28 -2
- package/ui/core/transform.mjs +12 -0
- package/ui/core/validate.mjs +6 -4
- package/ui/garden/catalog.mjs +58 -35
- package/ui/garden/check.mjs +22 -6
- package/ui/garden/parse.mjs +26 -0
- package/ui/garden/snippets.mjs +15 -13
- package/ui/garden/word-count.mjs +10 -18
- package/ui/preview/dist/garden-ui.esm.js +268 -242
- package/ui/preview/dist/garden-ui.iife.js +268 -242
- package/ui/prompt/build.mjs +1 -0
- package/ui/prompt/recipes/compose.md +40 -0
- package/ui/prompt/rules.md +3 -3
- package/ui/react/CatalogPage.tsx +2 -2
- package/ui/react/runtime.tsx +5 -1
- package/docs/handbook/components/figure.md +0 -59
- package/docs/handbook/en/components/figure.md +0 -59
- package/docs/handbook/en/reference/figure.md +0 -84
- package/docs/handbook/reference/figure.md +0 -84
package/app/styles/a2.css
CHANGED
|
@@ -73,8 +73,7 @@ body {
|
|
|
73
73
|
.g-card,
|
|
74
74
|
.g-timeline,
|
|
75
75
|
.g-sandbox,
|
|
76
|
-
.g-html
|
|
77
|
-
.g-figure {
|
|
76
|
+
.g-html {
|
|
78
77
|
box-shadow: none;
|
|
79
78
|
}
|
|
80
79
|
|
|
@@ -289,6 +288,17 @@ body {
|
|
|
289
288
|
max-width: var(--col);
|
|
290
289
|
}
|
|
291
290
|
|
|
291
|
+
/* The compare post puts two wide diagrams side by side. */
|
|
292
|
+
@media (min-width: 1260px) {
|
|
293
|
+
.post-reading-page:has(.g-compose-pair) .article-reading-layout {
|
|
294
|
+
grid-template-columns: 24px minmax(0, 1fr) var(--rail);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.post-reading-page:has(.g-compose-pair) .article-reading-column {
|
|
298
|
+
max-width: none;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
292
302
|
.post-reading-page .article-reading-layout > .toc {
|
|
293
303
|
grid-column: 3;
|
|
294
304
|
grid-row: 1;
|
|
@@ -785,6 +795,17 @@ html[data-theme="dark"] .markdown-body > p > img:not([class]) {
|
|
|
785
795
|
background: transparent;
|
|
786
796
|
}
|
|
787
797
|
|
|
798
|
+
.table-wrap td .markdown-image-trigger {
|
|
799
|
+
margin: 0;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
.table-wrap td .markdown-image-trigger img {
|
|
803
|
+
width: 280px;
|
|
804
|
+
max-width: 100%;
|
|
805
|
+
height: auto;
|
|
806
|
+
border-radius: 6px;
|
|
807
|
+
}
|
|
808
|
+
|
|
788
809
|
@media (min-width: 900px) {
|
|
789
810
|
.ux-wide {
|
|
790
811
|
margin-left: calc(-1 * var(--wl, 0px)) !important;
|
|
@@ -885,8 +906,6 @@ html[data-theme="dark"] .markdown-body > p > img:not([class]) {
|
|
|
885
906
|
.g-cmp,
|
|
886
907
|
.g-timeline,
|
|
887
908
|
.g-chart,
|
|
888
|
-
.g-figure,
|
|
889
|
-
.g-explore,
|
|
890
909
|
.g-html,
|
|
891
910
|
.g-idea,
|
|
892
911
|
.g-legacy,
|
|
@@ -895,77 +914,9 @@ html[data-theme="dark"] .markdown-body > p > img:not([class]) {
|
|
|
895
914
|
box-shadow: none;
|
|
896
915
|
}
|
|
897
916
|
|
|
898
|
-
.g-explore {
|
|
899
|
-
border: 1px solid var(--rule);
|
|
900
|
-
border-radius: var(--r);
|
|
901
|
-
padding: 12px 14px 14px;
|
|
902
|
-
background: transparent;
|
|
903
|
-
max-width: 100%;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
.g-explore [role="tablist"] {
|
|
907
|
-
display: flex;
|
|
908
|
-
flex-wrap: wrap;
|
|
909
|
-
gap: 6px;
|
|
910
|
-
margin: 0;
|
|
911
|
-
padding: 0;
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
.g-explore [role="tab"] {
|
|
915
|
-
font: 500 14px / 1 var(--sans);
|
|
916
|
-
padding: 9px 12px;
|
|
917
|
-
min-height: 44px;
|
|
918
|
-
border-radius: 999px;
|
|
919
|
-
border: 1px solid var(--rule);
|
|
920
|
-
background: transparent;
|
|
921
|
-
color: var(--soft);
|
|
922
|
-
cursor: pointer;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
.g-explore [role="tab"][aria-selected="true"] {
|
|
926
|
-
border-color: var(--blue);
|
|
927
|
-
color: var(--blue);
|
|
928
|
-
background: var(--blue-tint);
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
.dx-wrap {
|
|
932
|
-
overflow: visible;
|
|
933
|
-
margin-top: 10px;
|
|
934
|
-
max-width: 100%;
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
.dx-wrap svg {
|
|
938
|
-
display: block;
|
|
939
|
-
width: 100%;
|
|
940
|
-
max-width: 100%;
|
|
941
|
-
height: auto;
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
.g-explore:not([data-sel="all"]) .dx-wrap [data-p]:not(.on),
|
|
945
|
-
.g-explore:not([data-sel="all"]) .dx-wrap text:not(.on) {
|
|
946
|
-
opacity: 0.22;
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
.g-explore .on {
|
|
950
|
-
opacity: 1;
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
.dx-exp p {
|
|
954
|
-
margin: 10px 0 0;
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
.g-explore figcaption {
|
|
958
|
-
font-size: 13px;
|
|
959
|
-
color: var(--muted);
|
|
960
|
-
margin-top: 8px;
|
|
961
|
-
text-align: left;
|
|
962
|
-
}
|
|
963
|
-
|
|
964
917
|
.g-sandbox,
|
|
965
918
|
.g-play,
|
|
966
|
-
.g-html
|
|
967
|
-
.g-explore,
|
|
968
|
-
.dx-wrap {
|
|
919
|
+
.g-html {
|
|
969
920
|
max-width: 100%;
|
|
970
921
|
}
|
|
971
922
|
|
|
@@ -973,7 +924,6 @@ html[data-theme="dark"] .markdown-body > p > img:not([class]) {
|
|
|
973
924
|
.g-stat,
|
|
974
925
|
.g-cmp,
|
|
975
926
|
.g-timeline,
|
|
976
|
-
.g-figure,
|
|
977
927
|
.g-html {
|
|
978
928
|
border: 1px solid var(--rule);
|
|
979
929
|
border-radius: var(--r);
|
|
@@ -982,8 +932,7 @@ html[data-theme="dark"] .markdown-body > p > img:not([class]) {
|
|
|
982
932
|
|
|
983
933
|
.g-card,
|
|
984
934
|
.g-cmp,
|
|
985
|
-
.g-html
|
|
986
|
-
.g-figure {
|
|
935
|
+
.g-html {
|
|
987
936
|
padding: 14px 16px;
|
|
988
937
|
}
|
|
989
938
|
|
|
@@ -1163,7 +1112,6 @@ html[data-theme="dark"] .markdown-body > p > img:not([class]) {
|
|
|
1163
1112
|
min-width: 3px;
|
|
1164
1113
|
}
|
|
1165
1114
|
|
|
1166
|
-
.g-figure svg,
|
|
1167
1115
|
.g-mermaid svg,
|
|
1168
1116
|
.dx-svg {
|
|
1169
1117
|
display: block;
|
|
@@ -1172,16 +1120,6 @@ html[data-theme="dark"] .markdown-body > p > img:not([class]) {
|
|
|
1172
1120
|
height: auto;
|
|
1173
1121
|
}
|
|
1174
1122
|
|
|
1175
|
-
.g-figure:not([data-sel="all"]) [data-p]:not(.on),
|
|
1176
|
-
.g-figure:not([data-sel="all"]) text:not(.on) {
|
|
1177
|
-
opacity: 0.22;
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
.g-figure [data-p].on,
|
|
1181
|
-
.g-figure text.on {
|
|
1182
|
-
opacity: 1;
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
1123
|
.g-mermaid {
|
|
1186
1124
|
margin: 28px 0;
|
|
1187
1125
|
padding: 16px;
|
|
@@ -1399,19 +1337,10 @@ html[data-theme="dark"] .markdown-body > p > img:not([class]) {
|
|
|
1399
1337
|
padding-right: 44px;
|
|
1400
1338
|
}
|
|
1401
1339
|
|
|
1402
|
-
.ux-fs:not(.g-sandbox) > .ux-fsbar + .g-explore {
|
|
1403
|
-
padding-right: 14px;
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
1340
|
.ux-fs:not(.g-sandbox) > .ux-fsbar + .g-sandbox {
|
|
1407
1341
|
padding-right: 0;
|
|
1408
1342
|
}
|
|
1409
1343
|
|
|
1410
|
-
.ux-fs:not(.g-sandbox) > .ux-fsbar + .g-explore > [role="tablist"] {
|
|
1411
|
-
padding-right: 44px;
|
|
1412
|
-
box-sizing: border-box;
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
1344
|
.ux-fs:fullscreen,
|
|
1416
1345
|
.ux-fs.ux-fs-on {
|
|
1417
1346
|
background: var(--paper);
|
|
@@ -1793,13 +1722,6 @@ html[data-theme="dark"] .gf-scrim { background: rgb(0 0 0 / 45%); }
|
|
|
1793
1722
|
font-family: var(--sans);
|
|
1794
1723
|
}
|
|
1795
1724
|
|
|
1796
|
-
.garden-doc-page .g-explore:not([data-sel="all"]) .dx-wrap [data-p]:not(.on),
|
|
1797
|
-
.garden-doc-page .g-explore:not([data-sel="all"]) .dx-wrap text:not(.on),
|
|
1798
|
-
.garden-doc-page .g-figure:not([data-sel="all"]) [data-p]:not(.on),
|
|
1799
|
-
.garden-doc-page .g-figure:not([data-sel="all"]) text:not(.on) {
|
|
1800
|
-
opacity: 0.56;
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
1725
|
.garden-doc-page > .toc {
|
|
1804
1726
|
margin-top: 8px;
|
|
1805
1727
|
position: sticky;
|
|
@@ -2641,15 +2563,6 @@ html[data-theme="dark"] .ref-demo { --rd-s: #262624; --rd-p: #1f1e1d; --rd-i: #e
|
|
|
2641
2563
|
.ref-demo-in .toc-mobile-trigger { opacity: 0; visibility: hidden; pointer-events: none; }
|
|
2642
2564
|
}
|
|
2643
2565
|
|
|
2644
|
-
/* figure reference page: the drawing needs room, so the example stacks
|
|
2645
|
-
(preview on top, full width; code below). Scoped to the reference demo;
|
|
2646
|
-
figures in articles are untouched. */
|
|
2647
|
-
@media (min-width: 1024px) {
|
|
2648
|
-
.ref-demo[data-name="figure"] { grid-template-columns: minmax(0, 1fr); background: var(--rd-p); }
|
|
2649
|
-
.ref-demo[data-name="figure"] .ref-pane[data-p="v"] { grid-column: 1; grid-row: 1; }
|
|
2650
|
-
.ref-demo[data-name="figure"] .ref-pane[data-p="c"] { grid-column: 1; grid-row: 2; background: var(--rd-s); border-top: 1px solid var(--rd-r); }
|
|
2651
|
-
}
|
|
2652
|
-
|
|
2653
2566
|
/* ===== v0.10.1 tip keep (after git checkout of a2.css from 9a80f7e5) ===== */
|
|
2654
2567
|
|
|
2655
2568
|
/* List pages: PageIntro rides on .sh-head; keep eyebrow in the same vertical rhythm. */
|
package/app/styles/tokens.css
CHANGED
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
--accent-soft: var(--blue-tint);
|
|
34
34
|
--selection: #e8e5db;
|
|
35
35
|
--hl: #ffe58f;
|
|
36
|
+
/* Two lane-arrow emphases. Same hues as the note and tip callouts, not a second palette. */
|
|
37
|
+
--flow: #2c55b4;
|
|
38
|
+
--flow-back: #2d6a3e;
|
|
36
39
|
--red: #d82d48;
|
|
37
40
|
--red-text: #c2263f;
|
|
38
41
|
--red-tint: #fbeef0;
|
|
@@ -94,6 +97,8 @@ html[data-theme="dark"] {
|
|
|
94
97
|
--accent-soft: var(--blue-tint);
|
|
95
98
|
--selection: rgb(238 236 231 / 18%);
|
|
96
99
|
--hl: #5e4e17;
|
|
100
|
+
--flow: #93b2f4;
|
|
101
|
+
--flow-back: #8fcb9f;
|
|
97
102
|
--red: #f29aab;
|
|
98
103
|
--red-text: #f29aab;
|
|
99
104
|
--red-tint: rgb(242 154 171 / 12%);
|
|
@@ -21,7 +21,7 @@ order: 2
|
|
|
21
21
|
```
|
|
22
22
|
````
|
|
23
23
|
|
|
24
|
-
草稿(`draft: true`)里可以保留未编译的想法;非草稿文章里还有未编译的想法时,`npx garden ui check` 和 `npx garden check` 都会报 `garden-idea` 错误。Agent 会根据内容把想法编译成 `garden
|
|
24
|
+
草稿(`draft: true`)里可以保留未编译的想法;非草稿文章里还有未编译的想法时,`npx garden ui check` 和 `npx garden check` 都会报 `garden-idea` 错误。Agent 会根据内容把想法编译成 `garden compose`、`card`、`stat`、`compare` 等内置组件,或者在一段话就能说清时直接写回普通段落。
|
|
25
25
|
|
|
26
26
|
## 2. 随包安装的三个 skill
|
|
27
27
|
|
|
@@ -112,8 +112,8 @@ npx garden editors install --typora
|
|
|
112
112
|
|
|
113
113
|
不借助 AI 手写组件时,可以直接使用包内自带的模板与代码片段:
|
|
114
114
|
|
|
115
|
-
- `make new` 创建的草稿底部自带一段 `<!-- 组件速查 ... -->`
|
|
116
|
-
- `templates/garden-blocks.md`
|
|
115
|
+
- `make new` 创建的草稿底部自带一段 `<!-- 组件速查 ... -->` 注释,包含想法块和各个组件的示例,写完可直接删掉。
|
|
116
|
+
- `templates/garden-blocks.md` 汇总了想法块与各个组件的适用场景(`when` / `whenNot`)和可复制示例;macOS 与 Typora / Alfred 用户可导入 `templates/garden-snippets.plist`,输入 `;gidea`(或 `;garden想法`)、`;gcard`、`;gstat`、`;gcompare`、`;gtimeline`、`;gchart`、`;gcompose`、`;ghtml`、`;ginteractive`、`;gfile`、`;grel`、`;glist`、`;gchoice` 即可展开对应围栏。`;gcompose` 展开的是带一句白话的 `garden compose`。
|
|
117
117
|
- 编辑器插件的用法见上一节。`npx garden ui catalog` 在本地生成 `.garden/ui-catalog.html` 离线组件画廊。
|
|
118
118
|
|
|
119
119
|
## 8. 可选的独立管理后台
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 说明图(compose)
|
|
3
|
+
navTitle: 说明图
|
|
4
|
+
description: 在文章里写几句白话,让 AI 拼出静态说明图。
|
|
5
|
+
section: components
|
|
6
|
+
order: 36
|
|
7
|
+
badge: compose
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
写文章想画一张结构图时,输入 `/garden` 选「compose(想法)」。文章里会插入一个 `garden compose` 围栏。你在里面用白话写清结构,再对 AI 说「编译这篇」,AI 就会把这句话留在 `<intent>` 里,并用 Markdown 叶子和组件标签拼出静态说明图。
|
|
11
|
+
|
|
12
|
+
## 怎么写
|
|
13
|
+
|
|
14
|
+
围栏里只写你想让读者看见的结构,不要写样式。
|
|
15
|
+
|
|
16
|
+
把四件事写清楚:
|
|
17
|
+
|
|
18
|
+
- **分几块**:是三列并排、从上到下五层,还是上下两行。
|
|
19
|
+
- **每块叫什么**:用图上要摆出来的短词。解释放在名字下面那一行,别把一整句话当标题。
|
|
20
|
+
- **谁连谁**:谁先到谁、从一处散开,还是几处收到一起。没有先后顺序,就直接写「这几块没有先后」。
|
|
21
|
+
- **哪块是重点**:直接点名,比如「中间那列是重点」「下面一行才是重点」。
|
|
22
|
+
|
|
23
|
+
不要写颜色、圆角、灰胶囊、字重、间距、阴影、要不要撑满。外观由组件默认样式决定,写了反而乱。
|
|
24
|
+
|
|
25
|
+
**完整标签与属性**见 [组件参考 · compose](/garden/reference/compose);**全部图标名**见 [compose 图标](/garden/reference/compose-icons)。
|
|
26
|
+
|
|
27
|
+
## 写法对照
|
|
28
|
+
|
|
29
|
+
写围栏时,最常见的失误有两个:一是只写一个主题词,没给结构;二是把精力花在规定颜色、圆角和字重上。下面按五种常见结构,列出改写后的写法。
|
|
30
|
+
|
|
31
|
+
**三列并排,中间接起来**
|
|
32
|
+
|
|
33
|
+
````markdown
|
|
34
|
+
```garden compose
|
|
35
|
+
三列:User 下面是 Alice、Bob;Role 下面是管理员、审核员;
|
|
36
|
+
Permission 下面是 orders:read、orders:approve。
|
|
37
|
+
Role 在中间,把用户和权限接起来。Role 是重点。
|
|
38
|
+
```
|
|
39
|
+
````
|
|
40
|
+
|
|
41
|
+
**先到一处,再散开**
|
|
42
|
+
|
|
43
|
+
````markdown
|
|
44
|
+
```garden compose
|
|
45
|
+
用户浏览器先到身份提供方,再同时连到 HR、Finance、Project 三个系统。
|
|
46
|
+
三个系统都信任同一个身份提供方。身份提供方是重点。
|
|
47
|
+
```
|
|
48
|
+
````
|
|
49
|
+
|
|
50
|
+
**自上而下分层**
|
|
51
|
+
|
|
52
|
+
````markdown
|
|
53
|
+
```garden compose
|
|
54
|
+
从上到下五层:浏览器、身份服务、BFF、业务服务、授权决策。
|
|
55
|
+
身份服务和授权决策是重点,其余是经过的路径。
|
|
56
|
+
不是每次请求都按这个顺序走完。
|
|
57
|
+
```
|
|
58
|
+
````
|
|
59
|
+
|
|
60
|
+
**一件事的多个切面**
|
|
61
|
+
|
|
62
|
+
````markdown
|
|
63
|
+
```garden compose
|
|
64
|
+
用户发起请求后,先看四件事:认证(你是谁)、凭证(怎么证明)、
|
|
65
|
+
授权(有没有权)、验证(数据合不合法)。
|
|
66
|
+
落到业务和存储时,再看传输和保密。这六块没有严格的先后。
|
|
67
|
+
```
|
|
68
|
+
````
|
|
69
|
+
|
|
70
|
+
**上下两行对比**
|
|
71
|
+
|
|
72
|
+
````markdown
|
|
73
|
+
```garden compose
|
|
74
|
+
上面一行是常规交付:理解需求 → 设计方案 → 开发上线。
|
|
75
|
+
下面一行是探索循环:提出假设 → 低成本验证 → 迭代或放弃。
|
|
76
|
+
上面是背景,下面一行才是重点。
|
|
77
|
+
```
|
|
78
|
+
````
|
|
79
|
+
|
|
80
|
+
## 图标与表面
|
|
81
|
+
|
|
82
|
+
状态符号用 `<icon name="check-circle"/>` 一类具名图标,不要塞 emoji。小格子、浅底、圆角用 `padding`、`background`、`radius` 组合,不要为单张图发明专用标签。
|
|
83
|
+
|
|
84
|
+
## 一张示例
|
|
85
|
+
|
|
86
|
+
下面只留一张图;更多对照见仓库示例文,标签全表见参考页。
|
|
87
|
+
|
|
88
|
+
```garden compose
|
|
89
|
+
<intent>
|
|
90
|
+
三列:User 下面是 Alice 和 Bob,Role 下面是管理员和审核员,Permission 下面是 orders:read 和 orders:approve。Role 在中间,把用户和权限接起来。Role 是要先看见的一层。
|
|
91
|
+
</intent>
|
|
92
|
+
<row align="center">
|
|
93
|
+
<stack align="center">
|
|
94
|
+
<title>User</title>
|
|
95
|
+
<text>Alice</text>
|
|
96
|
+
<text>Bob</text>
|
|
97
|
+
</stack>
|
|
98
|
+
<band tone="accent" align="center">
|
|
99
|
+
<title>Role</title>
|
|
100
|
+
<text>管理员</text>
|
|
101
|
+
<text>审核员</text>
|
|
102
|
+
</band>
|
|
103
|
+
<stack align="center">
|
|
104
|
+
<title>Permission</title>
|
|
105
|
+
<text>orders:read</text>
|
|
106
|
+
<text>orders:approve</text>
|
|
107
|
+
</stack>
|
|
108
|
+
</row>
|
|
109
|
+
<join>角色连接用户和权限</join>
|
|
110
|
+
<text tone="muted" align="center">概念关系:User ↔ Role ↔ Permission</text>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 可调参数(play)
|
|
114
|
+
|
|
115
|
+
静态说明图还差一步、读者要拧参数时,仍写 `garden compose`:
|
|
116
|
+
|
|
117
|
+
- `{@body const [n, setN] = DIL.useState(3)}` 声明状态
|
|
118
|
+
- `{@body const total = n * 24}` 派生值
|
|
119
|
+
- `{total}` / `value={n}` 插值
|
|
120
|
+
- `{#if …}{:else}{/if}`、`{#each … as item, i}{/each}` 控制流
|
|
121
|
+
- 小写控件:`<slider>`、`<choice>`、`<button>`、`<pie>` / `<chart>`、`<stat>`
|
|
122
|
+
|
|
123
|
+
旧的 `garden interactive` 与 PascalCase 仅作兼容。完整映射见仓库 `docs/compose-dil.md`。
|
|
124
|
+
|
|
125
|
+
```garden compose #compose-play-demo
|
|
126
|
+
caption: 拧一下席位,看月费。
|
|
127
|
+
intent: |
|
|
128
|
+
让读者调席位,看月费怎么变。
|
|
129
|
+
---
|
|
130
|
+
{@body const [seats, setSeats] = DIL.useState(3)}
|
|
131
|
+
{@body const total = seats * 24}
|
|
132
|
+
<slider min={1} max={12} value={seats} onChange={setSeats} label="席位" />
|
|
133
|
+
<stat label="月费" value={total} unit="USD" />
|
|
134
|
+
```
|
|
@@ -34,7 +34,7 @@ code: |
|
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
- **什么时候用**:内置组件画不出来的画布动画、物理模拟或独立小工具。
|
|
37
|
-
- **什么时候不用**:只需要拖动滑杆算公式时用[可调公式与参数](/garden/components/interactive)
|
|
37
|
+
- **什么时候不用**:只需要拖动滑杆算公式时用[可调公式与参数](/garden/components/interactive);说明图用 [compose](/garden/components/compose)。
|
|
38
38
|
|
|
39
39
|
可以这样对 AI 说:
|
|
40
40
|
|
|
@@ -9,7 +9,7 @@ order: 45
|
|
|
9
9
|
图片单独成段时会包进图框,并在下方显示图注。
|
|
10
10
|
|
|
11
11
|
- **什么时候用**:这张图属于文章,读者需要看到图下说明。
|
|
12
|
-
- **什么时候不用**:只是装饰时,把 `alt` 写成以 `image`、`截图` 或 `img`
|
|
12
|
+
- **什么时候不用**:只是装饰时,把 `alt` 写成以 `image`、`截图` 或 `img` 开头的占位词,这样不会出现图注。要按部分点开说明时用[说明图](/garden/components/compose);要提供下载时用[文件下载与预览](/garden/components/file)。
|
|
13
13
|
|
|
14
14
|
长文 `content/posts/my-post.md` 的配图放在同名目录 `content/posts/my-post/`。正文用 Markdown 图片语法引用,地址写成 `./my-post/diagram.svg`,方括号里的 `alt` 写成图注。
|
|
15
15
|
|
|
@@ -7,7 +7,10 @@ order: 38
|
|
|
7
7
|
badge: interactive
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
> **已废弃。** 新文章请写 [`compose`](/garden/components/compose),用 ChatGPT 同款 DIL(`{@body}` / `{expr}` / `{#if}` / `{#each}` 与小写标签)。旧的 `garden interactive` 围栏仍会当作 compose play 解析以兼容,之后会像 `figure` 一样删掉。
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
```garden compose #reading-time
|
|
11
14
|
caption: 示例:按字数、阅读速度和配图数估算一篇文章的阅读时间。数字只用来演示组件,不是统计结果。
|
|
12
15
|
---
|
|
13
16
|
<State words={6000} speed={400} images={8} />
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 组件总览
|
|
3
3
|
navTitle: 组件总览
|
|
4
|
-
description:
|
|
4
|
+
description: garden 围栏的效果预览,以及链接卡片、来源胶囊和本地图片。
|
|
5
5
|
section: components
|
|
6
6
|
order: 30
|
|
7
7
|
---
|
|
@@ -74,39 +74,27 @@ data:
|
|
|
74
74
|
y: 1340
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
## [
|
|
78
|
-
|
|
79
|
-
```garden
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<text data-p="validate" x="468" y="108" text-anchor="middle" font-size="24" fill="var(--muted)">检查导出目录</text>
|
|
99
|
-
</svg>
|
|
100
|
-
parts:
|
|
101
|
-
- id: sync
|
|
102
|
-
label: 1. 同步内容
|
|
103
|
-
text: 扫描正文与附件,生成站点数据。
|
|
104
|
-
- id: build
|
|
105
|
-
label: 2. 构建页面
|
|
106
|
-
text: 预渲染所有页面路由,输出 RSS、sitemap 与搜索文件。
|
|
107
|
-
- id: validate
|
|
108
|
-
label: 3. 导出校验
|
|
109
|
-
text: 确认导出目录结构完整。
|
|
77
|
+
## [说明图 · compose](/garden/components/compose)
|
|
78
|
+
|
|
79
|
+
```garden compose
|
|
80
|
+
<intent>
|
|
81
|
+
上面一行是交付顺序:理解需求、设计方案、开发上线。下面一行才是要强调的决策循环:提出假设、低成本验证、迭代或放弃。上面是背景,下面是重点。
|
|
82
|
+
</intent>
|
|
83
|
+
<row align="center">
|
|
84
|
+
<title align="center">理解需求</title>
|
|
85
|
+
<arrow dir="right"/>
|
|
86
|
+
<title align="center">设计方案</title>
|
|
87
|
+
<arrow dir="right"/>
|
|
88
|
+
<title align="center">开发上线</title>
|
|
89
|
+
</row>
|
|
90
|
+
<divider/>
|
|
91
|
+
<row align="center">
|
|
92
|
+
<pill tone="muted">提出假设</pill>
|
|
93
|
+
<arrow dir="right"/>
|
|
94
|
+
<pill tone="muted">低成本验证</pill>
|
|
95
|
+
<arrow dir="right"/>
|
|
96
|
+
<pill tone="muted">迭代或放弃</pill>
|
|
97
|
+
</row>
|
|
110
98
|
```
|
|
111
99
|
|
|
112
100
|
## [嵌入网页片段 · html](/garden/components/html)
|
|
@@ -139,7 +127,7 @@ code: |
|
|
|
139
127
|
|
|
140
128
|
## [可调公式与参数 · interactive](/garden/components/interactive)
|
|
141
129
|
|
|
142
|
-
```garden
|
|
130
|
+
```garden compose #overview-reading
|
|
143
131
|
caption: 示例:按字数和阅读速度估算阅读时间。
|
|
144
132
|
---
|
|
145
133
|
<State words={6000} speed={400} />
|
package/docs/handbook/design.md
CHANGED
|
@@ -33,40 +33,31 @@ Garden 的文章页面围绕长文阅读体验做了几项自动化处理。这
|
|
|
33
33
|
|
|
34
34
|
在运行 `npx garden sync` 时,构建脚本会直接解析本地图片(PNG、JPEG、WebP、GIF、SVG)的像素宽高并写入 `.garden/generated-content.ts` 的 `imageSizes` 表:
|
|
35
35
|
|
|
36
|
-
```garden
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<
|
|
47
|
-
<text
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<
|
|
52
|
-
<
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
<
|
|
57
|
-
<text
|
|
58
|
-
<
|
|
59
|
-
</
|
|
60
|
-
|
|
61
|
-
- id: sync
|
|
62
|
-
label: 1. 构建期读取尺寸
|
|
63
|
-
text: 服务端生成的 HTML 已经带有图片的 `width`、`height`、`data-nw`、`data-bw` 以及宽图的初始 `--wl` / `--wr`,图片尚未下载完成时也不会把下方文字顶得跳动。
|
|
64
|
-
- id: measure
|
|
65
|
-
label: 2. 客户端测量拓宽
|
|
66
|
-
text: 浏览器加载后,`ArticleMeasure` 根据当前窗口的实际宽度重新计算拓宽边距,并在滚动时实时判断宽图是否与右侧目录重叠。
|
|
67
|
-
- id: dark
|
|
68
|
-
label: 3. 深色衬底与灯箱
|
|
69
|
-
text: "正文配图点击后可在当前页打开灯箱大图(按 `Esc` 或点击背景关闭);深色模式下自动为配图设置 `--image-backing: #faf9f5` 背景。"
|
|
36
|
+
```garden compose
|
|
37
|
+
<intent>
|
|
38
|
+
图片从构建到渲染分三步。点一步,看这一阶段做什么。
|
|
39
|
+
</intent>
|
|
40
|
+
# 图片从构建到渲染
|
|
41
|
+
|
|
42
|
+
点一步,看这一阶段做什么
|
|
43
|
+
|
|
44
|
+
<steps>
|
|
45
|
+
<step id="sync">
|
|
46
|
+
<title>构建期读取尺寸</title>
|
|
47
|
+
<text>写入宽高,避免文字跳动</text>
|
|
48
|
+
<note>服务端生成的 HTML 已经带有图片的 width、height 和宽图边距。图片还没下载完时,下方文字也不会被顶得跳动。</note>
|
|
49
|
+
</step>
|
|
50
|
+
<step id="measure">
|
|
51
|
+
<title>客户端测量拓宽</title>
|
|
52
|
+
<text>按当前视口调整宽图与目录</text>
|
|
53
|
+
<note>浏览器加载后,ArticleMeasure 按当前窗口宽度重算拓宽边距,并在滚动时判断宽图是否挡住右侧目录。</note>
|
|
54
|
+
</step>
|
|
55
|
+
<step id="dark">
|
|
56
|
+
<title>深色衬底与灯箱</title>
|
|
57
|
+
<text>浅色纸底垫住黑线,点击可以放大</text>
|
|
58
|
+
<note>正文配图可以在当前页打开灯箱。深色模式下配图使用浅色纸底,不反色。</note>
|
|
59
|
+
</step>
|
|
60
|
+
</steps>
|
|
70
61
|
```
|
|
71
62
|
|
|
72
63
|
## 4. 深色模式配图衬底与暖纸墨色
|
|
@@ -21,7 +21,7 @@ Let the reader drag daily word count and writing days per week to see how many w
|
|
|
21
21
|
```
|
|
22
22
|
````
|
|
23
23
|
|
|
24
|
-
Draft posts (`draft: true`) may keep uncompiled idea fences; in non-draft posts, both `npx garden ui check` and `npx garden check` report a `garden-idea` error. Depending on the content, the Agent compiles the idea into a built-in component (`garden
|
|
24
|
+
Draft posts (`draft: true`) may keep uncompiled idea fences; in non-draft posts, both `npx garden ui check` and `npx garden check` report a `garden-idea` error. Depending on the content, the Agent compiles the idea into a built-in component (`garden compose`, `card`, `stat`, `compare`, and others) or replaces it with plain prose when a paragraph is clearer.
|
|
25
25
|
|
|
26
26
|
## 2. Three Bundled Skills
|
|
27
27
|
|
|
@@ -106,8 +106,8 @@ A component then takes four steps:
|
|
|
106
106
|
|
|
107
107
|
When writing components by hand without AI, you can use the templates and snippets shipped in the package:
|
|
108
108
|
|
|
109
|
-
- Every draft created by `make new` includes an HTML comment at the bottom with copy-ready examples for idea fences and
|
|
110
|
-
- `templates/garden-blocks.md` lists `when` / `whenNot` guidance and copyable templates for every block; macOS, Typora, and Alfred users can import `templates/garden-snippets.plist` to expand `;gidea`, `;gcard`, `;gstat`, `;gcompare`, `;gtimeline`, `;gchart`, `;
|
|
109
|
+
- Every draft created by `make new` includes an HTML comment at the bottom with copy-ready examples for idea fences and the built-in components; delete the comment whenever you are done.
|
|
110
|
+
- `templates/garden-blocks.md` lists `when` / `whenNot` guidance and copyable templates for every block; macOS, Typora, and Alfred users can import `templates/garden-snippets.plist` to expand `;gidea`, `;gcard`, `;gstat`, `;gcompare`, `;gtimeline`, `;gchart`, `;gcompose`, `;ghtml`, `;ginteractive`, `;gfile`, `;grel`, `;glist`, and `;gchoice`. `;gcompose` expands to a `garden compose` fence with one sentence.
|
|
111
111
|
- Editor plugin usage is in the previous section. `npx garden ui catalog` writes an offline component catalog at `.garden/ui-catalog.html`.
|
|
112
112
|
|
|
113
113
|
## 8. Optional Standalone Admin
|