magick-ui 0.1.0 → 0.1.2

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/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,14 +17,27 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var src_exports = {};
22
32
  __export(src_exports, {
23
- ButtonGroupPrimitive: () => ButtonGroupPrimitive,
24
- CardPrimitive: () => CardPrimitive,
25
- KeyValuePrimitive: () => KeyValuePrimitive,
33
+ Button: () => Button,
34
+ Card: () => Card,
35
+ CardAction: () => CardAction,
36
+ CardContent: () => CardContent,
37
+ CardDescription: () => CardDescription,
38
+ CardFooter: () => CardFooter,
39
+ CardHeader: () => CardHeader,
40
+ CardTitle: () => CardTitle,
26
41
  UIRenderer: () => UIRenderer,
27
42
  cn: () => cn,
28
43
  componentSchema: () => componentSchema,
@@ -37,294 +52,381 @@ __export(src_exports, {
37
52
  });
38
53
  module.exports = __toCommonJS(src_exports);
39
54
 
40
- // src/primitives/CardPrimitive.tsx
55
+ // src/utils.ts
56
+ var import_clsx = require("clsx");
57
+ var import_tailwind_merge = require("tailwind-merge");
58
+ function cn(...inputs) {
59
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
60
+ }
61
+
62
+ // src/ui/Card.tsx
41
63
  var import_jsx_runtime = require("react/jsx-runtime");
42
- function CardPrimitive({
43
- title,
44
- subtitle,
45
- children
46
- }) {
47
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
64
+ function Card({ className, ...props }) {
65
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
48
66
  "div",
49
67
  {
50
- style: {
51
- width: "100%",
52
- maxWidth: "28rem",
53
- overflow: "hidden",
54
- borderRadius: "1rem",
55
- border: "1px solid var(--gen-ui-border, #e2e8f0)",
56
- backgroundColor: "var(--gen-ui-card-bg, #ffffff)"
57
- },
58
- children: [
59
- (title || subtitle) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
60
- "div",
61
- {
62
- style: {
63
- padding: "0.75rem 1rem",
64
- borderBottom: "1px solid var(--gen-ui-border, #e2e8f0)"
65
- },
66
- children: [
67
- title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
68
- "h3",
69
- {
70
- style: {
71
- margin: 0,
72
- fontSize: "0.875rem",
73
- fontWeight: 600,
74
- color: "var(--gen-ui-text, #1a202c)"
75
- },
76
- children: title
77
- }
78
- ),
79
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
80
- "p",
81
- {
82
- style: {
83
- margin: "0.125rem 0 0",
84
- fontSize: "0.75rem",
85
- color: "var(--gen-ui-text-muted, #718096)"
86
- },
87
- children: subtitle
88
- }
89
- )
90
- ]
91
- }
92
- ),
93
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { padding: "1rem", display: "flex", flexDirection: "column", gap: "0.75rem" }, children })
94
- ]
68
+ "data-slot": "card",
69
+ className: cn(
70
+ "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
71
+ className
72
+ ),
73
+ ...props
95
74
  }
96
75
  );
97
76
  }
98
-
99
- // src/primitives/KeyValuePrimitive.tsx
100
- var import_jsx_runtime2 = require("react/jsx-runtime");
101
- function KeyValuePrimitive({
102
- items = []
103
- }) {
104
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
77
+ function CardHeader({ className, ...props }) {
78
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
105
79
  "div",
106
80
  {
107
- style: {
108
- display: "flex",
109
- alignItems: "baseline",
110
- justifyContent: "space-between",
111
- gap: "1rem"
112
- },
113
- children: [
114
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
115
- "span",
116
- {
117
- style: {
118
- flexShrink: 0,
119
- fontSize: "0.75rem",
120
- fontWeight: 500,
121
- color: "var(--gen-ui-text-muted, #718096)"
122
- },
123
- children: item.label
124
- }
125
- ),
126
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
127
- "span",
128
- {
129
- style: {
130
- fontSize: "0.875rem",
131
- fontWeight: 500,
132
- textAlign: "right",
133
- overflow: "hidden",
134
- textOverflow: "ellipsis",
135
- whiteSpace: "nowrap",
136
- color: "var(--gen-ui-text, #1a202c)"
137
- },
138
- children: item.value
139
- }
140
- )
141
- ]
142
- },
143
- i
144
- )) });
81
+ "data-slot": "card-header",
82
+ className: cn(
83
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
84
+ className
85
+ ),
86
+ ...props
87
+ }
88
+ );
145
89
  }
