@kubuild/components 0.2.0 → 0.3.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.
Files changed (133) hide show
  1. package/dist/blocks/forms.d.ts +6 -0
  2. package/dist/blocks/forms.d.ts.map +1 -0
  3. package/dist/blocks/index.cjs +1661 -0
  4. package/dist/blocks/index.cjs.map +1 -0
  5. package/dist/blocks/index.d.ts +11 -0
  6. package/dist/blocks/index.d.ts.map +1 -0
  7. package/dist/blocks/index.js +15 -0
  8. package/dist/blocks/index.js.map +1 -0
  9. package/dist/blocks/layout.d.ts +6 -0
  10. package/dist/blocks/layout.d.ts.map +1 -0
  11. package/dist/blocks/sections.d.ts +6 -0
  12. package/dist/blocks/sections.d.ts.map +1 -0
  13. package/dist/{blocks.d.ts → blocks/types.d.ts} +2 -5
  14. package/dist/blocks/types.d.ts.map +1 -0
  15. package/dist/chunk-JTQ35OQQ.js +1631 -0
  16. package/dist/chunk-JTQ35OQQ.js.map +1 -0
  17. package/dist/chunk-K6I6U7F3.js +2707 -0
  18. package/dist/chunk-K6I6U7F3.js.map +1 -0
  19. package/dist/chunk-OK53DS7G.js +911 -0
  20. package/dist/chunk-OK53DS7G.js.map +1 -0
  21. package/dist/definitions/constants.d.ts +10 -0
  22. package/dist/definitions/constants.d.ts.map +1 -0
  23. package/dist/definitions/data/collection.d.ts +3 -0
  24. package/dist/definitions/data/collection.d.ts.map +1 -0
  25. package/dist/definitions/data/index.d.ts +4 -0
  26. package/dist/definitions/data/index.d.ts.map +1 -0
  27. package/dist/definitions/data/list.d.ts +4 -0
  28. package/dist/definitions/data/list.d.ts.map +1 -0
  29. package/dist/definitions/data/table.d.ts +5 -0
  30. package/dist/definitions/data/table.d.ts.map +1 -0
  31. package/dist/definitions/form/button.d.ts +4 -0
  32. package/dist/definitions/form/button.d.ts.map +1 -0
  33. package/dist/definitions/form/checkbox.d.ts +3 -0
  34. package/dist/definitions/form/checkbox.d.ts.map +1 -0
  35. package/dist/definitions/form/file-upload.d.ts +3 -0
  36. package/dist/definitions/form/file-upload.d.ts.map +1 -0
  37. package/dist/definitions/form/form.d.ts +3 -0
  38. package/dist/definitions/form/form.d.ts.map +1 -0
  39. package/dist/definitions/form/index.d.ts +10 -0
  40. package/dist/definitions/form/index.d.ts.map +1 -0
  41. package/dist/definitions/form/input.d.ts +3 -0
  42. package/dist/definitions/form/input.d.ts.map +1 -0
  43. package/dist/definitions/form/radio.d.ts +5 -0
  44. package/dist/definitions/form/radio.d.ts.map +1 -0
  45. package/dist/definitions/form/select.d.ts +3 -0
  46. package/dist/definitions/form/select.d.ts.map +1 -0
  47. package/dist/definitions/form/switch.d.ts +3 -0
  48. package/dist/definitions/form/switch.d.ts.map +1 -0
  49. package/dist/definitions/form/textarea.d.ts +3 -0
  50. package/dist/definitions/form/textarea.d.ts.map +1 -0
  51. package/dist/definitions/index.cjs +3512 -0
  52. package/dist/definitions/index.cjs.map +1 -0
  53. package/dist/definitions/index.d.ts +12 -0
  54. package/dist/definitions/index.d.ts.map +1 -0
  55. package/dist/definitions/index.js +90 -0
  56. package/dist/definitions/index.js.map +1 -0
  57. package/dist/definitions/interactive/collapsible.d.ts +3 -0
  58. package/dist/definitions/interactive/collapsible.d.ts.map +1 -0
  59. package/dist/definitions/interactive/drawer.d.ts +3 -0
  60. package/dist/definitions/interactive/drawer.d.ts.map +1 -0
  61. package/dist/definitions/interactive/index.d.ts +4 -0
  62. package/dist/definitions/interactive/index.d.ts.map +1 -0
  63. package/dist/definitions/interactive/modal.d.ts +3 -0
  64. package/dist/definitions/interactive/modal.d.ts.map +1 -0
  65. package/dist/definitions/layout/columns.d.ts +3 -0
  66. package/dist/definitions/layout/columns.d.ts.map +1 -0
  67. package/dist/definitions/layout/container.d.ts +3 -0
  68. package/dist/definitions/layout/container.d.ts.map +1 -0
  69. package/dist/definitions/layout/flex.d.ts +7 -0
  70. package/dist/definitions/layout/flex.d.ts.map +1 -0
  71. package/dist/definitions/layout/grid.d.ts +7 -0
  72. package/dist/definitions/layout/grid.d.ts.map +1 -0
  73. package/dist/definitions/layout/index.d.ts +7 -0
  74. package/dist/definitions/layout/index.d.ts.map +1 -0
  75. package/dist/definitions/layout/page.d.ts +3 -0
  76. package/dist/definitions/layout/page.d.ts.map +1 -0
  77. package/dist/definitions/layout/section.d.ts +3 -0
  78. package/dist/definitions/layout/section.d.ts.map +1 -0
  79. package/dist/definitions/media/html-embed.d.ts +3 -0
  80. package/dist/definitions/media/html-embed.d.ts.map +1 -0
  81. package/dist/definitions/media/icon.d.ts +3 -0
  82. package/dist/definitions/media/icon.d.ts.map +1 -0
  83. package/dist/definitions/media/image.d.ts +3 -0
  84. package/dist/definitions/media/image.d.ts.map +1 -0
  85. package/dist/definitions/media/index.d.ts +5 -0
  86. package/dist/definitions/media/index.d.ts.map +1 -0
  87. package/dist/definitions/media/video.d.ts +3 -0
  88. package/dist/definitions/media/video.d.ts.map +1 -0
  89. package/dist/definitions/types.d.ts +5 -0
  90. package/dist/definitions/types.d.ts.map +1 -0
  91. package/dist/definitions/typography/badge.d.ts +3 -0
  92. package/dist/definitions/typography/badge.d.ts.map +1 -0
  93. package/dist/definitions/typography/blockquote.d.ts +3 -0
  94. package/dist/definitions/typography/blockquote.d.ts.map +1 -0
  95. package/dist/definitions/typography/code-block.d.ts +3 -0
  96. package/dist/definitions/typography/code-block.d.ts.map +1 -0
  97. package/dist/definitions/typography/heading.d.ts +3 -0
  98. package/dist/definitions/typography/heading.d.ts.map +1 -0
  99. package/dist/definitions/typography/index.d.ts +8 -0
  100. package/dist/definitions/typography/index.d.ts.map +1 -0
  101. package/dist/definitions/typography/link.d.ts +3 -0
  102. package/dist/definitions/typography/link.d.ts.map +1 -0
  103. package/dist/definitions/typography/paragraph.d.ts +3 -0
  104. package/dist/definitions/typography/paragraph.d.ts.map +1 -0
  105. package/dist/definitions/typography/text.d.ts +3 -0
  106. package/dist/definitions/typography/text.d.ts.map +1 -0
  107. package/dist/index.cjs +1568 -814
  108. package/dist/index.cjs.map +1 -1
  109. package/dist/index.js +120 -4332
  110. package/dist/index.js.map +1 -1
  111. package/dist/traits/common.d.ts +8 -0
  112. package/dist/traits/common.d.ts.map +1 -0
  113. package/dist/{traits.d.ts → traits/form.d.ts} +2 -109
  114. package/dist/traits/form.d.ts.map +1 -0
  115. package/dist/traits/index.cjs +998 -0
  116. package/dist/traits/index.cjs.map +1 -0
  117. package/dist/traits/index.d.ts +7 -0
  118. package/dist/traits/index.d.ts.map +1 -0
  119. package/dist/traits/index.js +129 -0
  120. package/dist/traits/index.js.map +1 -0
  121. package/dist/traits/link.d.ts +8 -0
  122. package/dist/traits/link.d.ts.map +1 -0
  123. package/dist/traits/media.d.ts +18 -0
  124. package/dist/traits/media.d.ts.map +1 -0
  125. package/dist/traits/structure.d.ts +10 -0
  126. package/dist/traits/structure.d.ts.map +1 -0
  127. package/dist/traits/types.d.ts +69 -0
  128. package/dist/traits/types.d.ts.map +1 -0
  129. package/package.json +20 -4
  130. package/dist/blocks.d.ts.map +0 -1
  131. package/dist/definitions.d.ts +0 -37
  132. package/dist/definitions.d.ts.map +0 -1
  133. package/dist/traits.d.ts.map +0 -1
