velloo 0.4.1 → 0.6.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 +29 -7
- package/canvas/assets/index-CnyI3aig.js +29 -0
- package/canvas/assets/index-GNLd0pCG.css +2 -0
- package/canvas/assets/lucide-all-CH8LmVh0.js +1 -0
- package/canvas/index.html +2 -2
- package/{chunk-91pajfnm.js → chunk-08mjtg1e.js} +1 -1
- package/{chunk-m1wp8cpt.js → chunk-1gkeepkm.js} +1 -1
- package/{chunk-2dm4x17z.js → chunk-1td6z6ey.js} +1 -1
- package/{chunk-ykdx12na.js → chunk-2ba6edh8.js} +1 -1
- package/chunk-2q561dec.js +2 -0
- package/chunk-2web93qz.js +2 -0
- package/{chunk-py6sjyzk.js → chunk-3trkmgfr.js} +1 -1
- package/chunk-52m26hh4.js +3 -0
- package/{chunk-7xffbj5h.js → chunk-56vfy0db.js} +1 -1
- package/{chunk-8t5phg0s.js → chunk-56z5xd5b.js} +1 -1
- package/{chunk-xbhxzdat.js → chunk-63y5gdzw.js} +1 -1
- package/{chunk-t9ygewjx.js → chunk-6813v926.js} +257 -3
- package/{chunk-cejmmx3r.js → chunk-69qb8p8s.js} +2 -2
- package/chunk-6k05kqnc.js +3 -0
- package/chunk-74yxy75r.js +3 -0
- package/{chunk-7a45tn73.js → chunk-8cj4swpr.js} +5 -5
- package/chunk-8grzf8q1.js +2 -0
- package/chunk-8vam2893.js +3 -0
- package/{chunk-dj1pp4e3.js → chunk-8vgpffn7.js} +1 -1
- package/{chunk-j5axqyan.js → chunk-96qhpth5.js} +1 -1
- package/chunk-ab8fga32.js +22 -0
- package/chunk-azeqkms7.js +6 -0
- package/{chunk-2y9nnzpr.js → chunk-bc7pkjcn.js} +1 -1
- package/{chunk-7gtvstne.js → chunk-c4spp880.js} +1 -1
- package/{chunk-a9mgvspm.js → chunk-chtv0yj6.js} +211 -110
- package/{chunk-r9ekd92e.js → chunk-dar6wbf2.js} +1 -1
- package/{chunk-aa3str7g.js → chunk-e2btp1wd.js} +1 -1
- package/{chunk-hsrg23gd.js → chunk-eqjtq673.js} +1 -1
- package/chunk-esb7n55g.js +244 -0
- package/chunk-ey65err5.js +5 -0
- package/{chunk-r03aywsb.js → chunk-ff0jfn0v.js} +1 -1
- package/chunk-ff2vt7cz.js +12 -0
- package/chunk-g185gx8a.js +2 -0
- package/{chunk-km3z2czq.js → chunk-h85hv05d.js} +1 -1
- package/{chunk-db7mf114.js → chunk-hf4adxe0.js} +9 -7
- package/{chunk-6zr596r2.js → chunk-hjc5eg5c.js} +1 -1
- package/{chunk-b4jy4hcd.js → chunk-hsfpbjpc.js} +1 -1
- package/{chunk-ph94nrc8.js → chunk-jsvkqae2.js} +1 -1
- package/{chunk-rfrbnw8r.js → chunk-k423dkjz.js} +1 -1
- package/chunk-mfch0b0t.js +3 -0
- package/chunk-nbbnb5e9.js +3 -0
- package/{chunk-tr49kraa.js → chunk-nx09zqgs.js} +1 -1
- package/chunk-p93x4pn2.js +3 -0
- package/{chunk-k3dpwjx4.js → chunk-pxaxgkaq.js} +1 -1
- package/chunk-qwccndcd.js +5 -0
- package/{chunk-vjrn10xr.js → chunk-rjjc9vam.js} +2 -2
- package/{chunk-npsg7btt.js → chunk-rk238m15.js} +1 -1
- package/chunk-t2x3mztc.js +2 -0
- package/chunk-t6qr2ay9.js +3 -0
- package/chunk-ta84ehgg.js +2 -0
- package/chunk-tac2wvc7.js +2 -0
- package/chunk-tbd6wn3q.js +6 -0
- package/chunk-v6c3h9ft.js +3 -0
- package/chunk-w2naqxqt.js +2 -0
- package/chunk-wfhv9jg4.js +2 -0
- package/chunk-wnj432fw.js +3 -0
- package/chunk-x02z2ccm.js +2 -0
- package/{chunk-b58pnj20.js → chunk-xtwx2p9g.js} +1 -1
- package/chunk-yfvc8d2g.js +716 -0
- package/chunk-z73q4dq9.js +2 -0
- package/{chunk-yfttm20w.js → chunk-ztsckexy.js} +2 -2
- package/cli.js +1 -1
- package/package.json +3 -1
- package/pkgs/helpers/src/descriptors.ts +1 -0
- package/pkgs/helpers/src/index.ts +7 -4
- package/pkgs/helpers/src/lowering.ts +0 -24
- package/pkgs/helpers/src/primitive-classes.tsx +43 -0
- package/pkgs/provider-antd/src/intro.ts +3 -3
- package/pkgs/provider-antd/src/manifest.ts +478 -57
- package/pkgs/provider-antd/src/registry.ts +8 -5
- package/pkgs/provider-antd/src/render-pass.ts +10 -4
- package/pkgs/provider-antd/src/reset-css.d.ts +5 -0
- package/pkgs/provider-antd/src/theme.ts +54 -11
- package/pkgs/provider-chakra/src/manifest.ts +5 -1
- package/pkgs/provider-html/src/index.ts +68 -0
- package/pkgs/provider-html/src/registry.ts +121 -0
- package/pkgs/provider-html/src/version.ts +1 -0
- package/pkgs/provider-mui/src/index.ts +4 -2
- package/pkgs/provider-mui/src/manifest.ts +10 -1
- package/pkgs/provider-mui/src/render-pass.ts +15 -1
- package/pkgs/provider-mui/src/theme.ts +10 -4
- package/pkgs/provider-none/src/components-inline.tsx +12 -3
- package/pkgs/provider-none/src/components.tsx +26 -53
- package/pkgs/provider-none/src/manifest.ts +2 -0
- package/pkgs/schema/src/annotation.ts +6 -3
- package/pkgs/schema/src/comment.ts +10 -1
- package/pkgs/schema/src/config.ts +33 -1
- package/pkgs/schema/src/css-declarations.ts +41 -0
- package/pkgs/schema/src/index.ts +16 -1
- package/pkgs/schema/src/node-identity.ts +92 -0
- package/pkgs/schema/src/node.ts +13 -4
- package/pkgs/schema/src/theme.ts +46 -1
- package/pkgs/schema/src/typeset.ts +24 -17
- package/pkgs/shadcn-snapshot/dist/manifest.json +1 -0
- package/pkgs/shadcn-snapshot/src/components/ui/alert.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/aspect-ratio.tsx +2 -3
- package/pkgs/shadcn-snapshot/src/components/ui/attachment.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/avatar.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/badge.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/breadcrumb.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/bubble.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/button-group.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/button.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/card.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/carousel.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/chart.tsx +1 -1
- package/pkgs/shadcn-snapshot/src/components/ui/direction.tsx +2 -3
- package/pkgs/shadcn-snapshot/src/components/ui/empty.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/field.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/input-group.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/item.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/kbd.tsx +2 -3
- package/pkgs/shadcn-snapshot/src/components/ui/label.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/marker.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/message.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/native-select.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/navigation-menu.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/pagination.tsx +3 -4
- package/pkgs/shadcn-snapshot/src/components/ui/progress.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/radio-group.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/scroll-area.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/separator.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/skeleton.tsx +2 -3
- package/pkgs/shadcn-snapshot/src/components/ui/spinner.tsx +2 -3
- package/pkgs/shadcn-snapshot/src/components/ui/table.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/tabs.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/components/ui/toggle.tsx +2 -4
- package/pkgs/shadcn-snapshot/src/shadcn-tailwind.css +1 -1
- package/pkgs/shadcn-snapshot/src/tailwind-entry.css +1 -1
- package/plugins/claude/velloo/agents/velloo-design-reviewer.md +56 -13
- package/plugins/claude/velloo/agents/velloo-designer.md +4 -1
- package/skills/velloo-setup/SKILL.md +19 -55
- package/canvas/assets/index-B1OD0Yz5.css +0 -2
- package/canvas/assets/index-BWYFx2Rr.js +0 -29
- package/canvas/assets/lucide-all-Bcm80WFX.js +0 -1
- package/chunk-00t0bz7x.js +0 -244
- package/chunk-0446t32z.js +0 -2
- package/chunk-0zen7bzb.js +0 -3
- package/chunk-2h24va0j.js +0 -2
- package/chunk-2jbhv7vh.js +0 -3
- package/chunk-5ywkk7d6.js +0 -2
- package/chunk-b7famda5.js +0 -3
- package/chunk-cvn689d5.js +0 -3
- package/chunk-e6nhc3ay.js +0 -6
- package/chunk-f5g45xed.js +0 -2
- package/chunk-fjbzk4sw.js +0 -3
- package/chunk-hv52a6hf.js +0 -2
- package/chunk-jep31ffe.js +0 -2
- package/chunk-jwzhhhzn.js +0 -3
- package/chunk-mcymwefw.js +0 -5
- package/chunk-n0kx20s2.js +0 -2
- package/chunk-nwf2kn41.js +0 -26
- package/chunk-phz993p3.js +0 -2
- package/chunk-qan5dnjt.js +0 -688
- package/chunk-r5d0jsnd.js +0 -5
- package/chunk-shac6bat.js +0 -6
- package/chunk-t4zvcece.js +0 -10
- package/chunk-tarws372.js +0 -2
- package/chunk-yghypth2.js +0 -2
- package/chunk-zqtz23xk.js +0 -3
|
@@ -6,6 +6,12 @@ import type { ComponentDescriptor, Manifest, PropDescriptor } from "@velloo/prov
|
|
|
6
6
|
* children), which reads far better than a generated dump of antd's vast type
|
|
7
7
|
* surface. Mirrors the MUI adapter's curated-manifest stance; this stays the
|
|
8
8
|
* source of truth.
|
|
9
|
+
*
|
|
10
|
+
* Curated means leaving out handlers, render functions, deprecated aliases and
|
|
11
|
+
* prefixCls plumbing — not leaving out real visual props. A listed component
|
|
12
|
+
* warns on every prop it doesn't list, so a missing `strokeColor` teaches the
|
|
13
|
+
* agent that antd lacks it. Each entry was audited against antd's own prop
|
|
14
|
+
* types (`<Name>Props`) for every serializable, design-relevant prop.
|
|
9
15
|
*/
|
|
10
16
|
|
|
11
17
|
const style: PropDescriptor = {
|
|
@@ -62,6 +68,51 @@ const json = (name: string, type: string): PropDescriptor => ({
|
|
|
62
68
|
optional: true,
|
|
63
69
|
control: "string",
|
|
64
70
|
});
|
|
71
|
+
const color = (name: string): PropDescriptor => ({
|
|
72
|
+
name,
|
|
73
|
+
type: "string",
|
|
74
|
+
optional: true,
|
|
75
|
+
control: "color",
|
|
76
|
+
});
|
|
77
|
+
const css = (name: string): PropDescriptor => json(name, "CSSProperties");
|
|
78
|
+
/** antd's per-part inline styles (`styles={{ body: {…} }}`) — the style channel for inner parts. */
|
|
79
|
+
const styles = (parts: string): PropDescriptor =>
|
|
80
|
+
json(
|
|
81
|
+
"styles",
|
|
82
|
+
`{ ${parts
|
|
83
|
+
.split(" ")
|
|
84
|
+
.map((part) => `${part}?: CSSProperties`)
|
|
85
|
+
.join("; ")} }`,
|
|
86
|
+
);
|
|
87
|
+
const SIZES = ["small", "middle", "large"];
|
|
88
|
+
const STATUS = ["error", "warning"];
|
|
89
|
+
const VARIANTS = ["outlined", "borderless", "filled", "underlined"];
|
|
90
|
+
const PLACEMENTS = [
|
|
91
|
+
"top",
|
|
92
|
+
"left",
|
|
93
|
+
"right",
|
|
94
|
+
"bottom",
|
|
95
|
+
"topLeft",
|
|
96
|
+
"topRight",
|
|
97
|
+
"bottomLeft",
|
|
98
|
+
"bottomRight",
|
|
99
|
+
"leftTop",
|
|
100
|
+
"leftBottom",
|
|
101
|
+
"rightTop",
|
|
102
|
+
"rightBottom",
|
|
103
|
+
];
|
|
104
|
+
/** Typography's shared text decorations — Title, Text and Paragraph all take them. */
|
|
105
|
+
const TEXT_DECORATIONS: PropDescriptor[] = [
|
|
106
|
+
bool("code"),
|
|
107
|
+
bool("mark"),
|
|
108
|
+
bool("keyboard"),
|
|
109
|
+
bool("italic"),
|
|
110
|
+
bool("underline"),
|
|
111
|
+
bool("delete"),
|
|
112
|
+
bool("disabled"),
|
|
113
|
+
json("ellipsis", "boolean | { rows?: number; expandable?: boolean }"),
|
|
114
|
+
json("copyable", "boolean | { text?: string }"),
|
|
115
|
+
];
|
|
65
116
|
|
|
66
117
|
function ui(
|
|
67
118
|
id: string,
|
|
@@ -79,6 +130,21 @@ function ui(
|
|
|
79
130
|
};
|
|
80
131
|
}
|
|
81
132
|
|
|
133
|
+
/**
|
|
134
|
+
* An antd subcomponent whose real export is a dotted path. Neither a manifest id
|
|
135
|
+
* nor a JSX `$ref` can carry a dot, so it browses and composes under the flat id
|
|
136
|
+
* (`Typography.Title` ⇒ `TypographyTitle`) and emits as the dotted export — code
|
|
137
|
+
* the agent writes needs no destructure.
|
|
138
|
+
*/
|
|
139
|
+
function sub(
|
|
140
|
+
nativeExport: string,
|
|
141
|
+
props: PropDescriptor[],
|
|
142
|
+
notes?: string,
|
|
143
|
+
example?: Record<string, unknown>,
|
|
144
|
+
): ComponentDescriptor {
|
|
145
|
+
return { ...ui(nativeExport.replaceAll(".", ""), props, notes, example), nativeExport };
|
|
146
|
+
}
|
|
147
|
+
|
|
82
148
|
const className: PropDescriptor = {
|
|
83
149
|
name: "className",
|
|
84
150
|
type: "string | undefined",
|
|
@@ -113,7 +179,9 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
113
179
|
json("gap", '"small" | "middle" | "large" | number'),
|
|
114
180
|
str("align"),
|
|
115
181
|
str("justify"),
|
|
116
|
-
|
|
182
|
+
json("wrap", 'boolean | "wrap" | "nowrap" | "wrap-reverse"'),
|
|
183
|
+
json("flex", "string | number"),
|
|
184
|
+
str("component"),
|
|
117
185
|
],
|
|
118
186
|
"The flex layout primitive — use it for every row/column wrapper.",
|
|
119
187
|
{ vertical: false, gap: "middle", align: "center" },
|
|
@@ -123,20 +191,69 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
123
191
|
[
|
|
124
192
|
children,
|
|
125
193
|
enumProp("direction", ["horizontal", "vertical"], "horizontal"),
|
|
126
|
-
json("size", '"small" | "middle" | "large" | number'),
|
|
194
|
+
json("size", '"small" | "middle" | "large" | number | [number, number]'),
|
|
195
|
+
enumProp("align", ["start", "end", "center", "baseline"]),
|
|
196
|
+
bool("wrap"),
|
|
197
|
+
node("split"),
|
|
198
|
+
styles("item"),
|
|
127
199
|
],
|
|
128
200
|
"Inline spacing between adjacent items (buttons, tags).",
|
|
129
201
|
{ size: "middle" },
|
|
130
202
|
),
|
|
131
|
-
ui(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
203
|
+
ui(
|
|
204
|
+
"Row",
|
|
205
|
+
[
|
|
206
|
+
children,
|
|
207
|
+
json("gutter", "number | [number, number] | Partial<Record<Breakpoint, number>>"),
|
|
208
|
+
enumProp("align", ["top", "middle", "bottom", "stretch"]),
|
|
209
|
+
enumProp("justify", [
|
|
210
|
+
"start",
|
|
211
|
+
"end",
|
|
212
|
+
"center",
|
|
213
|
+
"space-around",
|
|
214
|
+
"space-between",
|
|
215
|
+
"space-evenly",
|
|
216
|
+
]),
|
|
217
|
+
bool("wrap"),
|
|
218
|
+
],
|
|
219
|
+
"Grid row; pair with Col spans (24-column grid).",
|
|
220
|
+
{ gutter: 16 },
|
|
221
|
+
),
|
|
222
|
+
ui(
|
|
223
|
+
"Col",
|
|
224
|
+
[
|
|
225
|
+
children,
|
|
226
|
+
num("span"),
|
|
227
|
+
num("offset"),
|
|
228
|
+
num("order"),
|
|
229
|
+
num("push"),
|
|
230
|
+
num("pull"),
|
|
231
|
+
json("flex", "string | number"),
|
|
232
|
+
...["xs", "sm", "md", "lg", "xl", "xxl"].map((bp) =>
|
|
233
|
+
json(bp, "number | { span?: number; offset?: number; order?: number }"),
|
|
234
|
+
),
|
|
235
|
+
],
|
|
236
|
+
"Grid column inside a Row; span is out of 24.",
|
|
237
|
+
{ span: 12 },
|
|
238
|
+
),
|
|
135
239
|
|
|
136
240
|
// --- surfaces + data display ---
|
|
137
241
|
ui(
|
|
138
242
|
"Card",
|
|
139
|
-
[
|
|
243
|
+
[
|
|
244
|
+
children,
|
|
245
|
+
node("title"),
|
|
246
|
+
node("extra"),
|
|
247
|
+
enumProp("size", ["default", "small"], "default"),
|
|
248
|
+
enumProp("variant", ["outlined", "borderless"], "outlined"),
|
|
249
|
+
bool("bordered"),
|
|
250
|
+
bool("hoverable"),
|
|
251
|
+
bool("loading"),
|
|
252
|
+
node("cover"),
|
|
253
|
+
json("actions", "ReactNode[]"),
|
|
254
|
+
enumProp("type", ["inner"]),
|
|
255
|
+
styles("header body extra title actions cover"),
|
|
256
|
+
],
|
|
140
257
|
"Card surface with an optional title bar.",
|
|
141
258
|
{ title: "Team" },
|
|
142
259
|
),
|
|
@@ -147,35 +264,97 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
147
264
|
node("description"),
|
|
148
265
|
enumProp("type", ["success", "info", "warning", "error"], "info"),
|
|
149
266
|
bool("showIcon"),
|
|
267
|
+
node("icon"),
|
|
268
|
+
node("action"),
|
|
269
|
+
bool("banner"),
|
|
270
|
+
bool("closable"),
|
|
150
271
|
],
|
|
151
272
|
"Inline alert banner. `message` is the headline; `description` the body.",
|
|
152
273
|
{ type: "info", message: "Workspace synced", showIcon: true },
|
|
153
274
|
),
|
|
154
275
|
ui(
|
|
155
276
|
"Tag",
|
|
156
|
-
[children, str("color")],
|
|
277
|
+
[children, str("color"), bool("bordered"), node("icon"), bool("closable")],
|
|
157
278
|
'Label chip. `color` takes a preset ("success", "processing", "error", "warning") or any CSS color.',
|
|
158
279
|
{ color: "success", children: "Active" },
|
|
159
280
|
),
|
|
160
281
|
ui(
|
|
161
282
|
"Badge",
|
|
162
|
-
[
|
|
283
|
+
[
|
|
284
|
+
children,
|
|
285
|
+
json("count", "number | ReactNode"),
|
|
286
|
+
bool("dot"),
|
|
287
|
+
num("overflowCount"),
|
|
288
|
+
bool("showZero"),
|
|
289
|
+
color("color"),
|
|
290
|
+
enumProp("status", ["success", "processing", "default", "error", "warning"]),
|
|
291
|
+
node("text"),
|
|
292
|
+
enumProp("size", ["default", "small"], "default"),
|
|
293
|
+
json("offset", "[number, number]"),
|
|
294
|
+
],
|
|
163
295
|
"Count/dot indicator wrapping its child (an Avatar, an icon).",
|
|
164
296
|
{ count: 5 },
|
|
165
297
|
),
|
|
166
|
-
ui(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
298
|
+
ui(
|
|
299
|
+
"Avatar",
|
|
300
|
+
[
|
|
301
|
+
children,
|
|
302
|
+
str("src"),
|
|
303
|
+
str("alt"),
|
|
304
|
+
json("size", '"large" | "small" | "default" | number'),
|
|
305
|
+
enumProp("shape", ["circle", "square"], "circle"),
|
|
306
|
+
node("icon"),
|
|
307
|
+
num("gap"),
|
|
308
|
+
],
|
|
309
|
+
"Avatar — `src` image or text children.",
|
|
310
|
+
{ children: "AB" },
|
|
311
|
+
),
|
|
312
|
+
ui("Divider", [
|
|
313
|
+
children,
|
|
314
|
+
enumProp("type", ["horizontal", "vertical"], "horizontal"),
|
|
315
|
+
enumProp("orientation", ["left", "right", "center", "start", "end"], "center"),
|
|
316
|
+
json("orientationMargin", "string | number"),
|
|
317
|
+
bool("dashed"),
|
|
318
|
+
enumProp("variant", ["solid", "dashed", "dotted"], "solid"),
|
|
319
|
+
bool("plain"),
|
|
320
|
+
]),
|
|
321
|
+
ui(
|
|
322
|
+
"Skeleton",
|
|
323
|
+
[
|
|
324
|
+
bool("active"),
|
|
325
|
+
json("avatar", "boolean | { shape?: 'circle' | 'square'; size?: number }"),
|
|
326
|
+
json(
|
|
327
|
+
"paragraph",
|
|
328
|
+
"boolean | { rows?: number; width?: number | string | (number | string)[] }",
|
|
329
|
+
),
|
|
330
|
+
bool("round"),
|
|
331
|
+
bool("loading"),
|
|
332
|
+
children,
|
|
333
|
+
],
|
|
334
|
+
"Loading placeholder blocks.",
|
|
335
|
+
{ active: true },
|
|
336
|
+
),
|
|
337
|
+
ui(
|
|
338
|
+
"Empty",
|
|
339
|
+
[node("description"), node("image"), children],
|
|
340
|
+
"Empty-state illustration + caption.",
|
|
341
|
+
{
|
|
342
|
+
description: "No data yet",
|
|
343
|
+
},
|
|
344
|
+
),
|
|
176
345
|
ui(
|
|
177
346
|
"Statistic",
|
|
178
|
-
[
|
|
347
|
+
[
|
|
348
|
+
node("title"),
|
|
349
|
+
json("value", "string | number"),
|
|
350
|
+
node("prefix"),
|
|
351
|
+
node("suffix"),
|
|
352
|
+
css("valueStyle"),
|
|
353
|
+
num("precision"),
|
|
354
|
+
str("groupSeparator"),
|
|
355
|
+
str("decimalSeparator"),
|
|
356
|
+
bool("loading"),
|
|
357
|
+
],
|
|
179
358
|
"A KPI number with a label.",
|
|
180
359
|
{ title: "Active users", value: 112893 },
|
|
181
360
|
),
|
|
@@ -185,32 +364,52 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
185
364
|
num("percent"),
|
|
186
365
|
enumProp("type", ["line", "circle", "dashboard"], "line"),
|
|
187
366
|
enumProp("status", ["normal", "active", "success", "exception"]),
|
|
367
|
+
json("strokeColor", "string | string[] | { from: string; to: string; direction?: string }"),
|
|
368
|
+
color("trailColor"),
|
|
369
|
+
bool("showInfo"),
|
|
370
|
+
json("size", '"small" | "default" | number | [number | string, number]'),
|
|
371
|
+
num("strokeWidth"),
|
|
372
|
+
enumProp("strokeLinecap", ["round", "butt", "square"], "round"),
|
|
373
|
+
num("steps"),
|
|
374
|
+
json("success", "{ percent?: number; strokeColor?: string }"),
|
|
375
|
+
num("gapDegree"),
|
|
376
|
+
json("percentPosition", '{ align?: "start" | "center" | "end"; type?: "inner" | "outer" }'),
|
|
188
377
|
],
|
|
189
378
|
undefined,
|
|
190
379
|
{ percent: 62 },
|
|
191
380
|
),
|
|
192
381
|
|
|
193
382
|
// --- typography (antd's Typography.* exposed as flat ids) ---
|
|
194
|
-
|
|
195
|
-
"
|
|
196
|
-
[
|
|
383
|
+
sub(
|
|
384
|
+
"Typography.Title",
|
|
385
|
+
[
|
|
386
|
+
children,
|
|
387
|
+
enumProp("level", [1, 2, 3, 4, 5], "1"),
|
|
388
|
+
enumProp("type", ["secondary", "success", "warning", "danger"]),
|
|
389
|
+
...TEXT_DECORATIONS,
|
|
390
|
+
],
|
|
197
391
|
"A heading — antd's Typography.Title. Pick `level` for the scale (1 largest).",
|
|
198
392
|
{ level: 2, children: "Team analytics" },
|
|
199
393
|
),
|
|
200
|
-
|
|
201
|
-
"
|
|
394
|
+
sub(
|
|
395
|
+
"Typography.Text",
|
|
202
396
|
[
|
|
203
397
|
children,
|
|
204
398
|
enumProp("type", ["secondary", "success", "warning", "danger"]),
|
|
205
399
|
bool("strong"),
|
|
206
|
-
|
|
400
|
+
...TEXT_DECORATIONS,
|
|
207
401
|
],
|
|
208
402
|
"Inline text — antd's Typography.Text. `type` picks the semantic tone.",
|
|
209
403
|
{ type: "secondary", children: "Updated 2 hours ago" },
|
|
210
404
|
),
|
|
211
|
-
|
|
212
|
-
"
|
|
213
|
-
[
|
|
405
|
+
sub(
|
|
406
|
+
"Typography.Paragraph",
|
|
407
|
+
[
|
|
408
|
+
children,
|
|
409
|
+
enumProp("type", ["secondary", "success", "warning", "danger"]),
|
|
410
|
+
bool("strong"),
|
|
411
|
+
...TEXT_DECORATIONS,
|
|
412
|
+
],
|
|
214
413
|
"Block paragraph — antd's Typography.Paragraph.",
|
|
215
414
|
{ children: "Body copy for a section." },
|
|
216
415
|
),
|
|
@@ -222,15 +421,42 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
222
421
|
children,
|
|
223
422
|
enumProp("type", ["primary", "default", "dashed", "text", "link"], "default"),
|
|
224
423
|
bool("danger"),
|
|
225
|
-
enumProp("size",
|
|
424
|
+
enumProp("size", SIZES, "middle"),
|
|
226
425
|
bool("block"),
|
|
426
|
+
node("icon"),
|
|
427
|
+
enumProp("iconPosition", ["start", "end"], "start"),
|
|
428
|
+
enumProp("shape", ["default", "circle", "round"], "default"),
|
|
429
|
+
enumProp("color", ["default", "primary", "danger"]),
|
|
430
|
+
enumProp("variant", ["outlined", "dashed", "solid", "filled", "text", "link"]),
|
|
431
|
+
bool("ghost"),
|
|
432
|
+
bool("loading"),
|
|
433
|
+
bool("disabled"),
|
|
434
|
+
str("href"),
|
|
435
|
+
enumProp("htmlType", ["button", "submit", "reset"], "button"),
|
|
436
|
+
styles("icon"),
|
|
227
437
|
],
|
|
228
438
|
"Action button.",
|
|
229
439
|
{ type: "primary", children: "Submit" },
|
|
230
440
|
),
|
|
231
441
|
ui(
|
|
232
442
|
"Input",
|
|
233
|
-
[
|
|
443
|
+
[
|
|
444
|
+
str("placeholder"),
|
|
445
|
+
str("value"),
|
|
446
|
+
enumProp("size", SIZES, "middle"),
|
|
447
|
+
str("type"),
|
|
448
|
+
node("prefix"),
|
|
449
|
+
node("suffix"),
|
|
450
|
+
node("addonBefore"),
|
|
451
|
+
node("addonAfter"),
|
|
452
|
+
bool("allowClear"),
|
|
453
|
+
bool("disabled"),
|
|
454
|
+
bool("readOnly"),
|
|
455
|
+
num("maxLength"),
|
|
456
|
+
bool("showCount"),
|
|
457
|
+
enumProp("status", STATUS),
|
|
458
|
+
enumProp("variant", VARIANTS, "outlined"),
|
|
459
|
+
],
|
|
234
460
|
undefined,
|
|
235
461
|
{ placeholder: "Email address" },
|
|
236
462
|
),
|
|
@@ -238,9 +464,19 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
238
464
|
"Select",
|
|
239
465
|
[
|
|
240
466
|
str("placeholder"),
|
|
241
|
-
|
|
467
|
+
json("value", "string | number | (string | number)[]"),
|
|
242
468
|
json("options", "{ value: string; label: string }[]"),
|
|
243
|
-
enumProp("size",
|
|
469
|
+
enumProp("size", SIZES, "middle"),
|
|
470
|
+
enumProp("mode", ["multiple", "tags"]),
|
|
471
|
+
bool("allowClear"),
|
|
472
|
+
bool("disabled"),
|
|
473
|
+
bool("loading"),
|
|
474
|
+
bool("showSearch"),
|
|
475
|
+
node("prefix"),
|
|
476
|
+
node("suffixIcon"),
|
|
477
|
+
json("maxTagCount", 'number | "responsive"'),
|
|
478
|
+
enumProp("status", STATUS),
|
|
479
|
+
enumProp("variant", VARIANTS, "outlined"),
|
|
244
480
|
],
|
|
245
481
|
"Closed select field in design mode (the dropdown is a portal).",
|
|
246
482
|
{
|
|
@@ -251,22 +487,68 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
251
487
|
],
|
|
252
488
|
},
|
|
253
489
|
),
|
|
254
|
-
ui("Checkbox", [children, bool("checked")], undefined, {
|
|
490
|
+
ui("Checkbox", [children, bool("checked"), bool("indeterminate"), bool("disabled")], undefined, {
|
|
255
491
|
checked: true,
|
|
256
492
|
children: "Remember me",
|
|
257
493
|
}),
|
|
258
|
-
ui(
|
|
259
|
-
|
|
260
|
-
checked
|
|
261
|
-
|
|
494
|
+
ui(
|
|
495
|
+
"Radio",
|
|
496
|
+
[children, bool("checked"), bool("disabled"), json("value", "string | number")],
|
|
497
|
+
undefined,
|
|
498
|
+
{ checked: true, children: "Monthly" },
|
|
499
|
+
),
|
|
500
|
+
ui(
|
|
501
|
+
"Switch",
|
|
502
|
+
[
|
|
503
|
+
bool("checked"),
|
|
504
|
+
enumProp("size", ["default", "small"], "default"),
|
|
505
|
+
bool("disabled"),
|
|
506
|
+
bool("loading"),
|
|
507
|
+
node("checkedChildren"),
|
|
508
|
+
node("unCheckedChildren"),
|
|
509
|
+
],
|
|
510
|
+
undefined,
|
|
511
|
+
{ checked: true },
|
|
512
|
+
),
|
|
262
513
|
ui(
|
|
263
514
|
"Segmented",
|
|
264
|
-
[
|
|
515
|
+
[
|
|
516
|
+
json("options", "(string | number | { label: ReactNode; value: string | number })[]"),
|
|
517
|
+
json("value", "string | number"),
|
|
518
|
+
enumProp("size", SIZES, "middle"),
|
|
519
|
+
bool("block"),
|
|
520
|
+
bool("disabled"),
|
|
521
|
+
bool("vertical"),
|
|
522
|
+
enumProp("shape", ["default", "round"], "default"),
|
|
523
|
+
],
|
|
265
524
|
"Segmented control.",
|
|
266
525
|
{ options: ["Daily", "Weekly", "Monthly"], value: "Weekly" },
|
|
267
526
|
),
|
|
268
|
-
ui(
|
|
269
|
-
|
|
527
|
+
ui(
|
|
528
|
+
"Slider",
|
|
529
|
+
[
|
|
530
|
+
json("value", "number | [number, number]"),
|
|
531
|
+
num("min"),
|
|
532
|
+
num("max"),
|
|
533
|
+
num("step"),
|
|
534
|
+
bool("range"),
|
|
535
|
+
json("marks", "Record<number, ReactNode>"),
|
|
536
|
+
bool("dots"),
|
|
537
|
+
bool("included"),
|
|
538
|
+
bool("reverse"),
|
|
539
|
+
bool("vertical"),
|
|
540
|
+
bool("disabled"),
|
|
541
|
+
styles("track tracks rail handle"),
|
|
542
|
+
],
|
|
543
|
+
undefined,
|
|
544
|
+
{ value: 30 },
|
|
545
|
+
),
|
|
546
|
+
ui(
|
|
547
|
+
"Rate",
|
|
548
|
+
[num("value"), num("count"), bool("allowHalf"), bool("disabled"), node("character")],
|
|
549
|
+
"Star rating.",
|
|
550
|
+
{ value: 4 },
|
|
551
|
+
),
|
|
270
552
|
|
|
271
553
|
// --- data ---
|
|
272
554
|
ui(
|
|
@@ -276,6 +558,18 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
276
558
|
json("dataSource", "Record<string, ReactNode>[] (each row needs a `key`)"),
|
|
277
559
|
enumProp("size", ["large", "middle", "small"], "large"),
|
|
278
560
|
json("pagination", "false | object"),
|
|
561
|
+
bool("bordered"),
|
|
562
|
+
bool("loading"),
|
|
563
|
+
bool("showHeader"),
|
|
564
|
+
str("rowKey"),
|
|
565
|
+
json("scroll", "{ x?: number | string; y?: number | string }"),
|
|
566
|
+
bool("sticky"),
|
|
567
|
+
enumProp("tableLayout", ["auto", "fixed"]),
|
|
568
|
+
json(
|
|
569
|
+
"rowSelection",
|
|
570
|
+
'{ type?: "checkbox" | "radio"; selectedRowKeys?: (string | number)[] }',
|
|
571
|
+
),
|
|
572
|
+
node("caption"),
|
|
279
573
|
],
|
|
280
574
|
"Data table — drive it with `columns` + `dataSource` (no render functions in design JSON).",
|
|
281
575
|
{
|
|
@@ -292,20 +586,44 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
292
586
|
),
|
|
293
587
|
ui(
|
|
294
588
|
"List",
|
|
295
|
-
[
|
|
589
|
+
[
|
|
590
|
+
children,
|
|
591
|
+
enumProp("size", ["default", "small", "large"], "default"),
|
|
592
|
+
bool("bordered"),
|
|
593
|
+
node("header"),
|
|
594
|
+
node("footer"),
|
|
595
|
+
bool("split"),
|
|
596
|
+
enumProp("itemLayout", ["horizontal", "vertical"], "horizontal"),
|
|
597
|
+
bool("loading"),
|
|
598
|
+
json("grid", "{ gutter?: number; column?: number }"),
|
|
599
|
+
],
|
|
296
600
|
"Compose with ListItem children (skip `dataSource`/`renderItem` — functions don't fit design JSON).",
|
|
297
601
|
{ bordered: true },
|
|
298
602
|
),
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
"
|
|
603
|
+
sub(
|
|
604
|
+
"List.Item",
|
|
605
|
+
[children, node("extra"), json("actions", "ReactNode[]")],
|
|
606
|
+
"One row inside a List — antd's List.Item.",
|
|
607
|
+
),
|
|
608
|
+
sub(
|
|
609
|
+
"List.Item.Meta",
|
|
302
610
|
[node("title"), node("description"), node("avatar")],
|
|
303
611
|
"Title/description/avatar layout inside a ListItem — antd's List.Item.Meta.",
|
|
304
612
|
{ title: "Deploy finished", description: "2 minutes ago" },
|
|
305
613
|
),
|
|
306
614
|
ui(
|
|
307
615
|
"Tabs",
|
|
308
|
-
[
|
|
616
|
+
[
|
|
617
|
+
json("items", "{ key: string; label: string; children?: ReactNode }[]"),
|
|
618
|
+
str("activeKey"),
|
|
619
|
+
enumProp("type", ["line", "card", "editable-card"], "line"),
|
|
620
|
+
enumProp("size", SIZES, "middle"),
|
|
621
|
+
bool("centered"),
|
|
622
|
+
enumProp("tabPosition", ["top", "right", "bottom", "left"], "top"),
|
|
623
|
+
node("tabBarExtraContent"),
|
|
624
|
+
num("tabBarGutter"),
|
|
625
|
+
css("tabBarStyle"),
|
|
626
|
+
],
|
|
309
627
|
"Tab bar + active pane, driven by `items`.",
|
|
310
628
|
{
|
|
311
629
|
items: [
|
|
@@ -316,23 +634,54 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
316
634
|
),
|
|
317
635
|
ui(
|
|
318
636
|
"Steps",
|
|
319
|
-
[
|
|
637
|
+
[
|
|
638
|
+
num("current"),
|
|
639
|
+
json("items", "{ title: string; description?: string }[]"),
|
|
640
|
+
enumProp("direction", ["horizontal", "vertical"], "horizontal"),
|
|
641
|
+
enumProp("size", ["default", "small"], "default"),
|
|
642
|
+
enumProp("status", ["wait", "process", "finish", "error"], "process"),
|
|
643
|
+
enumProp("type", ["default", "navigation", "inline"], "default"),
|
|
644
|
+
enumProp("labelPlacement", ["horizontal", "vertical"], "horizontal"),
|
|
645
|
+
bool("progressDot"),
|
|
646
|
+
num("percent"),
|
|
647
|
+
num("initial"),
|
|
648
|
+
],
|
|
320
649
|
undefined,
|
|
321
650
|
{ current: 1, items: [{ title: "Build" }, { title: "Review" }, { title: "Ship" }] },
|
|
322
651
|
),
|
|
323
|
-
ui("Breadcrumb", [json("items", "{ title: ReactNode }[]")], undefined, {
|
|
652
|
+
ui("Breadcrumb", [json("items", "{ title: ReactNode }[]"), node("separator")], undefined, {
|
|
324
653
|
items: [{ title: "Home" }, { title: "Reports" }],
|
|
325
654
|
}),
|
|
326
|
-
ui(
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
655
|
+
ui(
|
|
656
|
+
"Pagination",
|
|
657
|
+
[
|
|
658
|
+
num("current"),
|
|
659
|
+
num("total"),
|
|
660
|
+
num("pageSize"),
|
|
661
|
+
bool("simple"),
|
|
662
|
+
enumProp("size", ["default", "small"], "default"),
|
|
663
|
+
enumProp("align", ["start", "center", "end"], "start"),
|
|
664
|
+
bool("showSizeChanger"),
|
|
665
|
+
bool("showQuickJumper"),
|
|
666
|
+
bool("showLessItems"),
|
|
667
|
+
bool("hideOnSinglePage"),
|
|
668
|
+
bool("disabled"),
|
|
669
|
+
],
|
|
670
|
+
undefined,
|
|
671
|
+
{ current: 1, total: 50 },
|
|
672
|
+
),
|
|
330
673
|
ui(
|
|
331
674
|
"Menu",
|
|
332
675
|
[
|
|
333
676
|
json("items", "{ key: string; label: ReactNode; icon?: ReactNode }[]"),
|
|
334
677
|
enumProp("mode", ["vertical", "horizontal", "inline"], "vertical"),
|
|
335
678
|
json("selectedKeys", "string[]"),
|
|
679
|
+
json("openKeys", "string[]"),
|
|
680
|
+
enumProp("theme", ["light", "dark"], "light"),
|
|
681
|
+
bool("inlineCollapsed"),
|
|
682
|
+
num("inlineIndent"),
|
|
683
|
+
bool("selectable"),
|
|
684
|
+
bool("multiple"),
|
|
336
685
|
],
|
|
337
686
|
"Navigation menu driven by `items` (antd v5 dropped JSX children menus).",
|
|
338
687
|
{
|
|
@@ -350,31 +699,89 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
350
699
|
// directly inside them. ---
|
|
351
700
|
ui(
|
|
352
701
|
"Modal",
|
|
353
|
-
[
|
|
702
|
+
[
|
|
703
|
+
children,
|
|
704
|
+
node("title"),
|
|
705
|
+
json("width", "number | string"),
|
|
706
|
+
node("footer"),
|
|
707
|
+
bool("open"),
|
|
708
|
+
bool("centered"),
|
|
709
|
+
bool("closable"),
|
|
710
|
+
node("okText"),
|
|
711
|
+
node("cancelText"),
|
|
712
|
+
enumProp("okType", ["primary", "default", "dashed", "text", "link"], "primary"),
|
|
713
|
+
bool("confirmLoading"),
|
|
714
|
+
bool("loading"),
|
|
715
|
+
json("okButtonProps", "ButtonProps"),
|
|
716
|
+
json("cancelButtonProps", "ButtonProps"),
|
|
717
|
+
styles("header body footer content mask"),
|
|
718
|
+
],
|
|
354
719
|
"Modal dialog surface — renders open + inline in design mode. Put the body in children; `footer` renders as a right-aligned action row.",
|
|
355
720
|
{ title: "Delete item?" },
|
|
356
721
|
),
|
|
357
722
|
ui(
|
|
358
723
|
"Drawer",
|
|
359
|
-
[
|
|
724
|
+
[
|
|
725
|
+
children,
|
|
726
|
+
node("title"),
|
|
727
|
+
node("extra"),
|
|
728
|
+
node("footer"),
|
|
729
|
+
bool("open"),
|
|
730
|
+
enumProp("placement", ["top", "right", "bottom", "left"], "right"),
|
|
731
|
+
enumProp("size", ["default", "large"], "default"),
|
|
732
|
+
json("width", "number | string"),
|
|
733
|
+
json("height", "number | string"),
|
|
734
|
+
bool("closable"),
|
|
735
|
+
bool("loading"),
|
|
736
|
+
styles("header body footer content wrapper mask"),
|
|
737
|
+
],
|
|
360
738
|
"A side panel — renders inline as a fixed-width column in design mode.",
|
|
361
739
|
{ title: "Filters" },
|
|
362
740
|
),
|
|
363
741
|
ui(
|
|
364
742
|
"Popover",
|
|
365
|
-
[
|
|
743
|
+
[
|
|
744
|
+
children,
|
|
745
|
+
node("title"),
|
|
746
|
+
node("content"),
|
|
747
|
+
enumProp("placement", PLACEMENTS, "top"),
|
|
748
|
+
bool("open"),
|
|
749
|
+
json("arrow", "boolean | { pointAtCenter?: boolean }"),
|
|
750
|
+
color("color"),
|
|
751
|
+
styles("root body"),
|
|
752
|
+
],
|
|
366
753
|
"A popover — the trigger child renders inline with the surface pinned open below it.",
|
|
367
754
|
{ title: "Details", content: "Popover body" },
|
|
368
755
|
),
|
|
369
756
|
ui(
|
|
370
757
|
"Tooltip",
|
|
371
|
-
[
|
|
758
|
+
[
|
|
759
|
+
children,
|
|
760
|
+
node("title"),
|
|
761
|
+
enumProp("placement", PLACEMENTS, "top"),
|
|
762
|
+
bool("open"),
|
|
763
|
+
json("arrow", "boolean | { pointAtCenter?: boolean }"),
|
|
764
|
+
color("color"),
|
|
765
|
+
styles("root body"),
|
|
766
|
+
],
|
|
372
767
|
"The trigger child renders inline; `title` shows beside it as a dark pill in design mode.",
|
|
373
768
|
{ title: "Copy to clipboard" },
|
|
374
769
|
),
|
|
375
770
|
ui(
|
|
376
771
|
"Dropdown",
|
|
377
|
-
[
|
|
772
|
+
[
|
|
773
|
+
children,
|
|
774
|
+
json("menu", "{ items: { key: string; label: ReactNode }[] }"),
|
|
775
|
+
enumProp(
|
|
776
|
+
"placement",
|
|
777
|
+
["bottomLeft", "bottom", "bottomRight", "topLeft", "top", "topRight"],
|
|
778
|
+
"bottomLeft",
|
|
779
|
+
),
|
|
780
|
+
bool("open"),
|
|
781
|
+
json("arrow", "boolean | { pointAtCenter?: boolean }"),
|
|
782
|
+
json("trigger", '("click" | "hover" | "contextMenu")[]'),
|
|
783
|
+
bool("disabled"),
|
|
784
|
+
],
|
|
378
785
|
"The trigger child renders inline with the menu surface pinned open below it.",
|
|
379
786
|
{
|
|
380
787
|
menu: {
|
|
@@ -386,6 +793,20 @@ export const ANTD_MANIFEST: Manifest = [
|
|
|
386
793
|
},
|
|
387
794
|
),
|
|
388
795
|
|
|
796
|
+
// antd has no plain element: `Flex`/`Space` always lay out. Box is what a
|
|
797
|
+
// lowercase `<div>`/`<span>` in compose becomes, and what wraps text written
|
|
798
|
+
// beside an element, so it takes this folder's style channel and emits as the
|
|
799
|
+
// bare HTML element.
|
|
800
|
+
{
|
|
801
|
+
id: "Box",
|
|
802
|
+
category: "ui",
|
|
803
|
+
source: "velloo",
|
|
804
|
+
plainElement: true,
|
|
805
|
+
props: [children, { name: "as", type: "string", optional: true, control: "string" }, style],
|
|
806
|
+
designModeNotes:
|
|
807
|
+
'A plain HTML element — a div unless `as` names another lowercase tag ("span", "section", "ul"). Compose writes `<div>`/`<span>` as Box for you. Emits as the bare element with its `style`. Reach for antd\'s `Flex`/`Space` for layout and `Typography*` for text first.',
|
|
808
|
+
},
|
|
809
|
+
|
|
389
810
|
// Framework-neutral velloo helpers (antd's @ant-design/icons isn't shipped).
|
|
390
811
|
// source:"velloo" — sized/styled via props (NOT the antd style channel or
|
|
391
812
|
// Tailwind: an antd folder has no JIT). `Icon` emits a lucide-react import
|