146
-
147
- // src/primitives/ButtonGroupPrimitive.tsx
148
- var import_jsx_runtime3 = require("react/jsx-runtime");
149
- var variantStyles = {
150
- primary: {
151
- backgroundColor: "var(--gen-ui-btn-primary-bg, #3182ce)",
152
- color: "var(--gen-ui-btn-primary-text, #ffffff)",
153
- border: "none"
154
- },
155
- secondary: {
156
- backgroundColor: "var(--gen-ui-btn-secondary-bg, #edf2f7)",
157
- color: "var(--gen-ui-btn-secondary-text, #2d3748)",
158
- border: "none"
159
- },
160
- outline: {
161
- backgroundColor: "transparent",
162
- color: "var(--gen-ui-btn-outline-text, #2d3748)",
163
- border: "1px solid var(--gen-ui-border, #e2e8f0)"
164
- }
165
- };
166
- function ButtonGroupPrimitive({
167
- buttons = []
168
- }) {
169
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.5rem" }, children: buttons.map((btn, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
170
- "button",
90
+ function CardTitle({ className, ...props }) {
91
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
92
+ "div",
93
+ {
94
+ "data-slot": "card-title",
95
+ className: cn("leading-none font-semibold", className),
96
+ ...props
97
+ }
98
+ );
99
+ }
100
+ function CardDescription({ className, ...props }) {
101
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
102
+ "div",
171
103
  {
172
- style: {
173
- padding: "0.375rem 0.75rem",
174
- fontSize: "0.875rem",
175
- fontWeight: 500,
176
- borderRadius: "0.5rem",
177
- cursor: "pointer",
178
- ...variantStyles[btn.variant ?? "primary"]
104
+ "data-slot": "card-description",
105
+ className: cn("text-muted-foreground text-sm", className),
106
+ ...props
107
+ }
108
+ );
109
+ }
110
+ function CardAction({ className, ...props }) {
111
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
112
+ "div",
113
+ {
114
+ "data-slot": "card-action",
115
+ className: cn(
116
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
117
+ className
118
+ ),
119
+ ...props
120
+ }
121
+ );
122
+ }
123
+ function CardContent({ className, ...props }) {
124
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
125
+ "div",
126
+ {
127
+ "data-slot": "card-content",
128
+ className: cn("px-6", className),
129
+ ...props
130
+ }
131
+ );
132
+ }
133
+ function CardFooter({ className, ...props }) {
134
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
135
+ "div",
136
+ {
137
+ "data-slot": "card-footer",
138
+ className: cn("flex items-center px-6 [.border-t]:pt-6", className),
139
+ ...props
140
+ }
141
+ );
142
+ }
143
+
144
+ // src/ui/Button.tsx
145
+ var import_react_slot = require("@radix-ui/react-slot");
146
+ var import_class_variance_authority = require("class-variance-authority");
147
+ var import_lucide_react = require("lucide-react");
148
+ var React = __toESM(require("react"), 1);
149
+ var import_jsx_runtime2 = require("react/jsx-runtime");
150
+ var buttonVariants = (0, import_class_variance_authority.cva)(
151
+ "flex group leading-body-sm line-height-body-sm items-center cursor-pointer justify-center gap-2 whitespace-nowrap rounded-md font-medium transition-all disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-[20px] shrink-0 [&_svg]:shrink-0 outline-none ring-0",
152
+ {
153
+ variants: {
154
+ variant: {
155
+ // default:
156
+ // "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
157
+ primary: "bg-button-primary-enabled text-element-static-white! hover:bg-button-primary-hovered active:bg-button-primary-pressed focus-visible:bg-button-primary-pressed disabled:bg-button-primary-disabled disabled:text-element-inverse-disabled!",
158
+ secondary: "bg-button-secondary-enabled text-element-inverse-default-alt! hover:bg-button-secondary-hovered active:bg-button-secondary-pressed disabled:bg-button-secondary-disabled disabled:text-element-inverse-disabled!",
159
+ destructive: "bg-button-destructive-enabled text-element-static-white! hover:bg-button-destructive-hovered active:bg-button-destructive-pressed disabled:bg-button-destructive-disabled disabled:text-element-inverse-disabled!",
160
+ outline: "border border-stroke-inverse-slate-03 text-element-inverse-default rounded-unit-corner-radius-lg bg-button-outline-enabled hover:bg-button-outline-hovered active:bg-button-outline-pressed disabled:bg-button-outline-disabled disabled:text-element-inverse-disabled!",
161
+ ghost: "bg-transparent text-element-inverse-default hover:bg-button-ghost-hovered active:bg-button-ghost-pressed disabled:bg-button-ghost-disabled disabled:text-element-inverse-disabled!",
162
+ soft: "bg-button-soft-enabled text-element-inverse-default hover:bg-button-soft-hovered active:bg-button-soft-pressed disabled:bg-button-soft-disabled disabled:text-element-inverse-disabled!",
163
+ "ai-filled": "relative",
164
+ "ai-outline": "relative",
165
+ glass: "glass-effect bg-button-glass-enabled border border-stroke-inverse-slate-01 hover:bg-button-glass-hovered active:bg-button-glass-pressed disabled:bg-button-glass-disabled"
179
166
  },
180
- onClick: () => {
181
- if (btn.url) window.open(btn.url, "_blank");
167
+ size: {
168
+ sm: "rounded-lg gap-1 px-1.5 py-1 text-body-sm",
169
+ // "icon-sm": "p-4px rounded-md ",
170
+ md: "px-2.5 py-2 rounded-[10px] gap-2 text-body-sm",
171
+ // "icon-md": "rounded-lg p-2",
172
+ lg: "px-3.5 py-3 rounded-xl gap-2 text-body-lg"
173
+ // "icon-lg": "rounded-xl p-3",
182
174
  },
183
- children: btn.label
175
+ state: {
176
+ loading: "opacity-80 cursor-progress",
177
+ default: ""
178
+ }
184
179
  },
185
- i
186
- )) });
180
+ defaultVariants: {
181
+ variant: "primary",
182
+ size: "md",
183
+ state: "default"
184
+ }
185
+ }
186
+ );
187
+ function getButtonPadding(size, prefix, suffix, onlyIcon) {
188
+ if (prefix && suffix) {
189
+ if (size === "sm") return "px-1.5";
190
+ if (size === "md") return "p-2.5";
191
+ if (size === "lg") return "px-3";
192
+ } else if (prefix) {
193
+ if (size === "sm") return "pl-1.5 pr-2";
194
+ if (size === "md") return "pl-2.5 py-2.5 pr-3";
195
+ if (size === "lg") return "pl-3.5 pr-4";
196
+ } else if (suffix) {
197
+ if (size === "sm") return "pr-1.5 pl-2";
198
+ if (size === "md") return "pl-3";
199
+ if (size === "lg") return "pr-3.5 pl-4";
200
+ } else if (onlyIcon) {
201
+ if (size === "sm") return "p-1";
202
+ if (size === "md") return "p-2";
203
+ if (size === "lg") return "p-3";
204
+ }
205
+ return "";
206
+ }
207
+ function Button({
208
+ className,
209
+ variant = "primary",
210
+ state,
211
+ size = "md",
212
+ prefix,
213
+ suffix,
214
+ onlyIcon,
215
+ label,
216
+ url,
217
+ asChild = false,
218
+ children,
219
+ ...props
220
+ }) {
221
+ const Comp = asChild ? import_react_slot.Slot : "button";
222
+ const isDisabled = state === "loading" || props.disabled;
223
+ const content = children ?? label;
224
+ const handleClick = url ? (e) => {
225
+ props.onClick?.(e);
226
+ window.open(url, "_blank");
227
+ } : props.onClick;
228
+ const renderAffix = (node) => {
229
+ if (!node) return null;
230
+ if (React.isValidElement(node)) {
231
+ const nodeElement = node;
232
+ return React.cloneElement(nodeElement, {
233
+ className: cn(
234
+ nodeElement.props?.className || "",
235
+ isDisabled && "text-element-inverse-disabled"
236
+ )
237
+ });
238
+ }
239
+ return node;
240
+ };
241
+ if (variant === "ai-filled" || variant === "ai-outline") {
242
+ const isAiFilled = variant === "ai-filled";
243
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
244
+ Comp,
245
+ {
246
+ "data-variant": variant,
247
+ "data-slot": "button",
248
+ className: cn("group relative cursor-pointer p-0.5"),
249
+ disabled: isDisabled,
250
+ ...props,
251
+ onClick: handleClick,
252
+ children: [
253
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
254
+ "div",
255
+ {
256
+ className: cn(
257
+ "absolute inset-0 block",
258
+ buttonVariants({ size, className })
259
+ ),
260
+ style: {
261
+ backgroundImage: `url(${""})`,
262
+ backgroundSize: "cover",
263
+ backgroundPosition: "center"
264
+ }
265
+ }
266
+ ),
267
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
268
+ "div",
269
+ {
270
+ className: cn(
271
+ buttonVariants({ variant, size, className }),
272
+ size === "sm" && "rounded-[7px]",
273
+ size === "md" && "rounded-[9px]",
274
+ size === "lg" && "rounded-[11px]",
275
+ getButtonPadding(size, prefix, suffix, onlyIcon),
276
+ {
277
+ "gap-1": size === "sm",
278
+ "hover:text-element-inverse-default text-white hover:bg-white": isAiFilled,
279
+ "text-element-inverse-default dark:bg-fill-background bg-white hover:bg-transparent hover:text-white": !isAiFilled
280
+ }
281
+ ),
282
+ children: [
283
+ state === "loading" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Loader2Icon, { className: "animate-spin" }),
284
+ renderAffix(prefix),
285
+ content,
286
+ renderAffix(suffix)
287
+ ]
288
+ }
289
+ )
290
+ ]
291
+ }
292
+ );
293
+ }
294
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
295
+ Comp,
296
+ {
297
+ "data-variant": variant,
298
+ "data-slot": "button",
299
+ className: cn(
300
+ buttonVariants({ variant, size, className }),
301
+ getButtonPadding(size || "md", prefix, suffix, onlyIcon || false)
302
+ ),
303
+ disabled: isDisabled,
304
+ ...props,
305
+ onClick: handleClick,
306
+ children: [
307
+ state === "loading" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Loader2Icon, { className: "animate-spin" }),
308
+ renderAffix(prefix),
309
+ content,
310
+ renderAffix(suffix)
311
+ ]
312
+ }
313
+ );
187
314
  }