@@ -0,0 +1,2707 @@
1
+ import {
2
+ acceptTrait,
3
+ actionTrait,
4
+ altTrait,
5
+ ariaLabelTrait,
6
+ autoCompleteTrait,
7
+ autoDisableOnSubmitTrait,
8
+ autoGrowTrait,
9
+ autoplayTrait,
10
+ buttonTypeTrait,
11
+ citeTrait,
12
+ colSpanTrait,
13
+ controlsTrait,
14
+ defaultCheckedTrait,
15
+ defaultSelectedTrait,
16
+ defaultValueTrait,
17
+ disabledTrait,
18
+ fieldNameTrait,
19
+ helperTextTrait,
20
+ hrefTrait,
21
+ idTrait,
22
+ indeterminateTrait,
23
+ inputTypeTrait,
24
+ labelTextTrait,
25
+ loadingTextTrait,
26
+ loadingTrait,
27
+ loopTrait,
28
+ maxCharCountTrait,
29
+ maxFileSizeTrait,
30
+ maxLengthTrait,
31
+ methodTrait,
32
+ minLengthTrait,
33
+ multipleTrait,
34
+ mutedTrait,
35
+ optionsListTrait,
36
+ orientationTrait,
37
+ patternTrait,
38
+ placeholderTrait,
39
+ posterTrait,
40
+ prefixIconTrait,
41
+ preventDefaultTrait,
42
+ readOnlyTrait,
43
+ relTrait,
44
+ requiredTrait,
45
+ resetOnSubmitTrait,
46
+ resizeTrait,
47
+ rowSpanTrait,
48
+ rowsTrait,
49
+ scrollToFirstErrorTrait,
50
+ showPreviewTrait,
51
+ showSpinnerTrait,
52
+ srcTrait,
53
+ suffixIconTrait,
54
+ switchSizeTrait,
55
+ targetTrait,
56
+ titleTrait,
57
+ valueTrait
58
+ } from "./chunk-OK53DS7G.js";
59
+
60
+ // src/registry.ts
61
+ var ComponentRegistry = class {
62
+ components = /* @__PURE__ */ new Map();
63
+ register(definition, allowOverride = false) {
64
+ if (!allowOverride && this.components.has(definition.type)) {
65
+ throw new Error(`Component type "${definition.type}" is already registered.`);
66
+ }
67
+ this.components.set(definition.type, definition);
68
+ }
69
+ unregister(type) {
70
+ return this.components.delete(type);
71
+ }
72
+ get(type) {
73
+ return this.components.get(type);
74
+ }
75
+ has(type) {
76
+ return this.components.has(type);
77
+ }
78
+ list() {
79
+ return Array.from(this.components.values());
80
+ }
81
+ listByCategory(category) {
82
+ return this.list().filter((c) => c.category === category);
83
+ }
84
+ /**
85
+ * Check whether `childType` is a valid insertion target under `parentType`,
86
+ * covering both directions of child policy: the parent's `acceptsChildren`/
87
+ * `allowedChildren` (by type, category, or `'*'`) and the child's own
88
+ * `disallowedParents`. Used by the builder to reject an invalid insertion
89
+ * before a node is constructed, rather than after the fact via `validateNode`.
90
+ */
91
+ canInsertChild(parentType, childType) {
92
+ const errors = [];
93
+ const parentDef = this.get(parentType);
94
+ const childDef = this.get(childType);
95
+ if (!parentDef) {
96
+ errors.push(`Unknown target parent type: "${parentType}".`);
97
+ }
98
+ if (!childDef) {
99
+ errors.push(`Unknown component type: "${childType}".`);
100
+ }
101
+ if (!parentDef || !childDef) {
102
+ return { valid: false, errors };
103
+ }
104
+ if (!parentDef.acceptsChildren) {
105
+ errors.push(`"${parentDef.label}" does not accept children.`);
106
+ } else if (parentDef.allowedChildren) {
107
+ const allowed = parentDef.allowedChildren.includes("*") || parentDef.allowedChildren.includes(childType) || parentDef.allowedChildren.includes(childDef.category);
108
+ if (!allowed) {
109
+ errors.push(`"${parentDef.label}" does not allow "${childDef.label}" as a child.`);
110
+ }
111
+ }
112
+ if (childDef.disallowedParents?.includes(parentType)) {
113
+ errors.push(`"${childDef.label}" is not allowed inside "${parentDef.label}".`);
114
+ }
115
+ return { valid: errors.length === 0, errors };
116
+ }
117
+ validateNode(node, parentType) {
118
+ const def = this.get(node.type);
119
+ const errors = [];
120
+ if (!def) {
121
+ errors.push(`Unknown component type: "${node.type}"`);
122
+ return { valid: false, errors };
123
+ }
124
+ if (!def.acceptsChildren && node.children && node.children.length > 0) {
125
+ errors.push(`Component "${node.type}" does not accept children.`);
126
+ }
127
+ if (def.allowedChildren && node.children) {
128
+ for (const child of node.children) {
129
+ const childCategory = this.get(child.type)?.category;
130
+ const allowed = def.allowedChildren.includes("*") || def.allowedChildren.includes(child.type) || childCategory !== void 0 && def.allowedChildren.includes(childCategory);
131
+ if (!allowed) {
132
+ errors.push(`Component "${node.type}" does not allow child type "${child.type}".`);
133
+ }
134
+ }
135
+ }
136
+ if (parentType && def.disallowedParents?.includes(parentType)) {
137
+ errors.push(`Component "${node.type}" is not allowed inside parent "${parentType}".`);
138
+ }
139
+ if (def.validateProps && node.props) {
140
+ const propResult = def.validateProps(node.props);
141
+ if (Array.isArray(propResult) && propResult.length > 0) {
142
+ errors.push(...propResult);
143
+ } else if (propResult === false) {
144
+ errors.push(`Props validation failed for component "${node.type}".`);
145
+ }
146
+ }
147
+ return { valid: errors.length === 0, errors };
148
+ }
149
+ };
150
+
151
+ // src/definitions/constants.ts
152
+ var LAYOUT_PARENTS = ["page", "section", "container", "columns", "flex", "grid", "modal", "drawer", "collapsible"];
153
+ var CONTENT_CHILD_TYPES = [
154
+ "heading",
155
+ "text",
156
+ "paragraph",
157
+ "link",
158
+ "blockquote",
159
+ "badge",
160
+ "code-block",
161
+ "image",
162
+ "video",
163
+ "icon",
164
+ "html-embed",
165
+ "button",
166
+ "button-submit",
167
+ "form",
168
+ "input",
169
+ "textarea",
170
+ "select",
171
+ "checkbox",
172
+ "switch",
173
+ "radio-group",
174
+ "radio",
175
+ "radio-item",
176
+ "file-upload",
177
+ "list",
178
+ "table",
179
+ "collection",
180
+ "custom",
181
+ "modal",
182
+ "drawer",
183
+ "collapsible"
184
+ ];
185
+
186
+ // src/definitions/layout/page.ts
187
+ var pageDefinition = {
188
+ type: "page",
189
+ label: "Page",
190
+ category: "layout",
191
+ icon: "layout",
192
+ acceptsChildren: true,
193
+ allowedChildren: ["section", "custom"],
194
+ disallowedParents: [...LAYOUT_PARENTS, ...CONTENT_CHILD_TYPES, "list-item", "table-row", "table-cell"],
195
+ defaultProps: { title: "New Page" },
196
+ traits: [
197
+ titleTrait({ defaultValue: "New Page", description: "The document title shown in the browser tab and search results." }),
198
+ idTrait()
199
+ ],
200
+ defaultStyles: { base: { minHeight: "100vh", backgroundColor: "#ffffff" } }
201
+ };
202
+
203
+ // src/definitions/layout/section.ts
204
+ var sectionDefinition = {
205
+ type: "section",
206
+ label: "Section",
207
+ category: "layout",
208
+ icon: "rows",
209
+ acceptsChildren: true,
210
+ allowedChildren: ["container", "columns", "flex", "grid", ...CONTENT_CHILD_TYPES],
211
+ defaultProps: {},
212
+ traits: [
213
+ idTrait(),
214
+ ariaLabelTrait({ description: "Accessible name for the section landmark." })
215
+ ],
216
+ defaultStyles: {
217
+ base: {
218
+ paddingTop: "48px",
219
+ paddingBottom: "48px",
220
+ paddingLeft: "16px",
221
+ paddingRight: "16px"
222
+ },
223
+ tablet: {
224
+ paddingTop: "32px",
225
+ paddingBottom: "32px"
226
+ },
227
+ mobile: {
228
+ paddingTop: "24px",
229
+ paddingBottom: "24px",
230
+ paddingLeft: "16px",
231
+ paddingRight: "16px"
232
+ }
233
+ }
234
+ };
235
+
236
+ // src/definitions/layout/container.ts
237
+ var containerDefinition = {
238
+ type: "container",
239
+ label: "Container",
240
+ category: "layout",
241
+ icon: "box",
242
+ acceptsChildren: true,
243
+ allowedChildren: ["columns", "flex", "grid", ...CONTENT_CHILD_TYPES],
244
+ defaultProps: { maxWidth: "1200px" },
245
+ traits: [
246
+ idTrait()
247
+ ],
248
+ defaultStyles: {
249
+ base: {
250
+ maxWidth: "1200px",
251
+ margin: "0 auto",
252
+ width: "100%"
253
+ },
254
+ tablet: {
255
+ maxWidth: "720px"
256
+ },
257
+ mobile: {
258
+ maxWidth: "100%",
259
+ paddingLeft: "16px",
260
+ paddingRight: "16px"
261
+ }
262
+ }
263
+ };
264
+
265
+ // src/definitions/layout/columns.ts
266
+ var columnsDefinition = {
267
+ type: "columns",
268
+ label: "Columns",
269
+ category: "layout",
270
+ icon: "columns",
271
+ acceptsChildren: true,
272
+ allowedChildren: ["container", "flex", "grid", ...CONTENT_CHILD_TYPES],
273
+ defaultProps: { columns: 2, gap: "16px" },
274
+ traits: [
275
+ idTrait()
276
+ ],
277
+ defaultStyles: {
278
+ base: {
279
+ display: "grid",
280
+ gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
281
+ gap: "16px"
282
+ },
283
+ tablet: {
284
+ gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
285
+ gap: "12px"
286
+ },
287
+ mobile: {
288
+ gridTemplateColumns: "repeat(1, minmax(0, 1fr))",
289
+ gap: "12px"
290
+ }
291
+ }
292
+ };
293
+
294
+ // src/definitions/layout/flex.ts
295
+ var flexDefinition = {
296
+ type: "flex",
297
+ label: "Flex",
298
+ category: "layout",
299
+ icon: "flex",
300
+ acceptsChildren: true,
301
+ allowedChildren: ["*"],
302
+ disallowedParents: ["page"],
303
+ defaultProps: {},
304
+ traits: [
305
+ idTrait(),
306
+ ariaLabelTrait({ description: "Accessible name for the flex container." })
307
+ ],
308
+ defaultStyles: {
309
+ base: {
310
+ display: "flex",
311
+ flexDirection: "column",
312
+ gap: "16px"
313
+ }
314
+ }
315
+ };
316
+
317
+ // src/definitions/layout/grid.ts
318
+ var gridDefinition = {
319
+ type: "grid",
320
+ label: "Grid",
321
+ category: "layout",
322
+ icon: "grid",
323
+ acceptsChildren: true,
324
+ allowedChildren: ["*"],
325
+ disallowedParents: ["page"],
326
+ defaultProps: {
327
+ columns: 3,
328
+ gap: "16px"
329
+ },
330
+ traits: [
331
+ idTrait(),
332
+ ariaLabelTrait({ description: "Accessible name for the grid container." })
333
+ ],
334
+ defaultStyles: {
335
+ base: {
336
+ display: "grid",
337
+ gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
338
+ gap: "16px"
339
+ },
340
+ tablet: {
341
+ gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
342
+ gap: "16px"
343
+ },
344
+ mobile: {
345
+ gridTemplateColumns: "repeat(1, minmax(0, 1fr))",
346
+ gap: "16px"
347
+ }
348
+ }
349
+ };
350
+
351
+ // src/definitions/typography/heading.ts
352
+ import { isVariableBinding } from "@kubuild/schema";
353
+ var headingDefinition = {
354
+ type: "heading",
355
+ label: "Heading",
356
+ category: "typography",
357
+ icon: "heading",
358
+ acceptsChildren: false,
359
+ defaultProps: { text: "Heading Text", level: 2 },
360
+ propFields: [
361
+ { name: "text", label: "Text", type: "string", defaultValue: "Heading Text" },
362
+ {
363
+ name: "level",
364
+ label: "Heading Level",
365
+ type: "select",
366
+ defaultValue: 2,
367
+ options: [1, 2, 3, 4, 5, 6].map((level) => ({ label: `H${level}`, value: level }))
368
+ }
369
+ ],
370
+ traits: [
371
+ idTrait(),
372
+ titleTrait({ description: "Advisory title shown when hovering the heading." }),
373
+ ariaLabelTrait()
374
+ ],
375
+ validateProps: (props) => {
376
+ const errors = [];
377
+ if (!isVariableBinding(props.text) && (typeof props.text !== "string" || props.text.trim().length === 0)) {
378
+ errors.push('Heading requires a non-empty "text".');
379
+ }
380
+ if (props.level !== void 0 && (typeof props.level !== "number" || props.level < 1 || props.level > 6)) {
381
+ errors.push('Heading "level" must be a number between 1 and 6.');
382
+ }
383
+ return errors.length > 0 ? errors : true;
384
+ },
385
+ defaultStyles: {
386
+ base: {
387
+ fontSize: "32px",
388
+ fontWeight: "700",
389
+ color: "#111827",
390
+ margin: "0 0 16px 0"
391
+ }
392
+ }
393
+ };
394
+
395
+ // src/definitions/typography/text.ts
396
+ import { isVariableBinding as isVariableBinding2 } from "@kubuild/schema";
397
+ var textDefinition = {
398
+ type: "text",
399
+ label: "Text",
400
+ category: "typography",
401
+ icon: "type",
402
+ acceptsChildren: false,
403
+ defaultProps: { content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit." },
404
+ propFields: [
405
+ { name: "content", label: "Content", type: "string", defaultValue: "Lorem ipsum dolor sit amet." }
406
+ ],
407
+ traits: [
408
+ idTrait(),
409
+ titleTrait(),
410
+ ariaLabelTrait()
411
+ ],
412
+ validateProps: (props) => {
413
+ if (!isVariableBinding2(props.content) && (typeof props.content !== "string" || props.content.trim().length === 0)) {
414
+ return ['Text requires a non-empty "content".'];
415
+ }
416
+ return true;
417
+ },
418
+ defaultStyles: {
419
+ base: {
420
+ fontSize: "16px",
421
+ color: "#4b5563",
422
+ lineHeight: "1.6"
423
+ }
424
+ }
425
+ };
426
+
427
+ // src/definitions/typography/paragraph.ts
428
+ import { isVariableBinding as isVariableBinding3 } from "@kubuild/schema";
429
+ var paragraphDefinition = {
430
+ type: "paragraph",
431
+ label: "Paragraph",
432
+ category: "typography",
433
+ icon: "paragraph",
434
+ acceptsChildren: false,
435
+ defaultProps: {
436
+ text: "A paragraph of text with clean semantic typography."
437
+ },
438
+ propFields: [
439
+ {
440
+ name: "text",
441
+ label: "Text",
442
+ type: "string",
443
+ defaultValue: "A paragraph of text with clean semantic typography."
444
+ }
445
+ ],
446
+ traits: [
447
+ idTrait(),
448
+ titleTrait(),
449
+ ariaLabelTrait()
450
+ ],
451
+ validateProps: (props) => {
452
+ const errors = [];
453
+ const textVal = props.text ?? props.content;
454
+ if (textVal !== void 0 && !isVariableBinding3(textVal) && (typeof textVal !== "string" || textVal.trim().length === 0)) {
455
+ errors.push('Paragraph requires a non-empty "text".');
456
+ }
457
+ return errors.length > 0 ? errors : true;
458
+ },
459
+ defaultStyles: {
460
+ base: {
461
+ fontSize: "16px",
462
+ color: "#4b5563",
463
+ lineHeight: "1.6",
464
+ margin: "0 0 16px 0"
465
+ }
466
+ }
467
+ };
468
+
469
+ // src/definitions/typography/link.ts
470
+ import { isVariableBinding as isVariableBinding4 } from "@kubuild/schema";
471
+ var linkDefinition = {
472
+ type: "link",
473
+ label: "Link",
474
+ category: "typography",
475
+ icon: "link",
476
+ acceptsChildren: false,
477
+ defaultProps: {
478
+ text: "Click here",
479
+ href: "#",
480
+ target: "_self",
481
+ rel: ""
482
+ },
483
+ propFields: [
484
+ { name: "text", label: "Link Text", type: "string", defaultValue: "Click here" },
485
+ { name: "href", label: "URL (href)", type: "string", defaultValue: "#" },
486
+ {
487
+ name: "target",
488
+ label: "Target",
489
+ type: "select",
490
+ defaultValue: "_self",
491
+ options: [
492
+ { label: "Same tab (_self)", value: "_self" },
493
+ { label: "New tab (_blank)", value: "_blank" },
494
+ { label: "Parent (_parent)", value: "_parent" },
495
+ { label: "Top (_top)", value: "_top" }
496
+ ]
497
+ },
498
+ { name: "rel", label: "Relationship (rel)", type: "string", defaultValue: "" }
499
+ ],
500
+ traits: [
501
+ hrefTrait(),
502
+ targetTrait(),
503
+ relTrait(),
504
+ idTrait(),
505
+ titleTrait({ description: "Advisory title shown when hovering the link." }),
506
+ ariaLabelTrait()
507
+ ],
508
+ validateProps: (props) => {
509
+ const errors = [];
510
+ if (props.text !== void 0 && !isVariableBinding4(props.text) && (typeof props.text !== "string" || props.text.trim().length === 0)) {
511
+ errors.push('Link requires a non-empty "text".');
512
+ }
513
+ if (props.href !== void 0 && typeof props.href !== "string" && !isVariableBinding4(props.href)) {
514
+ errors.push('Link "href" must be a string when provided.');
515
+ }
516
+ if (props.target !== void 0 && !isVariableBinding4(props.target)) {
517
+ const allowedTargets = ["_self", "_blank", "_parent", "_top"];
518
+ if (typeof props.target !== "string" || !allowedTargets.includes(props.target)) {
519
+ errors.push(`Link "target" must be one of: ${allowedTargets.join(", ")}.`);
520
+ }
521
+ }
522
+ if (props.rel !== void 0 && typeof props.rel !== "string" && !isVariableBinding4(props.rel)) {
523
+ errors.push('Link "rel" must be a string when provided.');
524
+ }
525
+ return errors.length > 0 ? errors : true;
526
+ },
527
+ defaultStyles: {
528
+ base: {
529
+ color: "#2563eb",
530
+ textDecoration: "underline",
531
+ cursor: "pointer"
532
+ }
533
+ }
534
+ };
535
+
536
+ // src/definitions/typography/blockquote.ts
537
+ import { isVariableBinding as isVariableBinding5 } from "@kubuild/schema";
538
+ var blockquoteDefinition = {
539
+ type: "blockquote",
540
+ label: "Blockquote",
541
+ category: "typography",
542
+ icon: "blockquote",
543
+ acceptsChildren: true,
544
+ allowedChildren: [
545
+ "paragraph",
546
+ "text",
547
+ "heading",
548
+ "link",
549
+ "badge",
550
+ "code-block",
551
+ "image",
552
+ "video",
553
+ "icon",
554
+ "html-embed",
555
+ "custom"
556
+ ],
557
+ defaultProps: {
558
+ text: "\u201CSimplicity is the soul of efficiency.\u201D"
559
+ },
560
+ propFields: [
561
+ {
562
+ name: "text",
563
+ label: "Quote Text",
564
+ type: "string",
565
+ defaultValue: "\u201CSimplicity is the soul of efficiency.\u201D"
566
+ },
567
+ { name: "cite", label: "Citation URL (cite)", type: "string" }
568
+ ],
569
+ traits: [
570
+ citeTrait(),
571
+ idTrait(),
572
+ titleTrait(),
573
+ ariaLabelTrait()
574
+ ],
575
+ validateProps: (props) => {
576
+ const errors = [];
577
+ if (props.text !== void 0 && typeof props.text !== "string" && !isVariableBinding5(props.text)) {
578
+ errors.push('Blockquote "text" must be a string when provided.');
579
+ }
580
+ if (props.cite !== void 0 && typeof props.cite !== "string" && !isVariableBinding5(props.cite)) {
581
+ errors.push('Blockquote "cite" must be a string when provided.');
582
+ }
583
+ return errors.length > 0 ? errors : true;
584
+ },
585
+ defaultStyles: {
586
+ base: {
587
+ borderLeftWidth: "4px",
588
+ borderLeftColor: "#3b82f6",
589
+ borderLeftStyle: "solid",
590
+ paddingTop: "8px",
591
+ paddingBottom: "8px",
592
+ paddingLeft: "16px",
593
+ paddingRight: "12px",
594
+ margin: "0 0 16px 0",
595
+ fontStyle: "italic",
596
+ color: "#4b5563",
597
+ backgroundColor: "#f8fafc"
598
+ }
599
+ }
600
+ };
601
+
602
+ // src/definitions/typography/badge.ts
603
+ import { isVariableBinding as isVariableBinding6 } from "@kubuild/schema";
604
+ var badgeDefinition = {
605
+ type: "badge",
606
+ label: "Badge",
607
+ category: "typography",
608
+ icon: "badge",
609
+ acceptsChildren: false,
610
+ defaultProps: {
611
+ text: "Badge",
612
+ variant: "default"
613
+ },
614
+ propFields: [
615
+ { name: "text", label: "Badge Text", type: "string", defaultValue: "Badge" },
616
+ {
617
+ name: "variant",
618
+ label: "Variant",
619
+ type: "select",
620
+ defaultValue: "default",
621
+ options: [
622
+ { label: "Default", value: "default" },
623
+ { label: "Success", value: "success" },
624
+ { label: "Warning", value: "warning" },
625
+ { label: "Danger", value: "danger" },
626
+ { label: "Info", value: "info" }
627
+ ]
628
+ }
629
+ ],
630
+ traits: [
631
+ idTrait(),
632
+ titleTrait(),
633
+ ariaLabelTrait()
634
+ ],
635
+ validateProps: (props) => {
636
+ const errors = [];
637
+ if (props.text !== void 0 && !isVariableBinding6(props.text) && (typeof props.text !== "string" || props.text.trim().length === 0)) {
638
+ errors.push('Badge requires a non-empty "text".');
639
+ }
640
+ if (props.variant !== void 0 && typeof props.variant !== "string" && !isVariableBinding6(props.variant)) {
641
+ errors.push('Badge "variant" must be a string.');
642
+ }
643
+ return errors.length > 0 ? errors : true;
644
+ },
645
+ defaultStyles: {
646
+ base: {
647
+ display: "inline-flex",
648
+ alignItems: "center",
649
+ paddingLeft: "10px",
650
+ paddingRight: "10px",
651
+ paddingTop: "2px",
652
+ paddingBottom: "2px",
653
+ borderRadius: "9999px",
654
+ fontSize: "12px",
655
+ fontWeight: "500",
656
+ lineHeight: "1.4",
657
+ backgroundColor: "#e0e7ff",
658
+ color: "#3730a3"
659
+ }
660
+ }
661
+ };
662
+
663
+ // src/definitions/typography/code-block.ts
664
+ import { isVariableBinding as isVariableBinding7 } from "@kubuild/schema";
665
+ var codeBlockDefinition = {
666
+ type: "code-block",
667
+ label: "Code Block",
668
+ category: "typography",
669
+ icon: "code-block",
670
+ acceptsChildren: false,
671
+ defaultProps: {
672
+ code: 'console.log("Hello, world!");',
673
+ language: "javascript"
674
+ },
675
+ propFields: [
676
+ {
677
+ name: "code",
678
+ label: "Code",
679
+ type: "textarea",
680
+ defaultValue: 'console.log("Hello, world!");'
681
+ },
682
+ {
683
+ name: "language",
684
+ label: "Language",
685
+ type: "string",
686
+ defaultValue: "javascript"
687
+ }
688
+ ],
689
+ traits: [
690
+ idTrait(),
691
+ titleTrait(),
692
+ ariaLabelTrait({ description: "Accessible label describing what the code example shows." })
693
+ ],
694
+ validateProps: (props) => {
695
+ const errors = [];
696
+ if (props.code !== void 0 && typeof props.code !== "string" && !isVariableBinding7(props.code)) {
697
+ errors.push('Code Block "code" must be a string when provided.');
698
+ }
699
+ if (props.language !== void 0 && typeof props.language !== "string" && !isVariableBinding7(props.language)) {
700
+ errors.push('Code Block "language" must be a string when provided.');
701
+ }
702
+ return errors.length > 0 ? errors : true;
703
+ },
704
+ defaultStyles: {
705
+ base: {
706
+ backgroundColor: "#1e293b",
707
+ color: "#f8fafc",
708
+ padding: "16px",
709
+ borderRadius: "8px",
710
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
711
+ fontSize: "14px",
712
+ lineHeight: "1.5",
713
+ overflowX: "auto",
714
+ margin: "0 0 16px 0",
715
+ whiteSpace: "pre"
716
+ }
717
+ }
718
+ };
719
+
720
+ // src/definitions/media/image.ts
721
+ import { isAssetReference, isVariableBinding as isVariableBinding8 } from "@kubuild/schema";
722
+ var imageDefinition = {
723
+ type: "image",
724
+ label: "Image",
725
+ category: "media",
726
+ icon: "image",
727
+ acceptsChildren: false,
728
+ capabilities: ["assetProvider"],
729
+ defaultProps: {
730
+ src: "https://images.unsplash.com/photo-1579546929518-9e396f3cc809?w=800&auto=format&fit=crop&q=80",
731
+ alt: "Default image",
732
+ width: 600,
733
+ height: 400
734
+ },
735
+ propFields: [
736
+ { name: "src", label: "Image URL", type: "string" },
737
+ { name: "asset", label: "Asset Reference", type: "json" },
738
+ { name: "alt", label: "Alt Text", type: "string", defaultValue: "Default image" },
739
+ { name: "width", label: "Width", type: "number" },
740
+ { name: "height", label: "Height", type: "number" }
741
+ ],
742
+ traits: [
743
+ srcTrait(),
744
+ altTrait({ defaultValue: "Default image" }),
745
+ loadingTrait(),
746
+ idTrait(),
747
+ titleTrait(),
748
+ ariaLabelTrait({ description: "Override the alt text for assistive technology (rarely needed)." })
749
+ ],
750
+ validateProps: (props) => {
751
+ const errors = [];
752
+ const hasSrc = typeof props.src === "string" && props.src.trim().length > 0 || isVariableBinding8(props.src);
753
+ const hasAsset = isAssetReference(props.asset);
754
+ if (!hasSrc && !hasAsset) {
755
+ errors.push('Image requires either a non-empty "src" URL or a valid "asset" reference.');
756
+ }
757
+ const hasAlt = typeof props.alt === "string" && props.alt.trim().length > 0 || isVariableBinding8(props.alt);
758
+ if (!hasAlt) {
759
+ errors.push('Image requires non-empty "alt" text.');
760
+ }
761
+ return errors.length > 0 ? errors : true;
762
+ },
763
+ defaultStyles: {
764
+ base: {
765
+ maxWidth: "100%",
766
+ height: "auto",
767
+ borderRadius: "8px"
768
+ }
769
+ }
770
+ };
771
+
772
+ // src/definitions/media/video.ts
773
+ import { isVariableBinding as isVariableBinding9 } from "@kubuild/schema";
774
+ var videoDefinition = {
775
+ type: "video",
776
+ label: "Video",
777
+ category: "media",
778
+ icon: "video",
779
+ acceptsChildren: false,
780
+ defaultProps: {
781
+ src: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
782
+ provider: "auto",
783
+ poster: "",
784
+ controls: true,
785
+ autoplay: false,
786
+ loop: false,
787
+ muted: false,
788
+ aspectRatio: "16:9"
789
+ },
790
+ propFields: [
791
+ {
792
+ name: "src",
793
+ label: "Video URL (HTML5, YouTube, Vimeo)",
794
+ type: "string",
795
+ defaultValue: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
796
+ },
797
+ {
798
+ name: "provider",
799
+ label: "Provider",
800
+ type: "select",
801
+ defaultValue: "auto",
802
+ options: [
803
+ { label: "Auto Detect", value: "auto" },
804
+ { label: "HTML5 Video", value: "html5" },
805
+ { label: "YouTube Embed", value: "youtube" },
806
+ { label: "Vimeo Embed", value: "vimeo" }
807
+ ]
808
+ },
809
+ { name: "poster", label: "Poster Image URL", type: "string", defaultValue: "" },
810
+ { name: "controls", label: "Show Controls", type: "boolean", defaultValue: true },
811
+ { name: "autoplay", label: "Autoplay", type: "boolean", defaultValue: false },
812
+ { name: "loop", label: "Loop", type: "boolean", defaultValue: false },
813
+ { name: "muted", label: "Muted", type: "boolean", defaultValue: false },
814
+ {
815
+ name: "aspectRatio",
816
+ label: "Aspect Ratio",
817
+ type: "select",
818
+ defaultValue: "16:9",
819
+ options: [
820
+ { label: "16:9 (Widescreen)", value: "16:9" },
821
+ { label: "4:3 (Standard)", value: "4:3" },
822
+ { label: "1:1 (Square)", value: "1:1" },
823
+ { label: "9:16 (Vertical)", value: "9:16" },
824
+ { label: "Auto", value: "auto" }
825
+ ]
826
+ }
827
+ ],
828
+ traits: [
829
+ srcTrait(),
830
+ posterTrait(),
831
+ controlsTrait(),
832
+ autoplayTrait(),
833
+ loopTrait(),
834
+ mutedTrait(),
835
+ idTrait(),
836
+ titleTrait(),
837
+ ariaLabelTrait({ description: "Accessible name summarizing the video content." })
838
+ ],
839
+ validateProps: (props) => {
840
+ const errors = [];
841
+ if (props.src !== void 0 && typeof props.src !== "string" && !isVariableBinding9(props.src)) {
842
+ errors.push('Video "src" must be a string when provided.');
843
+ }
844
+ if (props.provider !== void 0 && !isVariableBinding9(props.provider)) {
845
+ const allowed = ["auto", "html5", "youtube", "vimeo"];
846
+ if (typeof props.provider !== "string" || !allowed.includes(props.provider)) {
847
+ errors.push(`Video "provider" must be one of: ${allowed.join(", ")}.`);
848
+ }
849
+ }
850
+ if (props.controls !== void 0 && typeof props.controls !== "boolean" && !isVariableBinding9(props.controls)) {
851
+ errors.push('Video "controls" must be a boolean.');
852
+ }
853
+ if (props.autoplay !== void 0 && typeof props.autoplay !== "boolean" && !isVariableBinding9(props.autoplay)) {
854
+ errors.push('Video "autoplay" must be a boolean.');
855
+ }
856
+ if (props.loop !== void 0 && typeof props.loop !== "boolean" && !isVariableBinding9(props.loop)) {
857
+ errors.push('Video "loop" must be a boolean.');
858
+ }
859
+ if (props.muted !== void 0 && typeof props.muted !== "boolean" && !isVariableBinding9(props.muted)) {
860
+ errors.push('Video "muted" must be a boolean.');
861
+ }
862
+ return errors.length > 0 ? errors : true;
863
+ },
864
+ defaultStyles: {
865
+ base: {
866
+ width: "100%",
867
+ maxWidth: "800px",
868
+ borderRadius: "8px",
869
+ overflow: "hidden",
870
+ display: "block",
871
+ margin: "0 0 16px 0"
872
+ }
873
+ }
874
+ };
875
+
876
+ // src/definitions/media/icon.ts
877
+ import { isVariableBinding as isVariableBinding10 } from "@kubuild/schema";
878
+ var iconDefinition = {
879
+ type: "icon",
880
+ label: "Icon",
881
+ category: "media",
882
+ icon: "sparkles",
883
+ acceptsChildren: false,
884
+ defaultProps: {
885
+ name: "star",
886
+ size: 24,
887
+ color: "#2563eb",
888
+ strokeWidth: 2
889
+ },
890
+ propFields: [
891
+ { name: "name", label: "Icon Name (Lucide)", type: "string", defaultValue: "star" },
892
+ { name: "size", label: "Size (px)", type: "number", defaultValue: 24 },
893
+ { name: "color", label: "Color", type: "color", defaultValue: "#2563eb" },
894
+ { name: "strokeWidth", label: "Stroke Width", type: "number", defaultValue: 2 }
895
+ ],
896
+ traits: [
897
+ idTrait(),
898
+ titleTrait(),
899
+ ariaLabelTrait({ required: true, description: "Required: describes what the icon represents for screen readers." })
900
+ ],
901
+ validateProps: (props) => {
902
+ const errors = [];
903
+ if (props.name !== void 0 && !isVariableBinding10(props.name) && (typeof props.name !== "string" || props.name.trim().length === 0)) {
904
+ errors.push('Icon requires a non-empty "name".');
905
+ }
906
+ if (props.size !== void 0 && !isVariableBinding10(props.size)) {
907
+ if (typeof props.size !== "number" || props.size < 0) {
908
+ errors.push('Icon "size" must be a non-negative number.');
909
+ }
910
+ }
911
+ if (props.strokeWidth !== void 0 && !isVariableBinding10(props.strokeWidth)) {
912
+ if (typeof props.strokeWidth !== "number" || props.strokeWidth < 0) {
913
+ errors.push('Icon "strokeWidth" must be a non-negative number.');
914
+ }
915
+ }
916
+ return errors.length > 0 ? errors : true;
917
+ },
918
+ defaultStyles: {
919
+ base: {
920
+ display: "inline-flex",
921
+ alignItems: "center",
922
+ justifyContent: "center"
923
+ }
924
+ }
925
+ };
926
+
927
+ // src/definitions/media/html-embed.ts
928
+ import { isVariableBinding as isVariableBinding11 } from "@kubuild/schema";
929
+ var htmlEmbedDefinition = {
930
+ type: "html-embed",
931
+ label: "HTML Embed",
932
+ category: "custom",
933
+ icon: "code",
934
+ acceptsChildren: false,
935
+ defaultProps: {
936
+ html: '<div style="padding: 16px; background: #f1f5f9; border-radius: 8px; text-align: center; font-family: sans-serif; color: #475569;">Custom HTML Embed Content</div>'
937
+ },
938
+ propFields: [
939
+ {
940
+ name: "html",
941
+ label: "HTML / Embed Code",
942
+ type: "textarea",
943
+ defaultValue: '<div style="padding: 16px; background: #f1f5f9; border-radius: 8px; text-align: center; font-family: sans-serif; color: #475569;">Custom HTML Embed Content</div>'
944
+ }
945
+ ],
946
+ traits: [
947
+ idTrait(),
948
+ ariaLabelTrait()
949
+ ],
950
+ validateProps: (props) => {
951
+ const errors = [];
952
+ if (props.html !== void 0 && typeof props.html !== "string" && !isVariableBinding11(props.html)) {
953
+ errors.push('HTML Embed "html" must be a string.');
954
+ }
955
+ return errors.length > 0 ? errors : true;
956
+ },
957
+ defaultStyles: {
958
+ base: {
959
+ width: "100%",
960
+ margin: "0 0 16px 0"
961
+ }
962
+ }
963
+ };
964
+
965
+ // src/definitions/data/table.ts
966
+ import { isVariableBinding as isVariableBinding12 } from "@kubuild/schema";
967
+ var tableDefinition = {
968
+ type: "table",
969
+ label: "Table",
970
+ category: "layout",
971
+ icon: "table",
972
+ acceptsChildren: true,
973
+ allowedChildren: ["table-row"],
974
+ defaultProps: {
975
+ striped: false,
976
+ bordered: true,
977
+ compact: false
978
+ },
979
+ defaultChildren: [
980
+ {
981
+ type: "table-row",
982
+ children: [
983
+ { type: "table-cell", props: { tag: "th", text: "Header 1" } },
984
+ { type: "table-cell", props: { tag: "th", text: "Header 2" } }
985
+ ]
986
+ },
987
+ {
988
+ type: "table-row",
989
+ children: [
990
+ { type: "table-cell", props: { tag: "td", text: "Data 1" } },
991
+ { type: "table-cell", props: { tag: "td", text: "Data 2" } }
992
+ ]
993
+ }
994
+ ],
995
+ propFields: [
996
+ { name: "striped", label: "Striped Rows", type: "boolean", defaultValue: false },
997
+ { name: "bordered", label: "Bordered", type: "boolean", defaultValue: true },
998
+ { name: "compact", label: "Compact Spacing", type: "boolean", defaultValue: false }
999
+ ],
1000
+ traits: [
1001
+ idTrait(),
1002
+ ariaLabelTrait({ description: "Required: provides a caption summary for the table when no visible caption exists." })
1003
+ ],
1004
+ validateProps: (props) => {
1005
+ const errors = [];
1006
+ if (props.striped !== void 0 && typeof props.striped !== "boolean" && !isVariableBinding12(props.striped)) {
1007
+ errors.push('Table "striped" must be a boolean.');
1008
+ }
1009
+ if (props.bordered !== void 0 && typeof props.bordered !== "boolean" && !isVariableBinding12(props.bordered)) {
1010
+ errors.push('Table "bordered" must be a boolean.');
1011
+ }
1012
+ if (props.compact !== void 0 && typeof props.compact !== "boolean" && !isVariableBinding12(props.compact)) {
1013
+ errors.push('Table "compact" must be a boolean.');
1014
+ }
1015
+ return errors.length > 0 ? errors : true;
1016
+ },
1017
+ defaultStyles: {
1018
+ base: {
1019
+ width: "100%",
1020
+ margin: "0 0 16px 0",
1021
+ borderCollapse: "collapse"
1022
+ }
1023
+ }
1024
+ };
1025
+ var tableRowDefinition = {
1026
+ type: "table-row",
1027
+ label: "Table Row",
1028
+ category: "layout",
1029
+ icon: "table-row",
1030
+ acceptsChildren: true,
1031
+ allowedChildren: ["table-cell"],
1032
+ disallowedParents: ["page"],
1033
+ defaultProps: {},
1034
+ defaultChildren: [
1035
+ { type: "table-cell", props: { tag: "td", text: "Data" } }
1036
+ ],
1037
+ traits: [
1038
+ idTrait(),
1039
+ ariaLabelTrait()
1040
+ ],
1041
+ defaultStyles: {
1042
+ base: {}
1043
+ }
1044
+ };
1045
+ var tableCellDefinition = {
1046
+ type: "table-cell",
1047
+ label: "Table Cell",
1048
+ category: "layout",
1049
+ icon: "table-cell",
1050
+ acceptsChildren: true,
1051
+ allowedChildren: [
1052
+ "heading",
1053
+ "text",
1054
+ "paragraph",
1055
+ "link",
1056
+ "blockquote",
1057
+ "badge",
1058
+ "code-block",
1059
+ "image",
1060
+ "video",
1061
+ "icon",
1062
+ "html-embed",
1063
+ "button",
1064
+ "list",
1065
+ "custom"
1066
+ ],
1067
+ disallowedParents: ["page"],
1068
+ defaultProps: {
1069
+ tag: "td",
1070
+ text: "Cell",
1071
+ colSpan: 1,
1072
+ rowSpan: 1
1073
+ },
1074
+ propFields: [
1075
+ {
1076
+ name: "tag",
1077
+ label: "Cell Type",
1078
+ type: "select",
1079
+ defaultValue: "td",
1080
+ options: [
1081
+ { label: "Data Cell (td)", value: "td" },
1082
+ { label: "Header Cell (th)", value: "th" }
1083
+ ]
1084
+ },
1085
+ { name: "text", label: "Text", type: "string", defaultValue: "Cell" },
1086
+ { name: "colSpan", label: "Column Span (colSpan)", type: "number", defaultValue: 1 },
1087
+ { name: "rowSpan", label: "Row Span (rowSpan)", type: "number", defaultValue: 1 }
1088
+ ],
1089
+ traits: [
1090
+ colSpanTrait(),
1091
+ rowSpanTrait(),
1092
+ idTrait(),
1093
+ ariaLabelTrait()
1094
+ ],
1095
+ validateProps: (props) => {
1096
+ const errors = [];
1097
+ if (props.tag !== void 0 && !isVariableBinding12(props.tag)) {
1098
+ if (props.tag !== "td" && props.tag !== "th") {
1099
+ errors.push('Table Cell "tag" must be either "td" or "th".');
1100
+ }
1101
+ }
1102
+ if (props.colSpan !== void 0 && !isVariableBinding12(props.colSpan)) {
1103
+ if (typeof props.colSpan !== "number" || props.colSpan < 1 || !Number.isInteger(props.colSpan)) {
1104
+ errors.push('Table Cell "colSpan" must be a positive integer (>= 1).');
1105
+ }
1106
+ }
1107
+ if (props.rowSpan !== void 0 && !isVariableBinding12(props.rowSpan)) {
1108
+ if (typeof props.rowSpan !== "number" || props.rowSpan < 1 || !Number.isInteger(props.rowSpan)) {
1109
+ errors.push('Table Cell "rowSpan" must be a positive integer (>= 1).');
1110
+ }
1111
+ }
1112
+ if (props.text !== void 0 && typeof props.text !== "string" && !isVariableBinding12(props.text)) {
1113
+ errors.push('Table Cell "text" must be a string when provided.');
1114
+ }
1115
+ return errors.length > 0 ? errors : true;
1116
+ },
1117
+ defaultStyles: {
1118
+ base: {
1119
+ padding: "8px 12px",
1120
+ borderWidth: "1px",
1121
+ borderColor: "#e2e8f0",
1122
+ borderStyle: "solid",
1123
+ textAlign: "left"
1124
+ }
1125
+ }
1126
+ };
1127
+
1128
+ // src/definitions/data/list.ts
1129
+ import { isVariableBinding as isVariableBinding13 } from "@kubuild/schema";
1130
+ var listDefinition = {
1131
+ type: "list",
1132
+ label: "List",
1133
+ category: "typography",
1134
+ icon: "list",
1135
+ acceptsChildren: true,
1136
+ allowedChildren: ["list-item"],
1137
+ defaultProps: {
1138
+ tag: "ul",
1139
+ listStyleType: "disc"
1140
+ },
1141
+ defaultChildren: [
1142
+ { type: "list-item", props: { text: "List item 1" } },
1143
+ { type: "list-item", props: { text: "List item 2" } },
1144
+ { type: "list-item", props: { text: "List item 3" } }
1145
+ ],
1146
+ propFields: [
1147
+ {
1148
+ name: "tag",
1149
+ label: "Tag",
1150
+ type: "select",
1151
+ defaultValue: "ul",
1152
+ options: [
1153
+ { label: "Unordered (ul)", value: "ul" },
1154
+ { label: "Ordered (ol)", value: "ol" }
1155
+ ]
1156
+ },
1157
+ {
1158
+ name: "listStyleType",
1159
+ label: "List Style Type",
1160
+ type: "select",
1161
+ defaultValue: "disc",
1162
+ options: [
1163
+ { label: "Disc", value: "disc" },
1164
+ { label: "Circle", value: "circle" },
1165
+ { label: "Square", value: "square" },
1166
+ { label: "Decimal", value: "decimal" },
1167
+ { label: "None", value: "none" },
1168
+ { label: "Custom Icon", value: "custom-icon" }
1169
+ ]
1170
+ }
1171
+ ],
1172
+ traits: [
1173
+ idTrait(),
1174
+ ariaLabelTrait({ description: 'Accessible name for the list (e.g. "Navigation menu", "Features").' })
1175
+ ],
1176
+ validateProps: (props) => {
1177
+ const errors = [];
1178
+ if (props.tag !== void 0 && !isVariableBinding13(props.tag)) {
1179
+ if (props.tag !== "ul" && props.tag !== "ol") {
1180
+ errors.push('List "tag" must be either "ul" or "ol".');
1181
+ }
1182
+ }
1183
+ if (props.listStyleType !== void 0 && !isVariableBinding13(props.listStyleType)) {
1184
+ const allowed = ["disc", "circle", "square", "decimal", "none", "custom-icon"];
1185
+ if (typeof props.listStyleType !== "string" || !allowed.includes(props.listStyleType)) {
1186
+ errors.push(`List "listStyleType" must be one of: ${allowed.join(", ")}.`);
1187
+ }
1188
+ }
1189
+ return errors.length > 0 ? errors : true;
1190
+ },
1191
+ defaultStyles: {
1192
+ base: {
1193
+ margin: "0 0 16px 0",
1194
+ paddingLeft: "24px"
1195
+ }
1196
+ }
1197
+ };
1198
+ var listItemDefinition = {
1199
+ type: "list-item",
1200
+ label: "List Item",
1201
+ category: "typography",
1202
+ icon: "list-item",
1203
+ acceptsChildren: true,
1204
+ allowedChildren: [
1205
+ "heading",
1206
+ "text",
1207
+ "paragraph",
1208
+ "link",
1209
+ "blockquote",
1210
+ "badge",
1211
+ "code-block",
1212
+ "image",
1213
+ "video",
1214
+ "icon",
1215
+ "html-embed",
1216
+ "button",
1217
+ "list",
1218
+ "custom"
1219
+ ],
1220
+ defaultProps: {
1221
+ text: "List item"
1222
+ },
1223
+ propFields: [
1224
+ {
1225
+ name: "text",
1226
+ label: "Text",
1227
+ type: "string",
1228
+ defaultValue: "List item"
1229
+ }
1230
+ ],
1231
+ traits: [
1232
+ idTrait(),
1233
+ titleTrait(),
1234
+ ariaLabelTrait()
1235
+ ],
1236
+ validateProps: (props) => {
1237
+ const errors = [];
1238
+ if (props.text !== void 0 && typeof props.text !== "string" && !isVariableBinding13(props.text)) {
1239
+ errors.push('List Item "text" must be a string when provided.');
1240
+ }
1241
+ return errors.length > 0 ? errors : true;
1242
+ },
1243
+ defaultStyles: {
1244
+ base: {
1245
+ margin: "4px 0",
1246
+ fontSize: "16px",
1247
+ color: "#374151",
1248
+ lineHeight: "1.5"
1249
+ }
1250
+ }
1251
+ };
1252
+
1253
+ // src/definitions/data/collection.ts
1254
+ var collectionDefinition = {
1255
+ type: "collection",
1256
+ label: "Collection",
1257
+ category: "data",
1258
+ icon: "database",
1259
+ acceptsChildren: true,
1260
+ defaultProps: {
1261
+ sourceKey: "items",
1262
+ itemAlias: "item"
1263
+ },
1264
+ propFields: [
1265
+ { name: "sourceKey", label: "Source Variable", type: "string", defaultValue: "items" },
1266
+ { name: "itemAlias", label: "Item Alias", type: "string", defaultValue: "item" }
1267
+ ],
1268
+ traits: [
1269
+ idTrait(),
1270
+ ariaLabelTrait({ description: 'Accessible name summarizing the repeated collection (e.g. "Product list").' })
1271
+ ]
1272
+ };
1273
+
1274
+ // src/definitions/form/button.ts
1275
+ import { isActionBinding, isVariableBinding as isVariableBinding14 } from "@kubuild/schema";
1276
+ var buttonDefinition = {
1277
+ type: "button",
1278
+ label: "Button",
1279
+ category: "interactive",
1280
+ icon: "mouse-pointer",
1281
+ acceptsChildren: false,
1282
+ capabilities: ["actionRegistry"],
1283
+ defaultProps: {
1284
+ label: "Click Me",
1285
+ variant: "primary"
1286
+ },
1287
+ propFields: [
1288
+ { name: "label", label: "Label", type: "string", defaultValue: "Click Me" },
1289
+ { name: "href", label: "Link URL", type: "string" },
1290
+ { name: "action", label: "Action", type: "action" },
1291
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
1292
+ {
1293
+ name: "buttonType",
1294
+ label: "Button Type",
1295
+ type: "select",
1296
+ defaultValue: "button",
1297
+ options: [
1298
+ { label: "Button", value: "button" },
1299
+ { label: "Submit Form (submit)", value: "submit" },
1300
+ { label: "Reset Form (reset)", value: "reset" }
1301
+ ]
1302
+ },
1303
+ {
1304
+ name: "variant",
1305
+ label: "Variant",
1306
+ type: "select",
1307
+ defaultValue: "primary",
1308
+ options: [
1309
+ { label: "Primary", value: "primary" },
1310
+ { label: "Secondary", value: "secondary" }
1311
+ ]
1312
+ }
1313
+ ],
1314
+ traits: [
1315
+ buttonTypeTrait(),
1316
+ disabledTrait(),
1317
+ hrefTrait({ description: "Optional URL \u2014 when set, the button renders as an anchor styled like a button." }),
1318
+ targetTrait({ description: "Where to open the href URL (only used when href is set)." }),
1319
+ relTrait({ description: "Relationship tokens (only used when href is set)." }),
1320
+ idTrait(),
1321
+ titleTrait(),
1322
+ ariaLabelTrait()
1323
+ ],
1324
+ validateProps: (props) => {
1325
+ const errors = [];
1326
+ const hasLabel = typeof props.label === "string" && props.label.trim().length > 0 || isVariableBinding14(props.label);
1327
+ if (!hasLabel) {
1328
+ errors.push('Button requires a non-empty "label".');
1329
+ }
1330
+ if (props.href !== void 0 && typeof props.href !== "string" && !isVariableBinding14(props.href)) {
1331
+ errors.push('Button "href" must be a string when provided.');
1332
+ }
1333
+ if (props.buttonType !== void 0 && !isVariableBinding14(props.buttonType)) {
1334
+ if (!["button", "submit", "reset"].includes(props.buttonType)) {
1335
+ errors.push('Button "buttonType" must be one of: "button", "submit", "reset".');
1336
+ }
1337
+ }
1338
+ if (props.action !== void 0 && !isActionBinding(props.action)) {
1339
+ errors.push('Button "action" must be a valid action binding when provided.');
1340
+ }
1341
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !isVariableBinding14(props.disabled)) {
1342
+ errors.push('Button "disabled" must be a boolean when provided.');
1343
+ }
1344
+ return errors.length > 0 ? errors : true;
1345
+ },
1346
+ defaultStyles: {
1347
+ base: {
1348
+ backgroundColor: "#2563eb",
1349
+ color: "#ffffff",
1350
+ paddingTop: "10px",
1351
+ paddingBottom: "10px",
1352
+ paddingLeft: "20px",
1353
+ paddingRight: "20px",
1354
+ borderRadius: "6px",
1355
+ fontWeight: "500",
1356
+ fontSize: "15px",
1357
+ border: "none",
1358
+ cursor: "pointer"
1359
+ }
1360
+ }
1361
+ };
1362
+ var buttonSubmitDefinition = {
1363
+ type: "button-submit",
1364
+ label: "Submit Button",
1365
+ category: "form",
1366
+ icon: "send",
1367
+ acceptsChildren: false,
1368
+ capabilities: ["actionRegistry"],
1369
+ disallowedParents: ["page"],
1370
+ defaultProps: {
1371
+ label: "Submit",
1372
+ loadingText: "Submitting...",
1373
+ showSpinner: true,
1374
+ autoDisableOnSubmit: true,
1375
+ variant: "primary",
1376
+ disabled: false,
1377
+ buttonType: "submit"
1378
+ },
1379
+ propFields: [
1380
+ { name: "label", label: "Label", type: "string", defaultValue: "Submit" },
1381
+ { name: "loadingText", label: "Loading Text", type: "string", defaultValue: "Submitting..." },
1382
+ { name: "showSpinner", label: "Show Loading Spinner", type: "boolean", defaultValue: true },
1383
+ { name: "autoDisableOnSubmit", label: "Auto Disable on Submit", type: "boolean", defaultValue: true },
1384
+ {
1385
+ name: "buttonType",
1386
+ label: "Button Type",
1387
+ type: "select",
1388
+ defaultValue: "submit",
1389
+ options: [
1390
+ { label: "Submit Form (submit)", value: "submit" },
1391
+ { label: "Reset Form (reset)", value: "reset" }
1392
+ ]
1393
+ },
1394
+ {
1395
+ name: "variant",
1396
+ label: "Variant",
1397
+ type: "select",
1398
+ defaultValue: "primary",
1399
+ options: [
1400
+ { label: "Primary", value: "primary" },
1401
+ { label: "Secondary", value: "secondary" }
1402
+ ]
1403
+ },
1404
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
1405
+ { name: "prefixIcon", label: "Prefix Icon", type: "string" },
1406
+ { name: "suffixIcon", label: "Suffix Icon", type: "string" }
1407
+ ],
1408
+ traits: [
1409
+ buttonTypeTrait({
1410
+ defaultValue: "submit",
1411
+ options: [
1412
+ { label: "Submit Form (submit)", value: "submit" },
1413
+ { label: "Reset Form (reset)", value: "reset" }
1414
+ ]
1415
+ }),
1416
+ labelTextTrait({ defaultValue: "Submit", label: "Label" }),
1417
+ loadingTextTrait(),
1418
+ showSpinnerTrait(),
1419
+ autoDisableOnSubmitTrait(),
1420
+ disabledTrait(),
1421
+ prefixIconTrait(),
1422
+ suffixIconTrait(),
1423
+ idTrait(),
1424
+ titleTrait(),
1425
+ ariaLabelTrait()
1426
+ ],
1427
+ validateProps: (props) => {
1428
+ const errors = [];
1429
+ const hasLabel = typeof props.label === "string" && props.label.trim().length > 0 || isVariableBinding14(props.label);
1430
+ if (!hasLabel) {
1431
+ errors.push('Submit Button requires a non-empty "label".');
1432
+ }
1433
+ if (props.loadingText !== void 0 && typeof props.loadingText !== "string" && !isVariableBinding14(props.loadingText)) {
1434
+ errors.push('Submit Button "loadingText" must be a string when provided.');
1435
+ }
1436
+ if (props.showSpinner !== void 0 && typeof props.showSpinner !== "boolean" && !isVariableBinding14(props.showSpinner)) {
1437
+ errors.push('Submit Button "showSpinner" must be a boolean when provided.');
1438
+ }
1439
+ if (props.autoDisableOnSubmit !== void 0 && typeof props.autoDisableOnSubmit !== "boolean" && !isVariableBinding14(props.autoDisableOnSubmit)) {
1440
+ errors.push('Submit Button "autoDisableOnSubmit" must be a boolean when provided.');
1441
+ }
1442
+ if (props.buttonType !== void 0 && !isVariableBinding14(props.buttonType)) {
1443
+ if (!["submit", "reset", "button"].includes(props.buttonType)) {
1444
+ errors.push('Submit Button "buttonType" must be one of: "submit", "reset", "button".');
1445
+ }
1446
+ }
1447
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !isVariableBinding14(props.disabled)) {
1448
+ errors.push('Submit Button "disabled" must be a boolean when provided.');
1449
+ }
1450
+ return errors.length > 0 ? errors : true;
1451
+ },
1452
+ defaultStyles: {
1453
+ base: {
1454
+ backgroundColor: "#2563eb",
1455
+ color: "#ffffff",
1456
+ paddingTop: "10px",
1457
+ paddingBottom: "10px",
1458
+ paddingLeft: "20px",
1459
+ paddingRight: "20px",
1460
+ borderRadius: "6px",
1461
+ fontWeight: "500",
1462
+ fontSize: "15px",
1463
+ border: "none",
1464
+ cursor: "pointer",
1465
+ display: "inline-flex",
1466
+ alignItems: "center",
1467
+ justifyContent: "center",
1468
+ gap: "8px"
1469
+ }
1470
+ }
1471
+ };
1472
+
1473
+ // src/definitions/form/form.ts
1474
+ import { isVariableBinding as isVariableBinding15 } from "@kubuild/schema";
1475
+ var formDefinition = {
1476
+ type: "form",
1477
+ label: "Form",
1478
+ category: "form",
1479
+ icon: "form",
1480
+ acceptsChildren: true,
1481
+ allowedChildren: [
1482
+ ...CONTENT_CHILD_TYPES,
1483
+ "container",
1484
+ "columns",
1485
+ "section"
1486
+ ],
1487
+ disallowedParents: ["page"],
1488
+ defaultProps: {
1489
+ name: "contact_form",
1490
+ method: "POST",
1491
+ action: "",
1492
+ target: "_self",
1493
+ autoComplete: "on",
1494
+ preventDefault: true,
1495
+ scrollToFirstError: true,
1496
+ resetOnSubmit: false
1497
+ },
1498
+ defaultChildren: [
1499
+ { type: "input", props: { name: "name", type: "text", placeholder: "Your Name", required: true } },
1500
+ { type: "input", props: { name: "email", type: "email", placeholder: "Your Email", required: true } },
1501
+ { type: "textarea", props: { name: "message", placeholder: "Your Message", rows: 4, required: true } },
1502
+ { type: "checkbox", props: { name: "agree", label: "I agree to the terms and privacy policy", required: true } },
1503
+ { type: "button", props: { label: "Send Message", variant: "primary", buttonType: "submit" } }
1504
+ ],
1505
+ propFields: [
1506
+ { name: "name", label: "Form Name", type: "string", defaultValue: "contact_form" },
1507
+ { name: "action", label: "Action URL", type: "string" },
1508
+ {
1509
+ name: "method",
1510
+ label: "Method",
1511
+ type: "select",
1512
+ defaultValue: "POST",
1513
+ options: [
1514
+ { label: "POST", value: "POST" },
1515
+ { label: "GET", value: "GET" }
1516
+ ]
1517
+ },
1518
+ {
1519
+ name: "target",
1520
+ label: "Target",
1521
+ type: "select",
1522
+ defaultValue: "_self",
1523
+ options: [
1524
+ { label: "Same Window (_self)", value: "_self" },
1525
+ { label: "New Tab (_blank)", value: "_blank" }
1526
+ ]
1527
+ },
1528
+ {
1529
+ name: "autoComplete",
1530
+ label: "Auto Complete",
1531
+ type: "select",
1532
+ defaultValue: "on",
1533
+ options: [
1534
+ { label: "On", value: "on" },
1535
+ { label: "Off", value: "off" }
1536
+ ]
1537
+ },
1538
+ { name: "preventDefault", label: "Prevent Default", type: "boolean", defaultValue: true },
1539
+ { name: "scrollToFirstError", label: "Scroll to First Error", type: "boolean", defaultValue: true },
1540
+ { name: "resetOnSubmit", label: "Reset on Submit", type: "boolean", defaultValue: false }
1541
+ ],
1542
+ traits: [
1543
+ fieldNameTrait({ defaultValue: "contact_form", required: false }),
1544
+ actionTrait(),
1545
+ methodTrait(),
1546
+ targetTrait({ options: [
1547
+ { label: "Same Window (_self)", value: "_self" },
1548
+ { label: "New Tab (_blank)", value: "_blank" },
1549
+ { label: "Parent (_parent)", value: "_parent" },
1550
+ { label: "Top (_top)", value: "_top" }
1551
+ ] }),
1552
+ autoCompleteTrait(),
1553
+ preventDefaultTrait(),
1554
+ scrollToFirstErrorTrait(),
1555
+ resetOnSubmitTrait(),
1556
+ idTrait(),
1557
+ ariaLabelTrait({ description: "Accessible name for the form landmark." })
1558
+ ],
1559
+ validateProps: (props) => {
1560
+ const errors = [];
1561
+ if (props.name !== void 0 && typeof props.name !== "string" && !isVariableBinding15(props.name)) {
1562
+ errors.push('Form "name" must be a string when provided.');
1563
+ }
1564
+ if (props.action !== void 0 && typeof props.action !== "string" && !isVariableBinding15(props.action)) {
1565
+ errors.push('Form "action" must be a string when provided.');
1566
+ }
1567
+ if (props.method !== void 0 && !isVariableBinding15(props.method)) {
1568
+ if (!["GET", "POST", "get", "post"].includes(props.method)) {
1569
+ errors.push('Form "method" must be either "GET" or "POST".');
1570
+ }
1571
+ }
1572
+ if (props.target !== void 0 && !isVariableBinding15(props.target)) {
1573
+ if (!["_self", "_blank", "_parent", "_top"].includes(props.target)) {
1574
+ errors.push('Form "target" must be one of: "_self", "_blank", "_parent", "_top".');
1575
+ }
1576
+ }
1577
+ if (props.autoComplete !== void 0 && !isVariableBinding15(props.autoComplete)) {
1578
+ if (!["on", "off"].includes(props.autoComplete)) {
1579
+ errors.push('Form "autoComplete" must be either "on" or "off".');
1580
+ }
1581
+ }
1582
+ if (props.preventDefault !== void 0 && typeof props.preventDefault !== "boolean" && !isVariableBinding15(props.preventDefault)) {
1583
+ errors.push('Form "preventDefault" must be a boolean when provided.');
1584
+ }
1585
+ if (props.scrollToFirstError !== void 0 && typeof props.scrollToFirstError !== "boolean" && !isVariableBinding15(props.scrollToFirstError)) {
1586
+ errors.push('Form "scrollToFirstError" must be a boolean when provided.');
1587
+ }
1588
+ if (props.resetOnSubmit !== void 0 && typeof props.resetOnSubmit !== "boolean" && !isVariableBinding15(props.resetOnSubmit)) {
1589
+ errors.push('Form "resetOnSubmit" must be a boolean when provided.');
1590
+ }
1591
+ return errors.length > 0 ? errors : true;
1592
+ },
1593
+ defaultStyles: {
1594
+ base: {
1595
+ width: "100%",
1596
+ display: "flex",
1597
+ flexDirection: "column",
1598
+ gap: "16px"
1599
+ }
1600
+ }
1601
+ };
1602
+
1603
+ // src/definitions/form/input.ts
1604
+ import { isVariableBinding as isVariableBinding16 } from "@kubuild/schema";
1605
+ var inputDefinition = {
1606
+ type: "input",
1607
+ label: "Input",
1608
+ category: "form",
1609
+ icon: "input",
1610
+ acceptsChildren: false,
1611
+ disallowedParents: ["page"],
1612
+ defaultProps: {
1613
+ name: "input_field",
1614
+ type: "text",
1615
+ placeholder: "Enter text...",
1616
+ defaultValue: "",
1617
+ required: false,
1618
+ disabled: false,
1619
+ readOnly: false,
1620
+ pattern: "",
1621
+ minLength: void 0,
1622
+ maxLength: void 0,
1623
+ prefixIcon: "",
1624
+ suffixIcon: "",
1625
+ helperText: ""
1626
+ },
1627
+ propFields: [
1628
+ { name: "name", label: "Field Name", type: "string", defaultValue: "input_field" },
1629
+ {
1630
+ name: "type",
1631
+ label: "Input Type",
1632
+ type: "select",
1633
+ defaultValue: "text",
1634
+ options: [
1635
+ { label: "Text", value: "text" },
1636
+ { label: "Email", value: "email" },
1637
+ { label: "Number", value: "number" },
1638
+ { label: "Password", value: "password" },
1639
+ { label: "Phone (tel)", value: "tel" },
1640
+ { label: "URL", value: "url" },
1641
+ { label: "Search", value: "search" },
1642
+ { label: "Date", value: "date" }
1643
+ ]
1644
+ },
1645
+ { name: "placeholder", label: "Placeholder", type: "string", defaultValue: "Enter text..." },
1646
+ { name: "defaultValue", label: "Default Value", type: "string" },
1647
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
1648
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
1649
+ { name: "readOnly", label: "Read Only", type: "boolean", defaultValue: false },
1650
+ { name: "pattern", label: "Pattern (regex)", type: "string" },
1651
+ { name: "minLength", label: "Min Length", type: "number" },
1652
+ { name: "maxLength", label: "Max Length", type: "number" },
1653
+ { name: "prefixIcon", label: "Prefix Icon", type: "string" },
1654
+ { name: "suffixIcon", label: "Suffix Icon", type: "string" },
1655
+ { name: "helperText", label: "Helper Text", type: "string" }
1656
+ ],
1657
+ traits: [
1658
+ inputTypeTrait({ options: [
1659
+ { label: "Text", value: "text" },
1660
+ { label: "Email", value: "email" },
1661
+ { label: "Number", value: "number" },
1662
+ { label: "Password", value: "password" },
1663
+ { label: "Phone (tel)", value: "tel" },
1664
+ { label: "URL", value: "url" },
1665
+ { label: "Search", value: "search" },
1666
+ { label: "Date", value: "date" },
1667
+ { label: "Hidden", value: "hidden" }
1668
+ ] }),
1669
+ fieldNameTrait({ defaultValue: "input_field" }),
1670
+ placeholderTrait({ defaultValue: "Enter text..." }),
1671
+ defaultValueTrait(),
1672
+ requiredTrait(),
1673
+ patternTrait(),
1674
+ minLengthTrait(),
1675
+ maxLengthTrait(),
1676
+ prefixIconTrait(),
1677
+ suffixIconTrait(),
1678
+ helperTextTrait(),
1679
+ disabledTrait(),
1680
+ readOnlyTrait(),
1681
+ idTrait(),
1682
+ ariaLabelTrait()
1683
+ ],
1684
+ validateProps: (props) => {
1685
+ const errors = [];
1686
+ if (props.name !== void 0 && typeof props.name !== "string" && !isVariableBinding16(props.name)) {
1687
+ errors.push('Input "name" must be a string when provided.');
1688
+ }
1689
+ if (props.type !== void 0 && !isVariableBinding16(props.type)) {
1690
+ const validTypes = ["text", "email", "number", "password", "tel", "url", "search", "date", "hidden"];
1691
+ if (!validTypes.includes(props.type)) {
1692
+ errors.push(`Input "type" must be one of: ${validTypes.join(", ")}.`);
1693
+ }
1694
+ }
1695
+ if (props.placeholder !== void 0 && typeof props.placeholder !== "string" && !isVariableBinding16(props.placeholder)) {
1696
+ errors.push('Input "placeholder" must be a string when provided.');
1697
+ }
1698
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !isVariableBinding16(props.required)) {
1699
+ errors.push('Input "required" must be a boolean when provided.');
1700
+ }
1701
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !isVariableBinding16(props.disabled)) {
1702
+ errors.push('Input "disabled" must be a boolean when provided.');
1703
+ }
1704
+ if (props.readOnly !== void 0 && typeof props.readOnly !== "boolean" && !isVariableBinding16(props.readOnly)) {
1705
+ errors.push('Input "readOnly" must be a boolean when provided.');
1706
+ }
1707
+ if (props.pattern !== void 0 && typeof props.pattern !== "string" && !isVariableBinding16(props.pattern)) {
1708
+ errors.push('Input "pattern" must be a string when provided.');
1709
+ }
1710
+ if (props.minLength !== void 0 && !isVariableBinding16(props.minLength)) {
1711
+ if (typeof props.minLength !== "number" || props.minLength < 0 || !Number.isInteger(props.minLength)) {
1712
+ errors.push('Input "minLength" must be a non-negative integer when provided.');
1713
+ }
1714
+ }
1715
+ if (props.maxLength !== void 0 && !isVariableBinding16(props.maxLength)) {
1716
+ if (typeof props.maxLength !== "number" || props.maxLength < 0 || !Number.isInteger(props.maxLength)) {
1717
+ errors.push('Input "maxLength" must be a non-negative integer when provided.');
1718
+ }
1719
+ }
1720
+ if (props.prefixIcon !== void 0 && typeof props.prefixIcon !== "string" && !isVariableBinding16(props.prefixIcon)) {
1721
+ errors.push('Input "prefixIcon" must be a string when provided.');
1722
+ }
1723
+ if (props.suffixIcon !== void 0 && typeof props.suffixIcon !== "string" && !isVariableBinding16(props.suffixIcon)) {
1724
+ errors.push('Input "suffixIcon" must be a string when provided.');
1725
+ }
1726
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !isVariableBinding16(props.helperText)) {
1727
+ errors.push('Input "helperText" must be a string when provided.');
1728
+ }
1729
+ return errors.length > 0 ? errors : true;
1730
+ },
1731
+ defaultStyles: {
1732
+ base: {
1733
+ width: "100%",
1734
+ paddingTop: "10px",
1735
+ paddingBottom: "10px",
1736
+ paddingLeft: "14px",
1737
+ paddingRight: "14px",
1738
+ borderRadius: "6px",
1739
+ borderWidth: "1px",
1740
+ borderStyle: "solid",
1741
+ borderColor: "#cbd5e1",
1742
+ fontSize: "14px",
1743
+ backgroundColor: "#ffffff",
1744
+ color: "#1e293b",
1745
+ boxSizing: "border-box"
1746
+ }
1747
+ }
1748
+ };
1749
+
1750
+ // src/definitions/form/textarea.ts
1751
+ import { isVariableBinding as isVariableBinding17 } from "@kubuild/schema";
1752
+ var textareaDefinition = {
1753
+ type: "textarea",
1754
+ label: "Textarea",
1755
+ category: "form",
1756
+ icon: "textarea",
1757
+ acceptsChildren: false,
1758
+ disallowedParents: ["page"],
1759
+ defaultProps: {
1760
+ name: "message",
1761
+ placeholder: "Enter your message...",
1762
+ defaultValue: "",
1763
+ rows: 4,
1764
+ required: false,
1765
+ disabled: false,
1766
+ readOnly: false,
1767
+ resize: "vertical",
1768
+ autoGrow: false,
1769
+ maxCharCount: void 0,
1770
+ helperText: ""
1771
+ },
1772
+ propFields: [
1773
+ { name: "name", label: "Field Name", type: "string", defaultValue: "message" },
1774
+ { name: "placeholder", label: "Placeholder", type: "string", defaultValue: "Enter your message..." },
1775
+ { name: "defaultValue", label: "Default Value", type: "textarea" },
1776
+ { name: "rows", label: "Rows", type: "number", defaultValue: 4 },
1777
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
1778
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
1779
+ { name: "readOnly", label: "Read Only", type: "boolean", defaultValue: false },
1780
+ {
1781
+ name: "resize",
1782
+ label: "Resize",
1783
+ type: "select",
1784
+ defaultValue: "vertical",
1785
+ options: [
1786
+ { label: "Vertical only", value: "vertical" },
1787
+ { label: "Horizontal only", value: "horizontal" },
1788
+ { label: "Both", value: "both" },
1789
+ { label: "None", value: "none" }
1790
+ ]
1791
+ },
1792
+ { name: "autoGrow", label: "Auto Grow", type: "boolean", defaultValue: false },
1793
+ { name: "maxCharCount", label: "Max Character Count", type: "number" },
1794
+ { name: "helperText", label: "Helper Text", type: "string" }
1795
+ ],
1796
+ traits: [
1797
+ fieldNameTrait({ defaultValue: "message" }),
1798
+ placeholderTrait({ defaultValue: "Enter your message..." }),
1799
+ defaultValueTrait(),
1800
+ rowsTrait(),
1801
+ resizeTrait(),
1802
+ autoGrowTrait(),
1803
+ maxCharCountTrait(),
1804
+ helperTextTrait(),
1805
+ requiredTrait(),
1806
+ disabledTrait(),
1807
+ readOnlyTrait(),
1808
+ idTrait(),
1809
+ ariaLabelTrait()
1810
+ ],
1811
+ validateProps: (props) => {
1812
+ const errors = [];
1813
+ if (props.name !== void 0 && typeof props.name !== "string" && !isVariableBinding17(props.name)) {
1814
+ errors.push('Textarea "name" must be a string when provided.');
1815
+ }
1816
+ if (props.rows !== void 0 && !isVariableBinding17(props.rows)) {
1817
+ if (typeof props.rows !== "number" || props.rows < 1 || !Number.isInteger(props.rows)) {
1818
+ errors.push('Textarea "rows" must be a positive integer (>= 1).');
1819
+ }
1820
+ }
1821
+ if (props.placeholder !== void 0 && typeof props.placeholder !== "string" && !isVariableBinding17(props.placeholder)) {
1822
+ errors.push('Textarea "placeholder" must be a string when provided.');
1823
+ }
1824
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !isVariableBinding17(props.required)) {
1825
+ errors.push('Textarea "required" must be a boolean when provided.');
1826
+ }
1827
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !isVariableBinding17(props.disabled)) {
1828
+ errors.push('Textarea "disabled" must be a boolean when provided.');
1829
+ }
1830
+ if (props.readOnly !== void 0 && typeof props.readOnly !== "boolean" && !isVariableBinding17(props.readOnly)) {
1831
+ errors.push('Textarea "readOnly" must be a boolean when provided.');
1832
+ }
1833
+ if (props.resize !== void 0 && !isVariableBinding17(props.resize)) {
1834
+ const allowedResize = ["vertical", "horizontal", "both", "none"];
1835
+ if (typeof props.resize !== "string" || !allowedResize.includes(props.resize)) {
1836
+ errors.push(`Textarea "resize" must be one of: ${allowedResize.join(", ")}.`);
1837
+ }
1838
+ }
1839
+ if (props.autoGrow !== void 0 && typeof props.autoGrow !== "boolean" && !isVariableBinding17(props.autoGrow)) {
1840
+ errors.push('Textarea "autoGrow" must be a boolean when provided.');
1841
+ }
1842
+ if (props.maxCharCount !== void 0 && !isVariableBinding17(props.maxCharCount)) {
1843
+ if (typeof props.maxCharCount !== "number" || props.maxCharCount < 1 || !Number.isInteger(props.maxCharCount)) {
1844
+ errors.push('Textarea "maxCharCount" must be a positive integer (>= 1) when provided.');
1845
+ }
1846
+ }
1847
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !isVariableBinding17(props.helperText)) {
1848
+ errors.push('Textarea "helperText" must be a string when provided.');
1849
+ }
1850
+ return errors.length > 0 ? errors : true;
1851
+ },
1852
+ defaultStyles: {
1853
+ base: {
1854
+ width: "100%",
1855
+ paddingTop: "10px",
1856
+ paddingBottom: "10px",
1857
+ paddingLeft: "14px",
1858
+ paddingRight: "14px",
1859
+ borderRadius: "6px",
1860
+ borderWidth: "1px",
1861
+ borderStyle: "solid",
1862
+ borderColor: "#cbd5e1",
1863
+ fontSize: "14px",
1864
+ backgroundColor: "#ffffff",
1865
+ color: "#1e293b",
1866
+ boxSizing: "border-box"
1867
+ }
1868
+ }
1869
+ };
1870
+
1871
+ // src/definitions/form/select.ts
1872
+ import { isVariableBinding as isVariableBinding18 } from "@kubuild/schema";
1873
+ var selectDefinition = {
1874
+ type: "select",
1875
+ label: "Select",
1876
+ category: "form",
1877
+ icon: "select",
1878
+ acceptsChildren: false,
1879
+ disallowedParents: ["page"],
1880
+ defaultProps: {
1881
+ name: "select_field",
1882
+ placeholder: "Select an option...",
1883
+ options: [
1884
+ { label: "Option 1", value: "option1" },
1885
+ { label: "Option 2", value: "option2" },
1886
+ { label: "Option 3", value: "option3" }
1887
+ ],
1888
+ defaultValue: "",
1889
+ required: false,
1890
+ disabled: false,
1891
+ helperText: ""
1892
+ },
1893
+ propFields: [
1894
+ { name: "name", label: "Field Name", type: "string", defaultValue: "select_field" },
1895
+ { name: "placeholder", label: "Placeholder", type: "string", defaultValue: "Select an option..." },
1896
+ {
1897
+ name: "options",
1898
+ label: "Options (JSON list)",
1899
+ type: "json",
1900
+ defaultValue: [
1901
+ { label: "Option 1", value: "option1" },
1902
+ { label: "Option 2", value: "option2" },
1903
+ { label: "Option 3", value: "option3" }
1904
+ ]
1905
+ },
1906
+ { name: "defaultValue", label: "Default Selected Value", type: "string" },
1907
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
1908
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
1909
+ { name: "helperText", label: "Helper Text", type: "string" }
1910
+ ],
1911
+ traits: [
1912
+ fieldNameTrait({ defaultValue: "select_field" }),
1913
+ placeholderTrait({ defaultValue: "Select an option..." }),
1914
+ optionsListTrait({ description: "The list of dropdown choices (label + value pairs). Editable via the inspector trait panel." }),
1915
+ defaultValueTrait({ description: "The initially selected option value (must match one of the option values)." }),
1916
+ helperTextTrait(),
1917
+ requiredTrait(),
1918
+ disabledTrait(),
1919
+ idTrait(),
1920
+ ariaLabelTrait()
1921
+ ],
1922
+ validateProps: (props) => {
1923
+ const errors = [];
1924
+ if (props.name !== void 0 && typeof props.name !== "string" && !isVariableBinding18(props.name)) {
1925
+ errors.push('Select "name" must be a string when provided.');
1926
+ }
1927
+ if (props.options !== void 0 && !isVariableBinding18(props.options)) {
1928
+ if (!Array.isArray(props.options) && typeof props.options !== "string") {
1929
+ errors.push('Select "options" must be an array of option objects or a JSON string.');
1930
+ }
1931
+ }
1932
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !isVariableBinding18(props.required)) {
1933
+ errors.push('Select "required" must be a boolean when provided.');
1934
+ }
1935
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !isVariableBinding18(props.disabled)) {
1936
+ errors.push('Select "disabled" must be a boolean when provided.');
1937
+ }
1938
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !isVariableBinding18(props.helperText)) {
1939
+ errors.push('Select "helperText" must be a string when provided.');
1940
+ }
1941
+ return errors.length > 0 ? errors : true;
1942
+ },
1943
+ defaultStyles: {
1944
+ base: {
1945
+ width: "100%",
1946
+ paddingTop: "10px",
1947
+ paddingBottom: "10px",
1948
+ paddingLeft: "14px",
1949
+ paddingRight: "14px",
1950
+ borderRadius: "6px",
1951
+ borderWidth: "1px",
1952
+ borderStyle: "solid",
1953
+ borderColor: "#cbd5e1",
1954
+ fontSize: "14px",
1955
+ backgroundColor: "#ffffff",
1956
+ color: "#1e293b",
1957
+ boxSizing: "border-box"
1958
+ }
1959
+ }
1960
+ };
1961
+
1962
+ // src/definitions/form/checkbox.ts
1963
+ import { isVariableBinding as isVariableBinding19 } from "@kubuild/schema";
1964
+ var checkboxDefinition = {
1965
+ type: "checkbox",
1966
+ label: "Checkbox",
1967
+ category: "form",
1968
+ icon: "checkbox",
1969
+ acceptsChildren: false,
1970
+ disallowedParents: ["page"],
1971
+ defaultProps: {
1972
+ name: "checkbox_field",
1973
+ label: "I agree to the terms and conditions",
1974
+ value: "yes",
1975
+ defaultChecked: false,
1976
+ indeterminate: false,
1977
+ required: false,
1978
+ disabled: false,
1979
+ helperText: ""
1980
+ },
1981
+ propFields: [
1982
+ { name: "name", label: "Field Name", type: "string", defaultValue: "checkbox_field" },
1983
+ { name: "label", label: "Label Text", type: "string", defaultValue: "I agree to the terms and conditions" },
1984
+ { name: "value", label: "Checked Value", type: "string", defaultValue: "yes" },
1985
+ { name: "defaultChecked", label: "Default Checked", type: "boolean", defaultValue: false },
1986
+ { name: "indeterminate", label: "Indeterminate", type: "boolean", defaultValue: false },
1987
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
1988
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
1989
+ { name: "helperText", label: "Helper Text", type: "string" }
1990
+ ],
1991
+ traits: [
1992
+ fieldNameTrait({ defaultValue: "checkbox_field" }),
1993
+ labelTextTrait({ defaultValue: "I agree to the terms and conditions" }),
1994
+ valueTrait({ defaultValue: "yes" }),
1995
+ defaultCheckedTrait(),
1996
+ indeterminateTrait(),
1997
+ helperTextTrait(),
1998
+ requiredTrait(),
1999
+ disabledTrait(),
2000
+ idTrait(),
2001
+ ariaLabelTrait()
2002
+ ],
2003
+ validateProps: (props) => {
2004
+ const errors = [];
2005
+ if (props.label !== void 0 && typeof props.label !== "string" && !isVariableBinding19(props.label)) {
2006
+ errors.push('Checkbox "label" must be a string when provided.');
2007
+ }
2008
+ if (props.name !== void 0 && typeof props.name !== "string" && !isVariableBinding19(props.name)) {
2009
+ errors.push('Checkbox "name" must be a string when provided.');
2010
+ }
2011
+ if (props.value !== void 0 && typeof props.value !== "string" && !isVariableBinding19(props.value)) {
2012
+ errors.push('Checkbox "value" must be a string when provided.');
2013
+ }
2014
+ if (props.defaultChecked !== void 0 && typeof props.defaultChecked !== "boolean" && !isVariableBinding19(props.defaultChecked)) {
2015
+ errors.push('Checkbox "defaultChecked" must be a boolean when provided.');
2016
+ }
2017
+ if (props.indeterminate !== void 0 && typeof props.indeterminate !== "boolean" && !isVariableBinding19(props.indeterminate)) {
2018
+ errors.push('Checkbox "indeterminate" must be a boolean when provided.');
2019
+ }
2020
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !isVariableBinding19(props.required)) {
2021
+ errors.push('Checkbox "required" must be a boolean when provided.');
2022
+ }
2023
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !isVariableBinding19(props.disabled)) {
2024
+ errors.push('Checkbox "disabled" must be a boolean when provided.');
2025
+ }
2026
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !isVariableBinding19(props.helperText)) {
2027
+ errors.push('Checkbox "helperText" must be a string when provided.');
2028
+ }
2029
+ return errors.length > 0 ? errors : true;
2030
+ },
2031
+ defaultStyles: {
2032
+ base: {
2033
+ display: "inline-flex",
2034
+ alignItems: "center",
2035
+ gap: "8px",
2036
+ fontSize: "14px",
2037
+ color: "#1e293b",
2038
+ cursor: "pointer",
2039
+ userSelect: "none"
2040
+ }
2041
+ }
2042
+ };
2043
+
2044
+ // src/definitions/form/switch.ts
2045
+ import { isVariableBinding as isVariableBinding20 } from "@kubuild/schema";
2046
+ var switchDefinition = {
2047
+ type: "switch",
2048
+ label: "Switch",
2049
+ category: "form",
2050
+ icon: "switch",
2051
+ acceptsChildren: false,
2052
+ disallowedParents: ["page"],
2053
+ defaultProps: {
2054
+ name: "switch_field",
2055
+ label: "Enable feature",
2056
+ value: "yes",
2057
+ defaultChecked: false,
2058
+ switchSize: "md",
2059
+ required: false,
2060
+ disabled: false,
2061
+ helperText: ""
2062
+ },
2063
+ propFields: [
2064
+ { name: "name", label: "Field Name", type: "string", defaultValue: "switch_field" },
2065
+ { name: "label", label: "Label Text", type: "string", defaultValue: "Enable feature" },
2066
+ { name: "value", label: "Checked Value", type: "string", defaultValue: "yes" },
2067
+ { name: "defaultChecked", label: "Default Checked", type: "boolean", defaultValue: false },
2068
+ {
2069
+ name: "switchSize",
2070
+ label: "Size",
2071
+ type: "select",
2072
+ defaultValue: "md",
2073
+ options: [
2074
+ { label: "Small", value: "sm" },
2075
+ { label: "Medium", value: "md" },
2076
+ { label: "Large", value: "lg" }
2077
+ ]
2078
+ },
2079
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
2080
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
2081
+ { name: "helperText", label: "Helper Text", type: "string" }
2082
+ ],
2083
+ traits: [
2084
+ fieldNameTrait({ defaultValue: "switch_field" }),
2085
+ labelTextTrait({ defaultValue: "Enable feature" }),
2086
+ valueTrait({ defaultValue: "yes" }),
2087
+ defaultCheckedTrait(),
2088
+ switchSizeTrait(),
2089
+ helperTextTrait(),
2090
+ requiredTrait(),
2091
+ disabledTrait(),
2092
+ idTrait(),
2093
+ ariaLabelTrait()
2094
+ ],
2095
+ validateProps: (props) => {
2096
+ const errors = [];
2097
+ if (props.label !== void 0 && typeof props.label !== "string" && !isVariableBinding20(props.label)) {
2098
+ errors.push('Switch "label" must be a string when provided.');
2099
+ }
2100
+ if (props.name !== void 0 && typeof props.name !== "string" && !isVariableBinding20(props.name)) {
2101
+ errors.push('Switch "name" must be a string when provided.');
2102
+ }
2103
+ if (props.value !== void 0 && typeof props.value !== "string" && !isVariableBinding20(props.value)) {
2104
+ errors.push('Switch "value" must be a string when provided.');
2105
+ }
2106
+ if (props.defaultChecked !== void 0 && typeof props.defaultChecked !== "boolean" && !isVariableBinding20(props.defaultChecked)) {
2107
+ errors.push('Switch "defaultChecked" must be a boolean when provided.');
2108
+ }
2109
+ if (props.switchSize !== void 0 && !isVariableBinding20(props.switchSize)) {
2110
+ const allowedSizes = ["sm", "md", "lg"];
2111
+ if (typeof props.switchSize !== "string" || !allowedSizes.includes(props.switchSize)) {
2112
+ errors.push(`Switch "switchSize" must be one of: ${allowedSizes.join(", ")}.`);
2113
+ }
2114
+ }
2115
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !isVariableBinding20(props.required)) {
2116
+ errors.push('Switch "required" must be a boolean when provided.');
2117
+ }
2118
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !isVariableBinding20(props.disabled)) {
2119
+ errors.push('Switch "disabled" must be a boolean when provided.');
2120
+ }
2121
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !isVariableBinding20(props.helperText)) {
2122
+ errors.push('Switch "helperText" must be a string when provided.');
2123
+ }
2124
+ return errors.length > 0 ? errors : true;
2125
+ },
2126
+ defaultStyles: {
2127
+ base: {
2128
+ display: "inline-flex",
2129
+ alignItems: "center",
2130
+ gap: "8px",
2131
+ fontSize: "14px",
2132
+ color: "#1e293b",
2133
+ cursor: "pointer",
2134
+ userSelect: "none"
2135
+ }
2136
+ }
2137
+ };
2138
+
2139
+ // src/definitions/form/radio.ts
2140
+ import { isVariableBinding as isVariableBinding21 } from "@kubuild/schema";
2141
+ var radioGroupDefinition = {
2142
+ type: "radio-group",
2143
+ label: "Radio Group",
2144
+ category: "form",
2145
+ icon: "radio-group",
2146
+ acceptsChildren: true,
2147
+ allowedChildren: ["radio", "radio-item", "custom"],
2148
+ disallowedParents: ["page"],
2149
+ defaultProps: {
2150
+ name: "radio_group",
2151
+ defaultSelected: "option1",
2152
+ orientation: "vertical",
2153
+ required: false,
2154
+ disabled: false,
2155
+ helperText: ""
2156
+ },
2157
+ defaultChildren: [
2158
+ { type: "radio", props: { name: "radio_group", label: "Option 1", value: "option1", defaultChecked: true } },
2159
+ { type: "radio", props: { name: "radio_group", label: "Option 2", value: "option2", defaultChecked: false } },
2160
+ { type: "radio", props: { name: "radio_group", label: "Option 3", value: "option3", defaultChecked: false } }
2161
+ ],
2162
+ propFields: [
2163
+ { name: "name", label: "Group Name", type: "string", defaultValue: "radio_group" },
2164
+ { name: "defaultSelected", label: "Default Selected", type: "string", defaultValue: "option1" },
2165
+ {
2166
+ name: "orientation",
2167
+ label: "Orientation",
2168
+ type: "select",
2169
+ defaultValue: "vertical",
2170
+ options: [
2171
+ { label: "Vertical", value: "vertical" },
2172
+ { label: "Horizontal", value: "horizontal" }
2173
+ ]
2174
+ },
2175
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
2176
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
2177
+ { name: "helperText", label: "Helper Text", type: "string" }
2178
+ ],
2179
+ traits: [
2180
+ fieldNameTrait({ defaultValue: "radio_group", label: "Group Name" }),
2181
+ defaultSelectedTrait({ defaultValue: "option1" }),
2182
+ orientationTrait(),
2183
+ helperTextTrait(),
2184
+ requiredTrait(),
2185
+ disabledTrait(),
2186
+ idTrait(),
2187
+ ariaLabelTrait()
2188
+ ],
2189
+ validateProps: (props) => {
2190
+ const errors = [];
2191
+ if (props.name !== void 0 && typeof props.name !== "string" && !isVariableBinding21(props.name)) {
2192
+ errors.push('RadioGroup "name" must be a string when provided.');
2193
+ }
2194
+ if (props.defaultSelected !== void 0 && typeof props.defaultSelected !== "string" && !isVariableBinding21(props.defaultSelected)) {
2195
+ errors.push('RadioGroup "defaultSelected" must be a string when provided.');
2196
+ }
2197
+ if (props.orientation !== void 0 && !isVariableBinding21(props.orientation)) {
2198
+ const allowedOrientations = ["vertical", "horizontal"];
2199
+ if (typeof props.orientation !== "string" || !allowedOrientations.includes(props.orientation)) {
2200
+ errors.push(`RadioGroup "orientation" must be one of: ${allowedOrientations.join(", ")}.`);
2201
+ }
2202
+ }
2203
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !isVariableBinding21(props.required)) {
2204
+ errors.push('RadioGroup "required" must be a boolean when provided.');
2205
+ }
2206
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !isVariableBinding21(props.disabled)) {
2207
+ errors.push('RadioGroup "disabled" must be a boolean when provided.');
2208
+ }
2209
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !isVariableBinding21(props.helperText)) {
2210
+ errors.push('RadioGroup "helperText" must be a string when provided.');
2211
+ }
2212
+ return errors.length > 0 ? errors : true;
2213
+ },
2214
+ defaultStyles: {
2215
+ base: {
2216
+ display: "flex",
2217
+ flexDirection: "column",
2218
+ gap: "8px"
2219
+ }
2220
+ }
2221
+ };
2222
+ var radioDefinition = {
2223
+ type: "radio",
2224
+ label: "Radio",
2225
+ category: "form",
2226
+ icon: "radio",
2227
+ acceptsChildren: false,
2228
+ disallowedParents: ["page"],
2229
+ defaultProps: {
2230
+ name: "radio_group",
2231
+ label: "Option 1",
2232
+ value: "option1",
2233
+ defaultChecked: false,
2234
+ required: false,
2235
+ disabled: false,
2236
+ helperText: ""
2237
+ },
2238
+ propFields: [
2239
+ { name: "name", label: "Group Name", type: "string", defaultValue: "radio_group" },
2240
+ { name: "label", label: "Label Text", type: "string", defaultValue: "Option 1" },
2241
+ { name: "value", label: "Radio Value", type: "string", defaultValue: "option1" },
2242
+ { name: "defaultChecked", label: "Default Selected", type: "boolean", defaultValue: false },
2243
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
2244
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
2245
+ { name: "helperText", label: "Helper Text", type: "string" }
2246
+ ],
2247
+ traits: [
2248
+ fieldNameTrait({ defaultValue: "radio_group", label: "Group Name" }),
2249
+ labelTextTrait({ defaultValue: "Option 1" }),
2250
+ valueTrait({ defaultValue: "option1" }),
2251
+ defaultCheckedTrait(),
2252
+ helperTextTrait(),
2253
+ requiredTrait(),
2254
+ disabledTrait(),
2255
+ idTrait(),
2256
+ ariaLabelTrait()
2257
+ ],
2258
+ validateProps: (props) => {
2259
+ const errors = [];
2260
+ if (props.label !== void 0 && typeof props.label !== "string" && !isVariableBinding21(props.label)) {
2261
+ errors.push('Radio "label" must be a string when provided.');
2262
+ }
2263
+ if (props.name !== void 0 && typeof props.name !== "string" && !isVariableBinding21(props.name)) {
2264
+ errors.push('Radio "name" must be a string when provided.');
2265
+ }
2266
+ if (props.value !== void 0 && typeof props.value !== "string" && !isVariableBinding21(props.value)) {
2267
+ errors.push('Radio "value" must be a string when provided.');
2268
+ }
2269
+ if (props.defaultChecked !== void 0 && typeof props.defaultChecked !== "boolean" && !isVariableBinding21(props.defaultChecked)) {
2270
+ errors.push('Radio "defaultChecked" must be a boolean when provided.');
2271
+ }
2272
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !isVariableBinding21(props.required)) {
2273
+ errors.push('Radio "required" must be a boolean when provided.');
2274
+ }
2275
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !isVariableBinding21(props.disabled)) {
2276
+ errors.push('Radio "disabled" must be a boolean when provided.');
2277
+ }
2278
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !isVariableBinding21(props.helperText)) {
2279
+ errors.push('Radio "helperText" must be a string when provided.');
2280
+ }
2281
+ return errors.length > 0 ? errors : true;
2282
+ },
2283
+ defaultStyles: {
2284
+ base: {
2285
+ display: "inline-flex",
2286
+ alignItems: "center",
2287
+ gap: "8px",
2288
+ fontSize: "14px",
2289
+ color: "#1e293b",
2290
+ cursor: "pointer",
2291
+ userSelect: "none"
2292
+ }
2293
+ }
2294
+ };
2295
+ var radioItemDefinition = {
2296
+ ...radioDefinition,
2297
+ type: "radio-item",
2298
+ label: "Radio Item"
2299
+ };
2300
+
2301
+ // src/definitions/form/file-upload.ts
2302
+ import { isVariableBinding as isVariableBinding22 } from "@kubuild/schema";
2303
+ var fileUploadDefinition = {
2304
+ type: "file-upload",
2305
+ label: "File Upload",
2306
+ category: "form",
2307
+ icon: "upload",
2308
+ acceptsChildren: false,
2309
+ disallowedParents: ["page"],
2310
+ defaultProps: {
2311
+ name: "file_upload",
2312
+ label: "Upload File",
2313
+ accept: "*/*",
2314
+ maxFileSize: 10,
2315
+ multiple: false,
2316
+ showPreview: true,
2317
+ required: false,
2318
+ disabled: false,
2319
+ helperText: ""
2320
+ },
2321
+ propFields: [
2322
+ { name: "name", label: "Field Name", type: "string", defaultValue: "file_upload" },
2323
+ { name: "label", label: "Label Text", type: "string", defaultValue: "Upload File" },
2324
+ { name: "accept", label: "Accepted File Types", type: "string", defaultValue: "*/*" },
2325
+ { name: "maxFileSize", label: "Max File Size (MB)", type: "number", defaultValue: 10 },
2326
+ { name: "multiple", label: "Allow Multiple Files", type: "boolean", defaultValue: false },
2327
+ { name: "showPreview", label: "Show Preview", type: "boolean", defaultValue: true },
2328
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
2329
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
2330
+ { name: "helperText", label: "Helper Text", type: "string" }
2331
+ ],
2332
+ traits: [
2333
+ fieldNameTrait({ defaultValue: "file_upload" }),
2334
+ labelTextTrait({ defaultValue: "Upload File" }),
2335
+ acceptTrait(),
2336
+ maxFileSizeTrait(),
2337
+ multipleTrait(),
2338
+ showPreviewTrait(),
2339
+ helperTextTrait(),
2340
+ requiredTrait(),
2341
+ disabledTrait(),
2342
+ idTrait(),
2343
+ ariaLabelTrait()
2344
+ ],
2345
+ validateProps: (props) => {
2346
+ const errors = [];
2347
+ if (props.label !== void 0 && typeof props.label !== "string" && !isVariableBinding22(props.label)) {
2348
+ errors.push('FileUpload "label" must be a string when provided.');
2349
+ }
2350
+ if (props.name !== void 0 && typeof props.name !== "string" && !isVariableBinding22(props.name)) {
2351
+ errors.push('FileUpload "name" must be a string when provided.');
2352
+ }
2353
+ if (props.accept !== void 0 && typeof props.accept !== "string" && !isVariableBinding22(props.accept)) {
2354
+ errors.push('FileUpload "accept" must be a string when provided.');
2355
+ }
2356
+ if (props.maxFileSize !== void 0 && !isVariableBinding22(props.maxFileSize)) {
2357
+ if (typeof props.maxFileSize !== "number" || props.maxFileSize <= 0) {
2358
+ errors.push('FileUpload "maxFileSize" must be a positive number when provided.');
2359
+ }
2360
+ }
2361
+ if (props.multiple !== void 0 && typeof props.multiple !== "boolean" && !isVariableBinding22(props.multiple)) {
2362
+ errors.push('FileUpload "multiple" must be a boolean when provided.');
2363
+ }
2364
+ if (props.showPreview !== void 0 && typeof props.showPreview !== "boolean" && !isVariableBinding22(props.showPreview)) {
2365
+ errors.push('FileUpload "showPreview" must be a boolean when provided.');
2366
+ }
2367
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !isVariableBinding22(props.required)) {
2368
+ errors.push('FileUpload "required" must be a boolean when provided.');
2369
+ }
2370
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !isVariableBinding22(props.disabled)) {
2371
+ errors.push('FileUpload "disabled" must be a boolean when provided.');
2372
+ }
2373
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !isVariableBinding22(props.helperText)) {
2374
+ errors.push('FileUpload "helperText" must be a string when provided.');
2375
+ }
2376
+ return errors.length > 0 ? errors : true;
2377
+ },
2378
+ defaultStyles: {
2379
+ base: {
2380
+ display: "flex",
2381
+ flexDirection: "column",
2382
+ gap: "8px",
2383
+ fontSize: "14px",
2384
+ color: "#1e293b"
2385
+ }
2386
+ }
2387
+ };
2388
+
2389
+ // src/definitions/interactive/modal.ts
2390
+ var modalDefinition = {
2391
+ type: "modal",
2392
+ label: "Modal",
2393
+ category: "interactive",
2394
+ icon: "layout",
2395
+ description: "Pop-up overlay dialog container with backdrop and close controls.",
2396
+ acceptsChildren: true,
2397
+ allowedChildren: ["*"],
2398
+ defaultProps: {
2399
+ modalId: "modal-dialog",
2400
+ title: "Modal Title",
2401
+ backdrop: true,
2402
+ closeOnBackdrop: true,
2403
+ closeOnEscape: true,
2404
+ size: "md",
2405
+ showCloseButton: true
2406
+ },
2407
+ propFields: [
2408
+ {
2409
+ name: "modalId",
2410
+ label: "Modal Target ID",
2411
+ type: "string",
2412
+ defaultValue: "modal-dialog",
2413
+ description: "Unique identifier targeted by open_modal and close_modal actions."
2414
+ },
2415
+ {
2416
+ name: "title",
2417
+ label: "Modal Title",
2418
+ type: "string",
2419
+ defaultValue: "Modal Title",
2420
+ description: "Header title text displayed at the top of the dialog."
2421
+ },
2422
+ {
2423
+ name: "size",
2424
+ label: "Size",
2425
+ type: "select",
2426
+ defaultValue: "md",
2427
+ options: [
2428
+ { label: "Small (400px)", value: "sm" },
2429
+ { label: "Medium (560px)", value: "md" },
2430
+ { label: "Large (768px)", value: "lg" },
2431
+ { label: "Full Screen", value: "fullscreen" }
2432
+ ]
2433
+ },
2434
+ {
2435
+ name: "backdrop",
2436
+ label: "Show Backdrop",
2437
+ type: "boolean",
2438
+ defaultValue: true
2439
+ },
2440
+ {
2441
+ name: "closeOnBackdrop",
2442
+ label: "Close on Backdrop Click",
2443
+ type: "boolean",
2444
+ defaultValue: true
2445
+ },
2446
+ {
2447
+ name: "closeOnEscape",
2448
+ label: "Close on Escape Key",
2449
+ type: "boolean",
2450
+ defaultValue: true
2451
+ },
2452
+ {
2453
+ name: "showCloseButton",
2454
+ label: "Show Close Button",
2455
+ type: "boolean",
2456
+ defaultValue: true
2457
+ }
2458
+ ],
2459
+ traits: [
2460
+ idTrait(),
2461
+ titleTrait(),
2462
+ ariaLabelTrait({ description: "Accessible name for the modal dialog." })
2463
+ ],
2464
+ defaultStyles: {
2465
+ base: {
2466
+ backgroundColor: "#ffffff",
2467
+ borderRadius: "12px",
2468
+ boxShadow: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
2469
+ padding: "24px",
2470
+ maxWidth: "560px",
2471
+ width: "100%"
2472
+ }
2473
+ }
2474
+ };
2475
+
2476
+ // src/definitions/interactive/drawer.ts
2477
+ var drawerDefinition = {
2478
+ type: "drawer",
2479
+ label: "Drawer",
2480
+ category: "interactive",
2481
+ icon: "sidebar",
2482
+ description: "Off-canvas slide-over panel container, ideal for mobile navigation and side sheets.",
2483
+ acceptsChildren: true,
2484
+ allowedChildren: ["*"],
2485
+ defaultProps: {
2486
+ modalId: "mobile-drawer",
2487
+ title: "Navigation Menu",
2488
+ placement: "right",
2489
+ backdrop: true,
2490
+ closeOnBackdrop: true,
2491
+ closeOnEscape: true,
2492
+ showCloseButton: true
2493
+ },
2494
+ propFields: [
2495
+ {
2496
+ name: "modalId",
2497
+ label: "Drawer Target ID",
2498
+ type: "string",
2499
+ defaultValue: "mobile-drawer",
2500
+ description: "Unique identifier targeted by open_modal and close_modal actions."
2501
+ },
2502
+ {
2503
+ name: "placement",
2504
+ label: "Placement",
2505
+ type: "select",
2506
+ defaultValue: "right",
2507
+ options: [
2508
+ { label: "Slide from Right", value: "right" },
2509
+ { label: "Slide from Left", value: "left" },
2510
+ { label: "Slide from Top (Dropdown)", value: "top" },
2511
+ { label: "Slide from Bottom", value: "bottom" }
2512
+ ]
2513
+ },
2514
+ {
2515
+ name: "title",
2516
+ label: "Drawer Title",
2517
+ type: "string",
2518
+ defaultValue: "Navigation Menu",
2519
+ description: "Header title text displayed at the top of the drawer."
2520
+ },
2521
+ {
2522
+ name: "backdrop",
2523
+ label: "Show Backdrop",
2524
+ type: "boolean",
2525
+ defaultValue: true
2526
+ },
2527
+ {
2528
+ name: "closeOnBackdrop",
2529
+ label: "Close on Backdrop Click",
2530
+ type: "boolean",
2531
+ defaultValue: true
2532
+ },
2533
+ {
2534
+ name: "closeOnEscape",
2535
+ label: "Close on Escape Key",
2536
+ type: "boolean",
2537
+ defaultValue: true
2538
+ },
2539
+ {
2540
+ name: "showCloseButton",
2541
+ label: "Show Close Button",
2542
+ type: "boolean",
2543
+ defaultValue: true
2544
+ }
2545
+ ],
2546
+ traits: [
2547
+ idTrait(),
2548
+ titleTrait(),
2549
+ ariaLabelTrait({ description: "Accessible name for the off-canvas drawer." })
2550
+ ],
2551
+ defaultStyles: {
2552
+ base: {
2553
+ backgroundColor: "#ffffff",
2554
+ boxShadow: "-4px 0 24px rgba(0, 0, 0, 0.15)",
2555
+ padding: "24px",
2556
+ width: "320px",
2557
+ maxWidth: "100%"
2558
+ },
2559
+ mobile: {
2560
+ width: "100%"
2561
+ }
2562
+ }
2563
+ };
2564
+
2565
+ // src/definitions/interactive/collapsible.ts
2566
+ var collapsibleDefinition = {
2567
+ type: "collapsible",
2568
+ label: "Collapsible",
2569
+ category: "interactive",
2570
+ icon: "chevron-down",
2571
+ description: "In-flow expandable container that toggles visibility without a fullscreen overlay.",
2572
+ acceptsChildren: true,
2573
+ allowedChildren: ["*"],
2574
+ defaultProps: {
2575
+ modalId: "collapsible-content",
2576
+ defaultOpen: false,
2577
+ animated: true
2578
+ },
2579
+ propFields: [
2580
+ {
2581
+ name: "modalId",
2582
+ label: "Target ID",
2583
+ type: "string",
2584
+ defaultValue: "collapsible-content",
2585
+ description: 'Identifier targeted by Open Modal (with "Toggle" enabled) or Close Modal actions.'
2586
+ },
2587
+ {
2588
+ name: "defaultOpen",
2589
+ label: "Default Open",
2590
+ type: "boolean",
2591
+ defaultValue: false,
2592
+ description: "Whether the collapsible container starts expanded on initial render."
2593
+ },
2594
+ {
2595
+ name: "animated",
2596
+ label: "Smooth Transition",
2597
+ type: "boolean",
2598
+ defaultValue: true
2599
+ }
2600
+ ],
2601
+ traits: [
2602
+ idTrait(),
2603
+ ariaLabelTrait({ description: "Accessible name for the collapsible container." })
2604
+ ],
2605
+ defaultStyles: {
2606
+ base: {
2607
+ width: "100%",
2608
+ overflow: "hidden"
2609
+ }
2610
+ }
2611
+ };
2612
+
2613
+ // src/definitions/index.ts
2614
+ var coreComponentDefinitions = [
2615
+ pageDefinition,
2616
+ sectionDefinition,
2617
+ containerDefinition,
2618
+ columnsDefinition,
2619
+ flexDefinition,
2620
+ gridDefinition,
2621
+ headingDefinition,
2622
+ textDefinition,
2623
+ paragraphDefinition,
2624
+ linkDefinition,
2625
+ blockquoteDefinition,
2626
+ badgeDefinition,
2627
+ codeBlockDefinition,
2628
+ imageDefinition,
2629
+ videoDefinition,
2630
+ iconDefinition,
2631
+ htmlEmbedDefinition,
2632
+ buttonDefinition,
2633
+ buttonSubmitDefinition,
2634
+ formDefinition,
2635
+ inputDefinition,
2636
+ textareaDefinition,
2637
+ selectDefinition,
2638
+ checkboxDefinition,
2639
+ switchDefinition,
2640
+ radioGroupDefinition,
2641
+ radioDefinition,
2642
+ radioItemDefinition,
2643
+ fileUploadDefinition,
2644
+ collectionDefinition,
2645
+ listDefinition,
2646
+ listItemDefinition,
2647
+ tableDefinition,
2648
+ tableRowDefinition,
2649
+ tableCellDefinition,
2650
+ modalDefinition,
2651
+ drawerDefinition,
2652
+ collapsibleDefinition
2653
+ ];
2654
+ function createDefaultComponentRegistry() {
2655
+ const registry = new ComponentRegistry();
2656
+ for (const def of coreComponentDefinitions) {
2657
+ registry.register(def);
2658
+ }
2659
+ return registry;
2660
+ }
2661
+
2662
+ export {
2663
+ ComponentRegistry,
2664
+ LAYOUT_PARENTS,
2665
+ CONTENT_CHILD_TYPES,
2666
+ pageDefinition,
2667
+ sectionDefinition,
2668
+ containerDefinition,
2669
+ columnsDefinition,
2670
+ flexDefinition,
2671
+ gridDefinition,
2672
+ headingDefinition,
2673
+ textDefinition,
2674
+ paragraphDefinition,
2675
+ linkDefinition,
2676
+ blockquoteDefinition,
2677
+ badgeDefinition,
2678
+ codeBlockDefinition,
2679
+ imageDefinition,
2680
+ videoDefinition,
2681
+ iconDefinition,
2682
+ htmlEmbedDefinition,
2683
+ tableDefinition,
2684
+ tableRowDefinition,
2685
+ tableCellDefinition,
2686
+ listDefinition,
2687
+ listItemDefinition,
2688
+ collectionDefinition,
2689
+ buttonDefinition,
2690
+ buttonSubmitDefinition,
2691
+ formDefinition,
2692
+ inputDefinition,
2693
+ textareaDefinition,
2694
+ selectDefinition,
2695
+ checkboxDefinition,
2696
+ switchDefinition,
2697
+ radioGroupDefinition,
2698
+ radioDefinition,
2699
+ radioItemDefinition,
2700
+ fileUploadDefinition,
2701
+ modalDefinition,
2702
+ drawerDefinition,
2703
+ collapsibleDefinition,
2704
+ coreComponentDefinitions,
2705
+ createDefaultComponentRegistry
2706
+ };
2707
+ //# sourceMappingURL=chunk-K6I6U7F3.js.map