188
315
 
189
316
  // src/renderer.tsx
190
- var import_jsx_runtime4 = require("react/jsx-runtime");
191
- var defaultPrimitives = {
192
- card: CardPrimitive,
193
- "key-value": KeyValuePrimitive,
194
- "button-group": ButtonGroupPrimitive
195
- };
196
- var registeredPrimitives = {
197
- ...defaultPrimitives
317
+ var import_jsx_runtime3 = require("react/jsx-runtime");
318
+ var defaultComponents = {
319
+ card: Card,
320
+ "card-header": CardHeader,
321
+ "card-title": CardTitle,
322
+ "card-description": CardDescription,
323
+ "card-content": CardContent,
324
+ "card-footer": CardFooter,
325
+ button: Button
198
326
  };
199
- function registerPrimitives(primitives) {
200
- registeredPrimitives = { ...registeredPrimitives, ...primitives };
327
+ var registry = { ...defaultComponents };
328
+ function registerPrimitives(components) {
329
+ registry = { ...registry, ...components };
201
330
  }
202
331
  function isUINode(data) {
203
- return typeof data === "object" && data !== null && "type" in data && typeof data.type === "string" && data.type in registeredPrimitives;
332
+ return typeof data === "object" && data !== null && "type" in data && typeof data.type === "string" && data.type in registry;
204
333
  }
205
334
  function getAvailablePrimitives() {
206
- return Object.keys(registeredPrimitives);
335
+ return Object.keys(registry);
207
336
  }
208
337
  function UIRenderer({ node }) {
209
- const Component = registeredPrimitives[node.type];
338
+ const Component = registry[node.type];
210
339
  if (!Component) return null;
211
- const childElements = node.children?.map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(UIRenderer, { node: child }, i));
212
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Component, { ...node.props ?? {}, children: childElements });
340
+ const childElements = node.children?.map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UIRenderer, { node: child }, i));
341
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Component, { ...node.props ?? {}, children: childElements });
213
342
  }
214
343
 
215
344
  // schema/component-schema.json
216
345
  var component_schema_default = {
217
346
  $schema: "Generative UI Component Schema",
218
- description: "Available primitive components for composing chat UI. The AI should return a JSON tree using these types. Each node has: type (string), props (object), children (array of nodes, optional).",
219
- primitives: {
347
+ description: "Available UI components for composing chat UI. The AI should return a JSON tree using these types. Each node has: type (string), props (object), children (array of nodes, optional).",
348
+ components: {
220
349
  card: {
221
- description: "Container with optional title and subtitle. Can wrap other components as children.",
222
- props: {
223
- title: { type: "string", required: false, description: "Card heading text" },
224
- subtitle: { type: "string", required: false, description: "Secondary text below the title" }
225
- },
350
+ description: "Container card. Compose with card-header, card-content, card-footer as children.",
351
+ props: {},
226
352
  accepts_children: true,
227
353
  example: {
228
354
  type: "card",
229
- props: { title: "Project Summary", subtitle: "Last updated 2 hours ago" },
230
- children: []
355
+ children: [
356
+ {
357
+ type: "card-header",
358
+ children: [
359
+ { type: "card-title", props: {}, children: [] },
360
+ { type: "card-description", props: {}, children: [] }
361
+ ]
362
+ },
363
+ { type: "card-content", children: [] }
364
+ ]
231
365
  }
232
366
  },
233
- "key-value": {
234
- description: "Displays a list of label-value pairs. Use for entity details like name, status, email, etc.",
235
- props: {
236
- items: {
237
- type: "array",
238
- required: true,
239
- description: "Array of { label, value } objects",
240
- item_schema: {
241
- label: { type: "string", description: "Field name (e.g. 'Email', 'Status')" },
242
- value: { type: "string", description: "Field value" }
243
- }
244
- }
245
- },
246
- accepts_children: false,
247
- example: {
248
- type: "key-value",
249
- props: {
250
- items: [
251
- { label: "Client", value: "Orchid Flo" },
252
- { label: "Status", value: "Active" },
253
- { label: "Email", value: "ray@example.com" }
254
- ]
255
- }
256
- }
367
+ "card-header": {
368
+ description: "Header section of a card. Place card-title and card-description inside.",
369
+ props: {},
370
+ accepts_children: true
371
+ },
372
+ "card-title": {
373
+ description: "Title inside a card-header.",
374
+ props: {},
375
+ accepts_children: true
376
+ },
377
+ "card-description": {
378
+ description: "Description text inside a card-header.",
379
+ props: {},
380
+ accepts_children: true
381
+ },
382
+ "card-content": {
383
+ description: "Main content area of a card.",
384
+ props: {},
385
+ accepts_children: true
257
386
  },
258
- "button-group": {
259
- description: "Row of action buttons. Use when offering choices or actions to the user.",
387
+ "card-footer": {
388
+ description: "Footer section of a card, typically for actions.",
389
+ props: {},
390
+ accepts_children: true
391
+ },
392
+ button: {
393
+ description: "An action button. Use label prop for text, or compose children.",
260
394
  props: {
261
- buttons: {
262
- type: "array",
263
- required: true,
264
- description: "Array of button definitions",
265
- item_schema: {
266
- label: { type: "string", description: "Button text" },
267
- variant: { type: "string", enum: ["primary", "secondary", "outline"], description: "Button style" },
268
- url: { type: "string", required: false, description: "URL to open when clicked" }
269
- }
270
- }
395
+ label: { type: "string", required: false, description: "Button text (shorthand for children)" },
396
+ variant: { type: "string", enum: ["primary", "secondary", "outline", "destructive", "ghost", "soft"], required: false, description: "Defaults to 'primary'" },
397
+ size: { type: "string", enum: ["sm", "md", "lg"], required: false, description: "Defaults to 'md'" },
398
+ url: { type: "string", required: false, description: "URL to open when clicked" },
399
+ disabled: { type: "boolean", required: false }
271
400
  },
272
- accepts_children: false,
401
+ accepts_children: true,
273
402
  example: {
274
- type: "button-group",
275
- props: {
276
- buttons: [
277
- { label: "Open Project", variant: "primary", url: "/projects/123" },
278
- { label: "View Documents", variant: "outline" }
279
- ]
280
- }
403
+ type: "button",
404
+ props: { label: "View Details", variant: "primary" }
281
405
  }
282
406
  }
283
407
  },
284
408
  ui_tree_format: {
285
- description: "The AI should return a JSON object with this structure. Send it via Centrifugo as the message payload.",
409
+ description: "The AI should return a JSON object with this structure.",
286
410
  schema: {
287
- type: { type: "string", description: "One of the primitive type names above" },
288
- props: { type: "object", description: "Props matching the primitive's prop schema" },
411
+ type: { type: "string", description: "One of the component type names above" },
412
+ props: { type: "object", description: "Props matching the component's prop schema" },
289
413
  children: { type: "array", description: "Optional array of nested nodes (only for types with accepts_children: true)" }
290
414
  }
291
415
  },
292
416
  full_example: {
293
417
  type: "card",
294
- props: { title: "Client Overview" },
295
418
  children: [
296
419
  {
297
- type: "key-value",
298
- props: {
299
- items: [
300
- { label: "Name", value: "Orchid Flo" },
301
- { label: "Type", value: "Company" },
302
- { label: "Email", value: "ray@example.com" }
303
- ]
304
- }
420
+ type: "card-header",
421
+ children: [
422
+ { type: "card-title", props: {}, children: [] }
423
+ ]
305
424
  },
306
425
  {
307
- type: "card",
308
- props: { title: "Project: Promotion" },
426
+ type: "card-content",
309
427
  children: [
310
- {
311
- type: "key-value",
312
- props: {
313
- items: [
314
- { label: "Status", value: "Active" },
315
- { label: "Workspaces", value: "3" }
316
- ]
317
- }
318
- },
319
- {
320
- type: "button-group",
321
- props: {
322
- buttons: [
323
- { label: "Open Project", variant: "primary" },
324
- { label: "View Documents", variant: "outline" }
325
- ]
326
- }
327
- }
428
+ { type: "button", props: { label: "Open Project", variant: "primary" } },
429
+ { type: "button", props: { label: "View Documents", variant: "outline" } }
328
430
  ]
329
431
  }
330
432
  ]
@@ -334,19 +436,12 @@ var component_schema_default = {
334
436
  // src/schema.ts
335
437
  var componentSchema = component_schema_default;
336
438
  function getPrimitiveSchemas() {
337
- return componentSchema.primitives;
439
+ return componentSchema.components;
338
440
  }
339
441
  function getFullExample() {
340
442
  return componentSchema.full_example;
341
443
  }
342
444
 
343
- // src/utils.ts
344
- var import_clsx = require("clsx");
345
- var import_tailwind_merge = require("tailwind-merge");
346
- function cn(...inputs) {
347
- return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
348
- }
349
-
350
445
  // src/design-tokens/design-tokens.ts
351
446
  var designTokens = {
352
447
  "color-slate-50": "var(--color-slate-50)",
@@ -1307,9 +1402,14 @@ function getTokenValueWithFallback(tokenName, fallback) {
1307
1402
  }
1308
1403
  // Annotate the CommonJS export names for ESM import in node:
1309
1404
  0 && (module.exports = {
1310
- ButtonGroupPrimitive,
1311
- CardPrimitive,
1312
- KeyValuePrimitive,
1405
+ Button,
1406
+ Card,
1407
+ CardAction,
1408
+ CardContent,
1409
+ CardDescription,
1410
+ CardFooter,
1411
+ CardHeader,
1412
+ CardTitle,
1313
1413
  UIRenderer,
1314
1414
  cn,
1315
1415
  componentSchema,