@kubuild/components 0.1.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 (135) hide show
  1. package/README.md +110 -0
  2. package/dist/blocks/forms.d.ts +6 -0
  3. package/dist/blocks/forms.d.ts.map +1 -0
  4. package/dist/blocks/index.cjs +1661 -0
  5. package/dist/blocks/index.cjs.map +1 -0
  6. package/dist/blocks/index.d.ts +11 -0
  7. package/dist/blocks/index.d.ts.map +1 -0
  8. package/dist/blocks/index.js +15 -0
  9. package/dist/blocks/index.js.map +1 -0
  10. package/dist/blocks/layout.d.ts +6 -0
  11. package/dist/blocks/layout.d.ts.map +1 -0
  12. package/dist/blocks/sections.d.ts +6 -0
  13. package/dist/blocks/sections.d.ts.map +1 -0
  14. package/dist/{blocks.d.ts → blocks/types.d.ts} +2 -5
  15. package/dist/blocks/types.d.ts.map +1 -0
  16. package/dist/chunk-JTQ35OQQ.js +1631 -0
  17. package/dist/chunk-JTQ35OQQ.js.map +1 -0
  18. package/dist/chunk-K6I6U7F3.js +2707 -0
  19. package/dist/chunk-K6I6U7F3.js.map +1 -0
  20. package/dist/chunk-OK53DS7G.js +911 -0
  21. package/dist/chunk-OK53DS7G.js.map +1 -0
  22. package/dist/definitions/constants.d.ts +10 -0
  23. package/dist/definitions/constants.d.ts.map +1 -0
  24. package/dist/definitions/data/collection.d.ts +3 -0
  25. package/dist/definitions/data/collection.d.ts.map +1 -0
  26. package/dist/definitions/data/index.d.ts +4 -0
  27. package/dist/definitions/data/index.d.ts.map +1 -0
  28. package/dist/definitions/data/list.d.ts +4 -0
  29. package/dist/definitions/data/list.d.ts.map +1 -0
  30. package/dist/definitions/data/table.d.ts +5 -0
  31. package/dist/definitions/data/table.d.ts.map +1 -0
  32. package/dist/definitions/form/button.d.ts +4 -0
  33. package/dist/definitions/form/button.d.ts.map +1 -0
  34. package/dist/definitions/form/checkbox.d.ts +3 -0
  35. package/dist/definitions/form/checkbox.d.ts.map +1 -0
  36. package/dist/definitions/form/file-upload.d.ts +3 -0
  37. package/dist/definitions/form/file-upload.d.ts.map +1 -0
  38. package/dist/definitions/form/form.d.ts +3 -0
  39. package/dist/definitions/form/form.d.ts.map +1 -0
  40. package/dist/definitions/form/index.d.ts +10 -0
  41. package/dist/definitions/form/index.d.ts.map +1 -0
  42. package/dist/definitions/form/input.d.ts +3 -0
  43. package/dist/definitions/form/input.d.ts.map +1 -0
  44. package/dist/definitions/form/radio.d.ts +5 -0
  45. package/dist/definitions/form/radio.d.ts.map +1 -0
  46. package/dist/definitions/form/select.d.ts +3 -0
  47. package/dist/definitions/form/select.d.ts.map +1 -0
  48. package/dist/definitions/form/switch.d.ts +3 -0
  49. package/dist/definitions/form/switch.d.ts.map +1 -0
  50. package/dist/definitions/form/textarea.d.ts +3 -0
  51. package/dist/definitions/form/textarea.d.ts.map +1 -0
  52. package/dist/definitions/index.cjs +3512 -0
  53. package/dist/definitions/index.cjs.map +1 -0
  54. package/dist/definitions/index.d.ts +12 -0
  55. package/dist/definitions/index.d.ts.map +1 -0
  56. package/dist/definitions/index.js +90 -0
  57. package/dist/definitions/index.js.map +1 -0
  58. package/dist/definitions/interactive/collapsible.d.ts +3 -0
  59. package/dist/definitions/interactive/collapsible.d.ts.map +1 -0
  60. package/dist/definitions/interactive/drawer.d.ts +3 -0
  61. package/dist/definitions/interactive/drawer.d.ts.map +1 -0
  62. package/dist/definitions/interactive/index.d.ts +4 -0
  63. package/dist/definitions/interactive/index.d.ts.map +1 -0
  64. package/dist/definitions/interactive/modal.d.ts +3 -0
  65. package/dist/definitions/interactive/modal.d.ts.map +1 -0
  66. package/dist/definitions/layout/columns.d.ts +3 -0
  67. package/dist/definitions/layout/columns.d.ts.map +1 -0
  68. package/dist/definitions/layout/container.d.ts +3 -0
  69. package/dist/definitions/layout/container.d.ts.map +1 -0
  70. package/dist/definitions/layout/flex.d.ts +7 -0
  71. package/dist/definitions/layout/flex.d.ts.map +1 -0
  72. package/dist/definitions/layout/grid.d.ts +7 -0
  73. package/dist/definitions/layout/grid.d.ts.map +1 -0
  74. package/dist/definitions/layout/index.d.ts +7 -0
  75. package/dist/definitions/layout/index.d.ts.map +1 -0
  76. package/dist/definitions/layout/page.d.ts +3 -0
  77. package/dist/definitions/layout/page.d.ts.map +1 -0
  78. package/dist/definitions/layout/section.d.ts +3 -0
  79. package/dist/definitions/layout/section.d.ts.map +1 -0
  80. package/dist/definitions/media/html-embed.d.ts +3 -0
  81. package/dist/definitions/media/html-embed.d.ts.map +1 -0
  82. package/dist/definitions/media/icon.d.ts +3 -0
  83. package/dist/definitions/media/icon.d.ts.map +1 -0
  84. package/dist/definitions/media/image.d.ts +3 -0
  85. package/dist/definitions/media/image.d.ts.map +1 -0
  86. package/dist/definitions/media/index.d.ts +5 -0
  87. package/dist/definitions/media/index.d.ts.map +1 -0
  88. package/dist/definitions/media/video.d.ts +3 -0
  89. package/dist/definitions/media/video.d.ts.map +1 -0
  90. package/dist/definitions/types.d.ts +5 -0
  91. package/dist/definitions/types.d.ts.map +1 -0
  92. package/dist/definitions/typography/badge.d.ts +3 -0
  93. package/dist/definitions/typography/badge.d.ts.map +1 -0
  94. package/dist/definitions/typography/blockquote.d.ts +3 -0
  95. package/dist/definitions/typography/blockquote.d.ts.map +1 -0
  96. package/dist/definitions/typography/code-block.d.ts +3 -0
  97. package/dist/definitions/typography/code-block.d.ts.map +1 -0
  98. package/dist/definitions/typography/heading.d.ts +3 -0
  99. package/dist/definitions/typography/heading.d.ts.map +1 -0
  100. package/dist/definitions/typography/index.d.ts +8 -0
  101. package/dist/definitions/typography/index.d.ts.map +1 -0
  102. package/dist/definitions/typography/link.d.ts +3 -0
  103. package/dist/definitions/typography/link.d.ts.map +1 -0
  104. package/dist/definitions/typography/paragraph.d.ts +3 -0
  105. package/dist/definitions/typography/paragraph.d.ts.map +1 -0
  106. package/dist/definitions/typography/text.d.ts +3 -0
  107. package/dist/definitions/typography/text.d.ts.map +1 -0
  108. package/dist/index.cjs +3114 -708
  109. package/dist/index.cjs.map +1 -1
  110. package/dist/index.js +151 -2741
  111. package/dist/index.js.map +1 -1
  112. package/dist/traits/common.d.ts +8 -0
  113. package/dist/traits/common.d.ts.map +1 -0
  114. package/dist/traits/form.d.ts +80 -0
  115. package/dist/traits/form.d.ts.map +1 -0
  116. package/dist/traits/index.cjs +998 -0
  117. package/dist/traits/index.cjs.map +1 -0
  118. package/dist/traits/index.d.ts +7 -0
  119. package/dist/traits/index.d.ts.map +1 -0
  120. package/dist/traits/index.js +129 -0
  121. package/dist/traits/index.js.map +1 -0
  122. package/dist/traits/link.d.ts +8 -0
  123. package/dist/traits/link.d.ts.map +1 -0
  124. package/dist/traits/media.d.ts +18 -0
  125. package/dist/traits/media.d.ts.map +1 -0
  126. package/dist/traits/structure.d.ts +10 -0
  127. package/dist/traits/structure.d.ts.map +1 -0
  128. package/dist/traits/types.d.ts +69 -0
  129. package/dist/traits/types.d.ts.map +1 -0
  130. package/package.json +20 -4
  131. package/dist/blocks.d.ts.map +0 -1
  132. package/dist/definitions.d.ts +0 -32
  133. package/dist/definitions.d.ts.map +0 -1
  134. package/dist/traits.d.ts +0 -137
  135. package/dist/traits.d.ts.map +0 -1
package/dist/index.cjs CHANGED
@@ -18,25 +18,35 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
20
  // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ CONTENT_CHILD_TYPES: () => CONTENT_CHILD_TYPES,
23
24
  ComponentRegistry: () => ComponentRegistry,
25
+ FORM_STARTER_BLOCKS: () => FORM_STARTER_BLOCKS,
26
+ LAYOUT_PARENTS: () => LAYOUT_PARENTS,
27
+ LAYOUT_STARTER_BLOCKS: () => LAYOUT_STARTER_BLOCKS,
24
28
  STARTER_BLOCKS: () => STARTER_BLOCKS,
25
29
  TRAIT_GROUP_LABELS: () => TRAIT_GROUP_LABELS,
26
30
  TRAIT_GROUP_ORDER: () => TRAIT_GROUP_ORDER,
31
+ UI_STARTER_BLOCKS: () => UI_STARTER_BLOCKS,
32
+ acceptTrait: () => acceptTrait,
27
33
  actionTrait: () => actionTrait,
28
34
  altTrait: () => altTrait,
29
35
  ariaLabelTrait: () => ariaLabelTrait,
30
36
  autoCompleteTrait: () => autoCompleteTrait,
37
+ autoDisableOnSubmitTrait: () => autoDisableOnSubmitTrait,
38
+ autoGrowTrait: () => autoGrowTrait,
31
39
  autoplayTrait: () => autoplayTrait,
32
40
  badgeDefinition: () => badgeDefinition,
33
41
  blockquoteDefinition: () => blockquoteDefinition,
34
42
  buttonDefinition: () => buttonDefinition,
43
+ buttonSubmitDefinition: () => buttonSubmitDefinition,
35
44
  buttonTypeTrait: () => buttonTypeTrait,
36
45
  checkboxDefinition: () => checkboxDefinition,
37
46
  citeTrait: () => citeTrait,
38
47
  codeBlockDefinition: () => codeBlockDefinition,
39
48
  colSpanTrait: () => colSpanTrait,
49
+ collapsibleDefinition: () => collapsibleDefinition,
40
50
  collectTraitNames: () => collectTraitNames,
41
51
  collectionDefinition: () => collectionDefinition,
42
52
  columnsDefinition: () => columnsDefinition,
@@ -45,42 +55,73 @@ __export(index_exports, {
45
55
  coreComponentDefinitions: () => coreComponentDefinitions,
46
56
  createDefaultComponentRegistry: () => createDefaultComponentRegistry,
47
57
  defaultCheckedTrait: () => defaultCheckedTrait,
58
+ defaultGenId: () => defaultGenId,
59
+ defaultSelectedTrait: () => defaultSelectedTrait,
48
60
  defaultValueTrait: () => defaultValueTrait,
49
61
  disabledTrait: () => disabledTrait,
62
+ drawerDefinition: () => drawerDefinition,
50
63
  extractComponentRequirements: () => extractComponentRequirements,
51
64
  fieldNameTrait: () => fieldNameTrait,
65
+ fileUploadDefinition: () => fileUploadDefinition,
66
+ flexDefinition: () => flexDefinition,
52
67
  formDefinition: () => formDefinition,
68
+ gridDefinition: () => gridDefinition,
53
69
  headingDefinition: () => headingDefinition,
70
+ helperTextTrait: () => helperTextTrait,
54
71
  hrefTrait: () => hrefTrait,
55
72
  htmlEmbedDefinition: () => htmlEmbedDefinition,
56
73
  iconDefinition: () => iconDefinition,
57
74
  idTrait: () => idTrait,
58
75
  imageDefinition: () => imageDefinition,
76
+ indeterminateTrait: () => indeterminateTrait,
59
77
  inputDefinition: () => inputDefinition,
60
78
  inputTypeTrait: () => inputTypeTrait,
61
79
  isBindableField: () => isBindableField,
80
+ labelTextTrait: () => labelTextTrait,
62
81
  linkDefinition: () => linkDefinition,
63
82
  listDefinition: () => listDefinition,
64
83
  listItemDefinition: () => listItemDefinition,
84
+ loadingTextTrait: () => loadingTextTrait,
65
85
  loadingTrait: () => loadingTrait,
66
86
  loopTrait: () => loopTrait,
87
+ maxCharCountTrait: () => maxCharCountTrait,
88
+ maxFileSizeTrait: () => maxFileSizeTrait,
89
+ maxLengthTrait: () => maxLengthTrait,
67
90
  methodTrait: () => methodTrait,
91
+ minLengthTrait: () => minLengthTrait,
92
+ modalDefinition: () => modalDefinition,
93
+ multipleTrait: () => multipleTrait,
68
94
  mutedTrait: () => mutedTrait,
95
+ optionsListTrait: () => optionsListTrait,
96
+ orientationTrait: () => orientationTrait,
69
97
  pageDefinition: () => pageDefinition,
70
98
  paragraphDefinition: () => paragraphDefinition,
99
+ patternTrait: () => patternTrait,
71
100
  placeholderTrait: () => placeholderTrait,
72
101
  posterTrait: () => posterTrait,
102
+ prefixIconTrait: () => prefixIconTrait,
103
+ preventDefaultTrait: () => preventDefaultTrait,
73
104
  primitiveTypeForField: () => primitiveTypeForField,
74
105
  radioDefinition: () => radioDefinition,
106
+ radioGroupDefinition: () => radioGroupDefinition,
107
+ radioItemDefinition: () => radioItemDefinition,
75
108
  readOnlyTrait: () => readOnlyTrait,
76
109
  relTrait: () => relTrait,
77
110
  requiredTrait: () => requiredTrait,
111
+ resetOnSubmitTrait: () => resetOnSubmitTrait,
112
+ resizeTrait: () => resizeTrait,
78
113
  rowSpanTrait: () => rowSpanTrait,
79
114
  rowsTrait: () => rowsTrait,
115
+ scrollToFirstErrorTrait: () => scrollToFirstErrorTrait,
80
116
  sectionDefinition: () => sectionDefinition,
81
117
  selectDefinition: () => selectDefinition,
118
+ showPreviewTrait: () => showPreviewTrait,
119
+ showSpinnerTrait: () => showSpinnerTrait,
82
120
  sortTraits: () => sortTraits,
83
121
  srcTrait: () => srcTrait,
122
+ suffixIconTrait: () => suffixIconTrait,
123
+ switchDefinition: () => switchDefinition,
124
+ switchSizeTrait: () => switchSizeTrait,
84
125
  tableCellDefinition: () => tableCellDefinition,
85
126
  tableDefinition: () => tableDefinition,
86
127
  tableRowDefinition: () => tableRowDefinition,
@@ -90,9 +131,10 @@ __export(index_exports, {
90
131
  textareaDefinition: () => textareaDefinition,
91
132
  titleTrait: () => titleTrait,
92
133
  valueTrait: () => valueTrait,
93
- videoDefinition: () => videoDefinition
134
+ videoDefinition: () => videoDefinition,
135
+ withOverrides: () => withOverrides
94
136
  });
95
- module.exports = __toCommonJS(index_exports);
137
+ module.exports = __toCommonJS(src_exports);
96
138
 
97
139
  // src/registry.ts
98
140
  var ComponentRegistry = class {
@@ -185,10 +227,7 @@ var ComponentRegistry = class {
185
227
  }
186
228
  };
187
229
 
188
- // src/definitions.ts
189
- var import_schema = require("@kubuild/schema");
190
-
191
- // src/traits.ts
230
+ // src/traits/types.ts
192
231
  var TRAIT_GROUP_ORDER = [
193
232
  "identity",
194
233
  "link",
@@ -210,64 +249,34 @@ var TRAIT_GROUP_LABELS = {
210
249
  function withOverrides(base, overrides) {
211
250
  return overrides ? { ...base, ...overrides } : base;
212
251
  }
213
- function hrefTrait(overrides) {
214
- return withOverrides(
215
- {
216
- name: "href",
217
- label: "Link URL",
218
- type: "string",
219
- defaultValue: "#",
220
- attribute: "href",
221
- group: "link",
222
- description: "The destination URL the element navigates to when activated."
223
- },
224
- overrides
225
- );
226
- }
227
- function targetTrait(overrides) {
228
- return withOverrides(
229
- {
230
- name: "target",
231
- label: "Open In",
232
- type: "select",
233
- defaultValue: "_self",
234
- attribute: "target",
235
- group: "link",
236
- options: [
237
- { label: "Same tab (_self)", value: "_self" },
238
- { label: "New tab (_blank)", value: "_blank" },
239
- { label: "Parent frame (_parent)", value: "_parent" },
240
- { label: "Top frame (_top)", value: "_top" }
241
- ],
242
- description: "Where the linked resource should open."
243
- },
244
- overrides
245
- );
252
+ function sortTraits(traits) {
253
+ const groupRank = (group) => {
254
+ if (!group) return Number.MAX_SAFE_INTEGER;
255
+ const idx = TRAIT_GROUP_ORDER.indexOf(group);
256
+ return idx === -1 ? Number.MAX_SAFE_INTEGER : idx;
257
+ };
258
+ return [...traits].sort((a, b) => groupRank(a.group) - groupRank(b.group));
246
259
  }
247
- function relTrait(overrides) {
248
- return withOverrides(
249
- {
250
- name: "rel",
251
- label: "Relationship (rel)",
252
- type: "string",
253
- defaultValue: "",
254
- attribute: "rel",
255
- group: "link",
256
- description: 'Space-separated relationship tokens (e.g. "noopener noreferrer").'
257
- },
258
- overrides
259
- );
260
+ function collectTraitNames(traitsList) {
261
+ const names = /* @__PURE__ */ new Set();
262
+ for (const traits of traitsList) {
263
+ for (const trait of traits) {
264
+ names.add(trait.name);
265
+ }
266
+ }
267
+ return Array.from(names);
260
268
  }
261
- function altTrait(overrides) {
269
+
270
+ // src/traits/common.ts
271
+ function idTrait(overrides) {
262
272
  return withOverrides(
263
273
  {
264
- name: "alt",
265
- label: "Alt Text",
274
+ name: "id",
275
+ label: "Element ID",
266
276
  type: "string",
267
- attribute: "alt",
268
- group: "accessibility",
269
- required: true,
270
- description: "Alternative text describing the media for screen readers and fallback."
277
+ attribute: "id",
278
+ group: "identity",
279
+ description: "A custom, document-unique identifier used for anchors, CSS, and scripting."
271
280
  },
272
281
  overrides
273
282
  );
@@ -285,19 +294,6 @@ function titleTrait(overrides) {
285
294
  overrides
286
295
  );
287
296
  }
288
- function placeholderTrait(overrides) {
289
- return withOverrides(
290
- {
291
- name: "placeholder",
292
- label: "Placeholder",
293
- type: "string",
294
- attribute: "placeholder",
295
- group: "form",
296
- description: "Hint text shown inside the control when it is empty."
297
- },
298
- overrides
299
- );
300
- }
301
297
  function ariaLabelTrait(overrides) {
302
298
  return withOverrides(
303
299
  {
@@ -311,75 +307,58 @@ function ariaLabelTrait(overrides) {
311
307
  overrides
312
308
  );
313
309
  }
314
- function idTrait(overrides) {
315
- return withOverrides(
316
- {
317
- name: "id",
318
- label: "Element ID",
319
- type: "string",
320
- attribute: "id",
321
- group: "identity",
322
- description: "A custom, document-unique identifier used for anchors, CSS, and scripting."
323
- },
324
- overrides
325
- );
326
- }
327
- function fieldNameTrait(overrides) {
310
+
311
+ // src/traits/link.ts
312
+ function hrefTrait(overrides) {
328
313
  return withOverrides(
329
314
  {
330
- name: "name",
331
- label: "Field Name",
315
+ name: "href",
316
+ label: "Link URL",
332
317
  type: "string",
333
- attribute: "name",
334
- group: "form",
335
- required: true,
336
- description: "The name submitted with the form data for this field."
337
- },
338
- overrides
339
- );
340
- }
341
- function requiredTrait(overrides) {
342
- return withOverrides(
343
- {
344
- name: "required",
345
- label: "Required",
346
- type: "boolean",
347
- defaultValue: false,
348
- attribute: "required",
349
- group: "form",
350
- description: "Whether the field must be filled before the form can be submitted."
318
+ defaultValue: "#",
319
+ attribute: "href",
320
+ group: "link",
321
+ description: "The destination URL the element navigates to when activated."
351
322
  },
352
323
  overrides
353
324
  );
354
325
  }
355
- function disabledTrait(overrides) {
326
+ function targetTrait(overrides) {
356
327
  return withOverrides(
357
328
  {
358
- name: "disabled",
359
- label: "Disabled",
360
- type: "boolean",
361
- defaultValue: false,
362
- attribute: "disabled",
363
- group: "behavior",
364
- description: "Disables the control so it cannot be focused or activated."
329
+ name: "target",
330
+ label: "Open In",
331
+ type: "select",
332
+ defaultValue: "_self",
333
+ attribute: "target",
334
+ group: "link",
335
+ options: [
336
+ { label: "Same tab (_self)", value: "_self" },
337
+ { label: "New tab (_blank)", value: "_blank" },
338
+ { label: "Parent frame (_parent)", value: "_parent" },
339
+ { label: "Top frame (_top)", value: "_top" }
340
+ ],
341
+ description: "Where the linked resource should open."
365
342
  },
366
343
  overrides
367
344
  );
368
345
  }
369
- function readOnlyTrait(overrides) {
346
+ function relTrait(overrides) {
370
347
  return withOverrides(
371
348
  {
372
- name: "readOnly",
373
- label: "Read Only",
374
- type: "boolean",
375
- defaultValue: false,
376
- attribute: "readonly",
377
- group: "behavior",
378
- description: "Prevents the user from modifying the control value."
349
+ name: "rel",
350
+ label: "Relationship (rel)",
351
+ type: "string",
352
+ defaultValue: "",
353
+ attribute: "rel",
354
+ group: "link",
355
+ description: 'Space-separated relationship tokens (e.g. "noopener noreferrer").'
379
356
  },
380
357
  overrides
381
358
  );
382
359
  }
360
+
361
+ // src/traits/media.ts
383
362
  function srcTrait(overrides) {
384
363
  return withOverrides(
385
364
  {
@@ -394,6 +373,20 @@ function srcTrait(overrides) {
394
373
  overrides
395
374
  );
396
375
  }
376
+ function altTrait(overrides) {
377
+ return withOverrides(
378
+ {
379
+ name: "alt",
380
+ label: "Alt Text",
381
+ type: "string",
382
+ attribute: "alt",
383
+ group: "accessibility",
384
+ required: true,
385
+ description: "Alternative text describing the media for screen readers and fallback."
386
+ },
387
+ overrides
388
+ );
389
+ }
397
390
  function posterTrait(overrides) {
398
391
  return withOverrides(
399
392
  {
@@ -463,19 +456,6 @@ function mutedTrait(overrides) {
463
456
  overrides
464
457
  );
465
458
  }
466
- function citeTrait(overrides) {
467
- return withOverrides(
468
- {
469
- name: "cite",
470
- label: "Citation URL (cite)",
471
- type: "string",
472
- attribute: "cite",
473
- group: "semantic",
474
- description: "The URL of the source document the quote is taken from."
475
- },
476
- overrides
477
- );
478
- }
479
459
  function loadingTrait(overrides) {
480
460
  return withOverrides(
481
461
  {
@@ -494,61 +474,188 @@ function loadingTrait(overrides) {
494
474
  overrides
495
475
  );
496
476
  }
497
- function actionTrait(overrides) {
477
+
478
+ // src/traits/structure.ts
479
+ function citeTrait(overrides) {
498
480
  return withOverrides(
499
481
  {
500
- name: "action",
501
- label: "Action URL",
482
+ name: "cite",
483
+ label: "Citation URL (cite)",
502
484
  type: "string",
503
- attribute: "action",
504
- group: "form",
505
- description: "The URL the form data is submitted to."
485
+ attribute: "cite",
486
+ group: "semantic",
487
+ description: "The URL of the source document the quote is taken from."
506
488
  },
507
489
  overrides
508
490
  );
509
491
  }
510
- function methodTrait(overrides) {
492
+ function colSpanTrait(overrides) {
511
493
  return withOverrides(
512
494
  {
513
- name: "method",
514
- label: "Method",
515
- type: "select",
516
- defaultValue: "POST",
517
- attribute: "method",
518
- group: "form",
519
- options: [
520
- { label: "POST", value: "POST" },
521
- { label: "GET", value: "GET" }
522
- ],
523
- description: "The HTTP method used to submit the form."
495
+ name: "colSpan",
496
+ label: "Column Span (colSpan)",
497
+ type: "number",
498
+ defaultValue: 1,
499
+ attribute: "colspan",
500
+ group: "semantic",
501
+ description: "The number of columns the cell spans."
524
502
  },
525
503
  overrides
526
504
  );
527
505
  }
528
- function autoCompleteTrait(overrides) {
506
+ function rowSpanTrait(overrides) {
529
507
  return withOverrides(
530
508
  {
531
- name: "autoComplete",
532
- label: "Auto Complete",
533
- type: "select",
534
- defaultValue: "on",
535
- attribute: "autocomplete",
536
- group: "form",
537
- options: [
538
- { label: "On", value: "on" },
539
- { label: "Off", value: "off" }
540
- ],
541
- description: "Whether the browser may autofill values for this form."
509
+ name: "rowSpan",
510
+ label: "Row Span (rowSpan)",
511
+ type: "number",
512
+ defaultValue: 1,
513
+ attribute: "rowspan",
514
+ group: "semantic",
515
+ description: "The number of rows the cell spans."
542
516
  },
543
517
  overrides
544
518
  );
545
519
  }
546
- function valueTrait(overrides) {
520
+ function tagTrait(overrides) {
547
521
  return withOverrides(
548
522
  {
549
- name: "value",
550
- label: "Value",
551
- type: "string",
523
+ name: "tag",
524
+ label: "HTML Tag",
525
+ type: "select",
526
+ attribute: "tag",
527
+ group: "semantic",
528
+ description: "The semantic HTML tag the component renders as."
529
+ },
530
+ overrides
531
+ );
532
+ }
533
+
534
+ // src/traits/form.ts
535
+ function placeholderTrait(overrides) {
536
+ return withOverrides(
537
+ {
538
+ name: "placeholder",
539
+ label: "Placeholder",
540
+ type: "string",
541
+ attribute: "placeholder",
542
+ group: "form",
543
+ description: "Hint text shown inside the control when it is empty."
544
+ },
545
+ overrides
546
+ );
547
+ }
548
+ function fieldNameTrait(overrides) {
549
+ return withOverrides(
550
+ {
551
+ name: "name",
552
+ label: "Field Name",
553
+ type: "string",
554
+ attribute: "name",
555
+ group: "form",
556
+ required: true,
557
+ description: "The name submitted with the form data for this field."
558
+ },
559
+ overrides
560
+ );
561
+ }
562
+ function requiredTrait(overrides) {
563
+ return withOverrides(
564
+ {
565
+ name: "required",
566
+ label: "Required",
567
+ type: "boolean",
568
+ defaultValue: false,
569
+ attribute: "required",
570
+ group: "form",
571
+ description: "Whether the field must be filled before the form can be submitted."
572
+ },
573
+ overrides
574
+ );
575
+ }
576
+ function disabledTrait(overrides) {
577
+ return withOverrides(
578
+ {
579
+ name: "disabled",
580
+ label: "Disabled",
581
+ type: "boolean",
582
+ defaultValue: false,
583
+ attribute: "disabled",
584
+ group: "behavior",
585
+ description: "Disables the control so it cannot be focused or activated."
586
+ },
587
+ overrides
588
+ );
589
+ }
590
+ function readOnlyTrait(overrides) {
591
+ return withOverrides(
592
+ {
593
+ name: "readOnly",
594
+ label: "Read Only",
595
+ type: "boolean",
596
+ defaultValue: false,
597
+ attribute: "readonly",
598
+ group: "behavior",
599
+ description: "Prevents the user from modifying the control value."
600
+ },
601
+ overrides
602
+ );
603
+ }
604
+ function actionTrait(overrides) {
605
+ return withOverrides(
606
+ {
607
+ name: "action",
608
+ label: "Action URL",
609
+ type: "string",
610
+ attribute: "action",
611
+ group: "form",
612
+ description: "The URL the form data is submitted to."
613
+ },
614
+ overrides
615
+ );
616
+ }
617
+ function methodTrait(overrides) {
618
+ return withOverrides(
619
+ {
620
+ name: "method",
621
+ label: "Method",
622
+ type: "select",
623
+ defaultValue: "POST",
624
+ attribute: "method",
625
+ group: "form",
626
+ options: [
627
+ { label: "POST", value: "POST" },
628
+ { label: "GET", value: "GET" }
629
+ ],
630
+ description: "The HTTP method used to submit the form."
631
+ },
632
+ overrides
633
+ );
634
+ }
635
+ function autoCompleteTrait(overrides) {
636
+ return withOverrides(
637
+ {
638
+ name: "autoComplete",
639
+ label: "Auto Complete",
640
+ type: "select",
641
+ defaultValue: "on",
642
+ attribute: "autocomplete",
643
+ group: "form",
644
+ options: [
645
+ { label: "On", value: "on" },
646
+ { label: "Off", value: "off" }
647
+ ],
648
+ description: "Whether the browser may autofill values for this form."
649
+ },
650
+ overrides
651
+ );
652
+ }
653
+ function valueTrait(overrides) {
654
+ return withOverrides(
655
+ {
656
+ name: "value",
657
+ label: "Value",
658
+ type: "string",
552
659
  attribute: "value",
553
660
  group: "form",
554
661
  description: "The value submitted with the form data when the control is selected."
@@ -597,100 +704,377 @@ function rowsTrait(overrides) {
597
704
  overrides
598
705
  );
599
706
  }
600
- function colSpanTrait(overrides) {
707
+ function inputTypeTrait(overrides) {
601
708
  return withOverrides(
602
709
  {
603
- name: "colSpan",
604
- label: "Column Span (colSpan)",
710
+ name: "type",
711
+ label: "Input Type",
712
+ type: "select",
713
+ defaultValue: "text",
714
+ attribute: "type",
715
+ group: "form",
716
+ description: "The semantic input type of the control."
717
+ },
718
+ overrides
719
+ );
720
+ }
721
+ function buttonTypeTrait(overrides) {
722
+ return withOverrides(
723
+ {
724
+ name: "buttonType",
725
+ label: "Button Type",
726
+ type: "select",
727
+ defaultValue: "button",
728
+ attribute: "type",
729
+ group: "form",
730
+ options: [
731
+ { label: "Button", value: "button" },
732
+ { label: "Submit Form (submit)", value: "submit" },
733
+ { label: "Reset Form (reset)", value: "reset" }
734
+ ],
735
+ description: "The button\u2019s behavior inside a form."
736
+ },
737
+ overrides
738
+ );
739
+ }
740
+ function preventDefaultTrait(overrides) {
741
+ return withOverrides(
742
+ {
743
+ name: "preventDefault",
744
+ label: "Prevent Default",
745
+ type: "boolean",
746
+ defaultValue: true,
747
+ group: "form",
748
+ description: "Intercept the native browser submit and handle it via the KUBUILD action pipeline instead."
749
+ },
750
+ overrides
751
+ );
752
+ }
753
+ function scrollToFirstErrorTrait(overrides) {
754
+ return withOverrides(
755
+ {
756
+ name: "scrollToFirstError",
757
+ label: "Scroll to First Error",
758
+ type: "boolean",
759
+ defaultValue: true,
760
+ group: "form",
761
+ description: "Automatically scroll to and focus the first invalid field when submission fails validation."
762
+ },
763
+ overrides
764
+ );
765
+ }
766
+ function resetOnSubmitTrait(overrides) {
767
+ return withOverrides(
768
+ {
769
+ name: "resetOnSubmit",
770
+ label: "Reset on Submit",
771
+ type: "boolean",
772
+ defaultValue: false,
773
+ group: "form",
774
+ description: "Reset all fields to their initial values after a successful form submission."
775
+ },
776
+ overrides
777
+ );
778
+ }
779
+ function patternTrait(overrides) {
780
+ return withOverrides(
781
+ {
782
+ name: "pattern",
783
+ label: "Pattern (regex)",
784
+ type: "string",
785
+ attribute: "pattern",
786
+ group: "form",
787
+ description: "A regular expression the input value must match to pass validation."
788
+ },
789
+ overrides
790
+ );
791
+ }
792
+ function minLengthTrait(overrides) {
793
+ return withOverrides(
794
+ {
795
+ name: "minLength",
796
+ label: "Min Length",
605
797
  type: "number",
606
- defaultValue: 1,
607
- attribute: "colspan",
608
- group: "semantic",
609
- description: "The number of columns the cell spans."
798
+ attribute: "minlength",
799
+ group: "form",
800
+ description: "The minimum number of characters the user must enter."
610
801
  },
611
802
  overrides
612
803
  );
613
804
  }
614
- function rowSpanTrait(overrides) {
805
+ function maxLengthTrait(overrides) {
615
806
  return withOverrides(
616
807
  {
617
- name: "rowSpan",
618
- label: "Row Span (rowSpan)",
808
+ name: "maxLength",
809
+ label: "Max Length",
619
810
  type: "number",
620
- defaultValue: 1,
621
- attribute: "rowspan",
622
- group: "semantic",
623
- description: "The number of rows the cell spans."
811
+ attribute: "maxlength",
812
+ group: "form",
813
+ description: "The maximum number of characters the user is allowed to enter."
624
814
  },
625
815
  overrides
626
816
  );
627
817
  }
628
- function tagTrait(overrides) {
818
+ function prefixIconTrait(overrides) {
629
819
  return withOverrides(
630
820
  {
631
- name: "tag",
632
- label: "HTML Tag",
633
- type: "select",
634
- attribute: "tag",
635
- group: "semantic",
636
- description: "The semantic HTML tag the component renders as."
821
+ name: "prefixIcon",
822
+ label: "Prefix Icon",
823
+ type: "string",
824
+ group: "form",
825
+ description: 'Lucide icon name displayed before the input value (e.g. "mail", "search").'
637
826
  },
638
827
  overrides
639
828
  );
640
829
  }
641
- function inputTypeTrait(overrides) {
830
+ function suffixIconTrait(overrides) {
642
831
  return withOverrides(
643
832
  {
644
- name: "type",
645
- label: "Input Type",
646
- type: "select",
647
- defaultValue: "text",
648
- attribute: "type",
833
+ name: "suffixIcon",
834
+ label: "Suffix Icon",
835
+ type: "string",
649
836
  group: "form",
650
- description: "The semantic input type of the control."
837
+ description: 'Lucide icon name displayed after the input value (e.g. "eye", "check").'
651
838
  },
652
839
  overrides
653
840
  );
654
841
  }
655
- function buttonTypeTrait(overrides) {
842
+ function helperTextTrait(overrides) {
656
843
  return withOverrides(
657
844
  {
658
- name: "buttonType",
659
- label: "Button Type",
845
+ name: "helperText",
846
+ label: "Helper Text",
847
+ type: "string",
848
+ group: "form",
849
+ description: 'A short message displayed below the input to guide the user (e.g. "Must be at least 8 characters").'
850
+ },
851
+ overrides
852
+ );
853
+ }
854
+ function resizeTrait(overrides) {
855
+ return withOverrides(
856
+ {
857
+ name: "resize",
858
+ label: "Resize",
660
859
  type: "select",
661
- defaultValue: "button",
662
- attribute: "type",
860
+ defaultValue: "vertical",
663
861
  group: "form",
664
862
  options: [
665
- { label: "Button", value: "button" },
666
- { label: "Submit Form (submit)", value: "submit" },
667
- { label: "Reset Form (reset)", value: "reset" }
863
+ { label: "Vertical only", value: "vertical" },
864
+ { label: "Horizontal only", value: "horizontal" },
865
+ { label: "Both", value: "both" },
866
+ { label: "None", value: "none" }
668
867
  ],
669
- description: "The button\u2019s behavior inside a form."
868
+ description: "Controls whether and how the user can resize the textarea."
670
869
  },
671
870
  overrides
672
871
  );
673
872
  }
674
- function sortTraits(traits) {
675
- const groupRank = (group) => {
676
- if (!group) return Number.MAX_SAFE_INTEGER;
677
- const idx = TRAIT_GROUP_ORDER.indexOf(group);
678
- return idx === -1 ? Number.MAX_SAFE_INTEGER : idx;
679
- };
680
- return [...traits].sort((a, b) => groupRank(a.group) - groupRank(b.group));
873
+ function autoGrowTrait(overrides) {
874
+ return withOverrides(
875
+ {
876
+ name: "autoGrow",
877
+ label: "Auto Grow",
878
+ type: "boolean",
879
+ defaultValue: false,
880
+ group: "form",
881
+ description: "Automatically expand the textarea height to fit the content without scrolling."
882
+ },
883
+ overrides
884
+ );
681
885
  }
682
- function collectTraitNames(traitsList) {
683
- const names = /* @__PURE__ */ new Set();
684
- for (const traits of traitsList) {
685
- for (const trait of traits) {
686
- names.add(trait.name);
687
- }
688
- }
689
- return Array.from(names);
886
+ function maxCharCountTrait(overrides) {
887
+ return withOverrides(
888
+ {
889
+ name: "maxCharCount",
890
+ label: "Max Character Count",
891
+ type: "number",
892
+ group: "form",
893
+ description: 'Maximum character limit displayed as a counter below the textarea (e.g. "120 / 500").'
894
+ },
895
+ overrides
896
+ );
897
+ }
898
+ function optionsListTrait(overrides) {
899
+ return withOverrides(
900
+ {
901
+ name: "options",
902
+ label: "Options",
903
+ type: "string",
904
+ group: "form",
905
+ description: "The list of dropdown options, each with a label and value. Editable via the inspector trait panel."
906
+ },
907
+ overrides
908
+ );
909
+ }
910
+ function labelTextTrait(overrides) {
911
+ return withOverrides(
912
+ {
913
+ name: "label",
914
+ label: "Label Text",
915
+ type: "string",
916
+ group: "form",
917
+ description: "The visible text label displayed alongside the control."
918
+ },
919
+ overrides
920
+ );
921
+ }
922
+ function indeterminateTrait(overrides) {
923
+ return withOverrides(
924
+ {
925
+ name: "indeterminate",
926
+ label: "Indeterminate",
927
+ type: "boolean",
928
+ defaultValue: false,
929
+ group: "form",
930
+ description: "Renders the checkbox in a mixed/indeterminate visual state (neither checked nor unchecked)."
931
+ },
932
+ overrides
933
+ );
934
+ }
935
+ function switchSizeTrait(overrides) {
936
+ return withOverrides(
937
+ {
938
+ name: "switchSize",
939
+ label: "Size",
940
+ type: "select",
941
+ defaultValue: "md",
942
+ group: "form",
943
+ options: [
944
+ { label: "Small", value: "sm" },
945
+ { label: "Medium", value: "md" },
946
+ { label: "Large", value: "lg" }
947
+ ],
948
+ description: "The visual size of the switch toggle."
949
+ },
950
+ overrides
951
+ );
952
+ }
953
+ function orientationTrait(overrides) {
954
+ return withOverrides(
955
+ {
956
+ name: "orientation",
957
+ label: "Orientation",
958
+ type: "select",
959
+ defaultValue: "vertical",
960
+ group: "form",
961
+ options: [
962
+ { label: "Vertical", value: "vertical" },
963
+ { label: "Horizontal", value: "horizontal" }
964
+ ],
965
+ description: "The layout direction of the child controls (vertical stack or horizontal row)."
966
+ },
967
+ overrides
968
+ );
969
+ }
970
+ function defaultSelectedTrait(overrides) {
971
+ return withOverrides(
972
+ {
973
+ name: "defaultSelected",
974
+ label: "Default Selected",
975
+ type: "string",
976
+ group: "form",
977
+ description: "The value of the radio item that is selected by default."
978
+ },
979
+ overrides
980
+ );
981
+ }
982
+ function acceptTrait(overrides) {
983
+ return withOverrides(
984
+ {
985
+ name: "accept",
986
+ label: "Accepted File Types",
987
+ type: "string",
988
+ attribute: "accept",
989
+ defaultValue: "*/*",
990
+ group: "form",
991
+ description: 'Comma-separated list of MIME types or file extensions accepted (e.g. "image/*,.pdf,.docx").'
992
+ },
993
+ overrides
994
+ );
995
+ }
996
+ function maxFileSizeTrait(overrides) {
997
+ return withOverrides(
998
+ {
999
+ name: "maxFileSize",
1000
+ label: "Max File Size (MB)",
1001
+ type: "number",
1002
+ defaultValue: 10,
1003
+ group: "form",
1004
+ description: "The maximum allowable file size in megabytes (MB)."
1005
+ },
1006
+ overrides
1007
+ );
1008
+ }
1009
+ function multipleTrait(overrides) {
1010
+ return withOverrides(
1011
+ {
1012
+ name: "multiple",
1013
+ label: "Allow Multiple Files",
1014
+ type: "boolean",
1015
+ attribute: "multiple",
1016
+ defaultValue: false,
1017
+ group: "form",
1018
+ description: "Allow multiple files to be selected and uploaded at once."
1019
+ },
1020
+ overrides
1021
+ );
1022
+ }
1023
+ function showPreviewTrait(overrides) {
1024
+ return withOverrides(
1025
+ {
1026
+ name: "showPreview",
1027
+ label: "Show Preview",
1028
+ type: "boolean",
1029
+ defaultValue: true,
1030
+ group: "form",
1031
+ description: "Display an interactive preview (image thumbnail or file list with badges) for selected files."
1032
+ },
1033
+ overrides
1034
+ );
1035
+ }
1036
+ function loadingTextTrait(overrides) {
1037
+ return withOverrides(
1038
+ {
1039
+ name: "loadingText",
1040
+ label: "Loading Text",
1041
+ type: "string",
1042
+ defaultValue: "Submitting...",
1043
+ group: "behavior",
1044
+ description: "Text displayed on the button while the form submission is in progress."
1045
+ },
1046
+ overrides
1047
+ );
1048
+ }
1049
+ function showSpinnerTrait(overrides) {
1050
+ return withOverrides(
1051
+ {
1052
+ name: "showSpinner",
1053
+ label: "Show Loading Spinner",
1054
+ type: "boolean",
1055
+ defaultValue: true,
1056
+ group: "behavior",
1057
+ description: "Automatically show an animated loading spinner icon while form is submitting."
1058
+ },
1059
+ overrides
1060
+ );
1061
+ }
1062
+ function autoDisableOnSubmitTrait(overrides) {
1063
+ return withOverrides(
1064
+ {
1065
+ name: "autoDisableOnSubmit",
1066
+ label: "Auto Disable on Submit",
1067
+ type: "boolean",
1068
+ defaultValue: true,
1069
+ group: "behavior",
1070
+ description: "Automatically disable the button to prevent duplicate submissions while the form is submitting."
1071
+ },
1072
+ overrides
1073
+ );
690
1074
  }
691
1075
 
692
- // src/definitions.ts
693
- var LAYOUT_PARENTS = ["page", "section", "container", "columns"];
1076
+ // src/definitions/constants.ts
1077
+ var LAYOUT_PARENTS = ["page", "section", "container", "columns", "flex", "grid", "modal", "drawer", "collapsible"];
694
1078
  var CONTENT_CHILD_TYPES = [
695
1079
  "heading",
696
1080
  "text",
@@ -704,17 +1088,27 @@ var CONTENT_CHILD_TYPES = [
704
1088
  "icon",
705
1089
  "html-embed",
706
1090
  "button",
1091
+ "button-submit",
707
1092
  "form",
708
1093
  "input",
709
1094
  "textarea",
710
1095
  "select",
711
1096
  "checkbox",
1097
+ "switch",
1098
+ "radio-group",
712
1099
  "radio",
1100
+ "radio-item",
1101
+ "file-upload",
713
1102
  "list",
714
1103
  "table",
715
1104
  "collection",
716
- "custom"
1105
+ "custom",
1106
+ "modal",
1107
+ "drawer",
1108
+ "collapsible"
717
1109
  ];
1110
+
1111
+ // src/definitions/layout/page.ts
718
1112
  var pageDefinition = {
719
1113
  type: "page",
720
1114
  label: "Page",
@@ -730,13 +1124,15 @@ var pageDefinition = {
730
1124
  ],
731
1125
  defaultStyles: { base: { minHeight: "100vh", backgroundColor: "#ffffff" } }
732
1126
  };
1127
+
1128
+ // src/definitions/layout/section.ts
733
1129
  var sectionDefinition = {
734
1130
  type: "section",
735
1131
  label: "Section",
736
1132
  category: "layout",
737
1133
  icon: "rows",
738
1134
  acceptsChildren: true,
739
- allowedChildren: ["container", "columns", ...CONTENT_CHILD_TYPES],
1135
+ allowedChildren: ["container", "columns", "flex", "grid", ...CONTENT_CHILD_TYPES],
740
1136
  defaultProps: {},
741
1137
  traits: [
742
1138
  idTrait(),
@@ -761,13 +1157,15 @@ var sectionDefinition = {
761
1157
  }
762
1158
  }
763
1159
  };
1160
+
1161
+ // src/definitions/layout/container.ts
764
1162
  var containerDefinition = {
765
1163
  type: "container",
766
1164
  label: "Container",
767
1165
  category: "layout",
768
1166
  icon: "box",
769
1167
  acceptsChildren: true,
770
- allowedChildren: ["columns", ...CONTENT_CHILD_TYPES],
1168
+ allowedChildren: ["columns", "flex", "grid", ...CONTENT_CHILD_TYPES],
771
1169
  defaultProps: { maxWidth: "1200px" },
772
1170
  traits: [
773
1171
  idTrait()
@@ -788,13 +1186,15 @@ var containerDefinition = {
788
1186
  }
789
1187
  }
790
1188
  };
1189
+
1190
+ // src/definitions/layout/columns.ts
791
1191
  var columnsDefinition = {
792
1192
  type: "columns",
793
1193
  label: "Columns",
794
1194
  category: "layout",
795
1195
  icon: "columns",
796
1196
  acceptsChildren: true,
797
- allowedChildren: ["container", ...CONTENT_CHILD_TYPES],
1197
+ allowedChildren: ["container", "flex", "grid", ...CONTENT_CHILD_TYPES],
798
1198
  defaultProps: { columns: 2, gap: "16px" },
799
1199
  traits: [
800
1200
  idTrait()
@@ -815,6 +1215,66 @@ var columnsDefinition = {
815
1215
  }
816
1216
  }
817
1217
  };
1218
+
1219
+ // src/definitions/layout/flex.ts
1220
+ var flexDefinition = {
1221
+ type: "flex",
1222
+ label: "Flex",
1223
+ category: "layout",
1224
+ icon: "flex",
1225
+ acceptsChildren: true,
1226
+ allowedChildren: ["*"],
1227
+ disallowedParents: ["page"],
1228
+ defaultProps: {},
1229
+ traits: [
1230
+ idTrait(),
1231
+ ariaLabelTrait({ description: "Accessible name for the flex container." })
1232
+ ],
1233
+ defaultStyles: {
1234
+ base: {
1235
+ display: "flex",
1236
+ flexDirection: "column",
1237
+ gap: "16px"
1238
+ }
1239
+ }
1240
+ };
1241
+
1242
+ // src/definitions/layout/grid.ts
1243
+ var gridDefinition = {
1244
+ type: "grid",
1245
+ label: "Grid",
1246
+ category: "layout",
1247
+ icon: "grid",
1248
+ acceptsChildren: true,
1249
+ allowedChildren: ["*"],
1250
+ disallowedParents: ["page"],
1251
+ defaultProps: {
1252
+ columns: 3,
1253
+ gap: "16px"
1254
+ },
1255
+ traits: [
1256
+ idTrait(),
1257
+ ariaLabelTrait({ description: "Accessible name for the grid container." })
1258
+ ],
1259
+ defaultStyles: {
1260
+ base: {
1261
+ display: "grid",
1262
+ gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
1263
+ gap: "16px"
1264
+ },
1265
+ tablet: {
1266
+ gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
1267
+ gap: "16px"
1268
+ },
1269
+ mobile: {
1270
+ gridTemplateColumns: "repeat(1, minmax(0, 1fr))",
1271
+ gap: "16px"
1272
+ }
1273
+ }
1274
+ };
1275
+
1276
+ // src/definitions/typography/heading.ts
1277
+ var import_schema = require("@kubuild/schema");
818
1278
  var headingDefinition = {
819
1279
  type: "heading",
820
1280
  label: "Heading",
@@ -856,6 +1316,9 @@ var headingDefinition = {
856
1316
  }
857
1317
  }
858
1318
  };
1319
+
1320
+ // src/definitions/typography/text.ts
1321
+ var import_schema2 = require("@kubuild/schema");
859
1322
  var textDefinition = {
860
1323
  type: "text",
861
1324
  label: "Text",
@@ -872,7 +1335,7 @@ var textDefinition = {
872
1335
  ariaLabelTrait()
873
1336
  ],
874
1337
  validateProps: (props) => {
875
- if (!(0, import_schema.isVariableBinding)(props.content) && (typeof props.content !== "string" || props.content.trim().length === 0)) {
1338
+ if (!(0, import_schema2.isVariableBinding)(props.content) && (typeof props.content !== "string" || props.content.trim().length === 0)) {
876
1339
  return ['Text requires a non-empty "content".'];
877
1340
  }
878
1341
  return true;
@@ -885,332 +1348,62 @@ var textDefinition = {
885
1348
  }
886
1349
  }
887
1350
  };
888
- var imageDefinition = {
889
- type: "image",
890
- label: "Image",
891
- category: "media",
892
- icon: "image",
1351
+
1352
+ // src/definitions/typography/paragraph.ts
1353
+ var import_schema3 = require("@kubuild/schema");
1354
+ var paragraphDefinition = {
1355
+ type: "paragraph",
1356
+ label: "Paragraph",
1357
+ category: "typography",
1358
+ icon: "paragraph",
893
1359
  acceptsChildren: false,
894
- capabilities: ["assetProvider"],
895
1360
  defaultProps: {
896
- src: "https://images.unsplash.com/photo-1579546929518-9e396f3cc809?w=800&auto=format&fit=crop&q=80",
897
- alt: "Default image",
898
- width: 600,
899
- height: 400
1361
+ text: "A paragraph of text with clean semantic typography."
900
1362
  },
901
1363
  propFields: [
902
- { name: "src", label: "Image URL", type: "string" },
903
- { name: "asset", label: "Asset Reference", type: "json" },
904
- { name: "alt", label: "Alt Text", type: "string", defaultValue: "Default image" },
905
- { name: "width", label: "Width", type: "number" },
906
- { name: "height", label: "Height", type: "number" }
1364
+ {
1365
+ name: "text",
1366
+ label: "Text",
1367
+ type: "string",
1368
+ defaultValue: "A paragraph of text with clean semantic typography."
1369
+ }
907
1370
  ],
908
1371
  traits: [
909
- srcTrait(),
910
- altTrait({ defaultValue: "Default image" }),
911
- loadingTrait(),
912
1372
  idTrait(),
913
1373
  titleTrait(),
914
- ariaLabelTrait({ description: "Override the alt text for assistive technology (rarely needed)." })
1374
+ ariaLabelTrait()
915
1375
  ],
916
1376
  validateProps: (props) => {
917
1377
  const errors = [];
918
- const hasSrc = typeof props.src === "string" && props.src.trim().length > 0 || (0, import_schema.isVariableBinding)(props.src);
919
- const hasAsset = (0, import_schema.isAssetReference)(props.asset);
920
- if (!hasSrc && !hasAsset) {
921
- errors.push('Image requires either a non-empty "src" URL or a valid "asset" reference.');
922
- }
923
- const hasAlt = typeof props.alt === "string" && props.alt.trim().length > 0 || (0, import_schema.isVariableBinding)(props.alt);
924
- if (!hasAlt) {
925
- errors.push('Image requires non-empty "alt" text.');
1378
+ const textVal = props.text ?? props.content;
1379
+ if (textVal !== void 0 && !(0, import_schema3.isVariableBinding)(textVal) && (typeof textVal !== "string" || textVal.trim().length === 0)) {
1380
+ errors.push('Paragraph requires a non-empty "text".');
926
1381
  }
927
1382
  return errors.length > 0 ? errors : true;
928
1383
  },
929
1384
  defaultStyles: {
930
1385
  base: {
931
- maxWidth: "100%",
932
- height: "auto",
933
- borderRadius: "8px"
1386
+ fontSize: "16px",
1387
+ color: "#4b5563",
1388
+ lineHeight: "1.6",
1389
+ margin: "0 0 16px 0"
934
1390
  }
935
1391
  }
936
1392
  };
937
- var buttonDefinition = {
938
- type: "button",
939
- label: "Button",
940
- category: "interactive",
941
- icon: "mouse-pointer",
1393
+
1394
+ // src/definitions/typography/link.ts
1395
+ var import_schema4 = require("@kubuild/schema");
1396
+ var linkDefinition = {
1397
+ type: "link",
1398
+ label: "Link",
1399
+ category: "typography",
1400
+ icon: "link",
942
1401
  acceptsChildren: false,
943
- capabilities: ["actionRegistry"],
944
1402
  defaultProps: {
945
- label: "Click Me",
946
- variant: "primary"
947
- },
948
- propFields: [
949
- { name: "label", label: "Label", type: "string", defaultValue: "Click Me" },
950
- { name: "href", label: "Link URL", type: "string" },
951
- { name: "action", label: "Action", type: "action" },
952
- { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
953
- {
954
- name: "buttonType",
955
- label: "Button Type",
956
- type: "select",
957
- defaultValue: "button",
958
- options: [
959
- { label: "Button", value: "button" },
960
- { label: "Submit Form (submit)", value: "submit" },
961
- { label: "Reset Form (reset)", value: "reset" }
962
- ]
963
- },
964
- {
965
- name: "variant",
966
- label: "Variant",
967
- type: "select",
968
- defaultValue: "primary",
969
- options: [
970
- { label: "Primary", value: "primary" },
971
- { label: "Secondary", value: "secondary" }
972
- ]
973
- }
974
- ],
975
- traits: [
976
- buttonTypeTrait(),
977
- disabledTrait(),
978
- hrefTrait({ description: "Optional URL \u2014 when set, the button renders as an anchor styled like a button." }),
979
- targetTrait({ description: "Where to open the href URL (only used when href is set)." }),
980
- relTrait({ description: "Relationship tokens (only used when href is set)." }),
981
- idTrait(),
982
- titleTrait(),
983
- ariaLabelTrait()
984
- ],
985
- validateProps: (props) => {
986
- const errors = [];
987
- const hasLabel = typeof props.label === "string" && props.label.trim().length > 0 || (0, import_schema.isVariableBinding)(props.label);
988
- if (!hasLabel) {
989
- errors.push('Button requires a non-empty "label".');
990
- }
991
- if (props.href !== void 0 && typeof props.href !== "string" && !(0, import_schema.isVariableBinding)(props.href)) {
992
- errors.push('Button "href" must be a string when provided.');
993
- }
994
- if (props.buttonType !== void 0 && !(0, import_schema.isVariableBinding)(props.buttonType)) {
995
- if (!["button", "submit", "reset"].includes(props.buttonType)) {
996
- errors.push('Button "buttonType" must be one of: "button", "submit", "reset".');
997
- }
998
- }
999
- if (props.action !== void 0 && !(0, import_schema.isActionBinding)(props.action)) {
1000
- errors.push('Button "action" must be a valid action binding when provided.');
1001
- }
1002
- if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema.isVariableBinding)(props.disabled)) {
1003
- errors.push('Button "disabled" must be a boolean when provided.');
1004
- }
1005
- return errors.length > 0 ? errors : true;
1006
- },
1007
- defaultStyles: {
1008
- base: {
1009
- backgroundColor: "#2563eb",
1010
- color: "#ffffff",
1011
- paddingTop: "10px",
1012
- paddingBottom: "10px",
1013
- paddingLeft: "20px",
1014
- paddingRight: "20px",
1015
- borderRadius: "6px",
1016
- fontWeight: "500",
1017
- fontSize: "15px",
1018
- border: "none",
1019
- cursor: "pointer"
1020
- }
1021
- }
1022
- };
1023
- var collectionDefinition = {
1024
- type: "collection",
1025
- label: "Collection",
1026
- category: "data",
1027
- icon: "database",
1028
- acceptsChildren: true,
1029
- defaultProps: {
1030
- sourceKey: "items",
1031
- itemAlias: "item"
1032
- },
1033
- propFields: [
1034
- { name: "sourceKey", label: "Source Variable", type: "string", defaultValue: "items" },
1035
- { name: "itemAlias", label: "Item Alias", type: "string", defaultValue: "item" }
1036
- ],
1037
- traits: [
1038
- idTrait(),
1039
- ariaLabelTrait({ description: 'Accessible name summarizing the repeated collection (e.g. "Product list").' })
1040
- ]
1041
- };
1042
- var listDefinition = {
1043
- type: "list",
1044
- label: "List",
1045
- category: "typography",
1046
- icon: "list",
1047
- acceptsChildren: true,
1048
- allowedChildren: ["list-item"],
1049
- defaultProps: {
1050
- tag: "ul",
1051
- listStyleType: "disc"
1052
- },
1053
- defaultChildren: [
1054
- { type: "list-item", props: { text: "List item 1" } },
1055
- { type: "list-item", props: { text: "List item 2" } },
1056
- { type: "list-item", props: { text: "List item 3" } }
1057
- ],
1058
- propFields: [
1059
- {
1060
- name: "tag",
1061
- label: "Tag",
1062
- type: "select",
1063
- defaultValue: "ul",
1064
- options: [
1065
- { label: "Unordered (ul)", value: "ul" },
1066
- { label: "Ordered (ol)", value: "ol" }
1067
- ]
1068
- },
1069
- {
1070
- name: "listStyleType",
1071
- label: "List Style Type",
1072
- type: "select",
1073
- defaultValue: "disc",
1074
- options: [
1075
- { label: "Disc", value: "disc" },
1076
- { label: "Circle", value: "circle" },
1077
- { label: "Square", value: "square" },
1078
- { label: "Decimal", value: "decimal" },
1079
- { label: "None", value: "none" },
1080
- { label: "Custom Icon", value: "custom-icon" }
1081
- ]
1082
- }
1083
- ],
1084
- traits: [
1085
- idTrait(),
1086
- ariaLabelTrait({ description: 'Accessible name for the list (e.g. "Navigation menu", "Features").' })
1087
- ],
1088
- validateProps: (props) => {
1089
- const errors = [];
1090
- if (props.tag !== void 0 && !(0, import_schema.isVariableBinding)(props.tag)) {
1091
- if (props.tag !== "ul" && props.tag !== "ol") {
1092
- errors.push('List "tag" must be either "ul" or "ol".');
1093
- }
1094
- }
1095
- if (props.listStyleType !== void 0 && !(0, import_schema.isVariableBinding)(props.listStyleType)) {
1096
- const allowed = ["disc", "circle", "square", "decimal", "none", "custom-icon"];
1097
- if (typeof props.listStyleType !== "string" || !allowed.includes(props.listStyleType)) {
1098
- errors.push(`List "listStyleType" must be one of: ${allowed.join(", ")}.`);
1099
- }
1100
- }
1101
- return errors.length > 0 ? errors : true;
1102
- },
1103
- defaultStyles: {
1104
- base: {
1105
- margin: "0 0 16px 0",
1106
- paddingLeft: "24px"
1107
- }
1108
- }
1109
- };
1110
- var listItemDefinition = {
1111
- type: "list-item",
1112
- label: "List Item",
1113
- category: "typography",
1114
- icon: "list-item",
1115
- acceptsChildren: true,
1116
- allowedChildren: [
1117
- "heading",
1118
- "text",
1119
- "paragraph",
1120
- "link",
1121
- "blockquote",
1122
- "badge",
1123
- "code-block",
1124
- "image",
1125
- "video",
1126
- "icon",
1127
- "html-embed",
1128
- "button",
1129
- "list",
1130
- "custom"
1131
- ],
1132
- defaultProps: {
1133
- text: "List item"
1134
- },
1135
- propFields: [
1136
- {
1137
- name: "text",
1138
- label: "Text",
1139
- type: "string",
1140
- defaultValue: "List item"
1141
- }
1142
- ],
1143
- traits: [
1144
- idTrait(),
1145
- titleTrait(),
1146
- ariaLabelTrait()
1147
- ],
1148
- validateProps: (props) => {
1149
- const errors = [];
1150
- if (props.text !== void 0 && typeof props.text !== "string" && !(0, import_schema.isVariableBinding)(props.text)) {
1151
- errors.push('List Item "text" must be a string when provided.');
1152
- }
1153
- return errors.length > 0 ? errors : true;
1154
- },
1155
- defaultStyles: {
1156
- base: {
1157
- margin: "4px 0",
1158
- fontSize: "16px",
1159
- color: "#374151",
1160
- lineHeight: "1.5"
1161
- }
1162
- }
1163
- };
1164
- var paragraphDefinition = {
1165
- type: "paragraph",
1166
- label: "Paragraph",
1167
- category: "typography",
1168
- icon: "paragraph",
1169
- acceptsChildren: false,
1170
- defaultProps: {
1171
- text: "A paragraph of text with clean semantic typography."
1172
- },
1173
- propFields: [
1174
- {
1175
- name: "text",
1176
- label: "Text",
1177
- type: "string",
1178
- defaultValue: "A paragraph of text with clean semantic typography."
1179
- }
1180
- ],
1181
- traits: [
1182
- idTrait(),
1183
- titleTrait(),
1184
- ariaLabelTrait()
1185
- ],
1186
- validateProps: (props) => {
1187
- const errors = [];
1188
- const textVal = props.text ?? props.content;
1189
- if (textVal !== void 0 && !(0, import_schema.isVariableBinding)(textVal) && (typeof textVal !== "string" || textVal.trim().length === 0)) {
1190
- errors.push('Paragraph requires a non-empty "text".');
1191
- }
1192
- return errors.length > 0 ? errors : true;
1193
- },
1194
- defaultStyles: {
1195
- base: {
1196
- fontSize: "16px",
1197
- color: "#4b5563",
1198
- lineHeight: "1.6",
1199
- margin: "0 0 16px 0"
1200
- }
1201
- }
1202
- };
1203
- var linkDefinition = {
1204
- type: "link",
1205
- label: "Link",
1206
- category: "typography",
1207
- icon: "link",
1208
- acceptsChildren: false,
1209
- defaultProps: {
1210
- text: "Click here",
1211
- href: "#",
1212
- target: "_self",
1213
- rel: ""
1403
+ text: "Click here",
1404
+ href: "#",
1405
+ target: "_self",
1406
+ rel: ""
1214
1407
  },
1215
1408
  propFields: [
1216
1409
  { name: "text", label: "Link Text", type: "string", defaultValue: "Click here" },
@@ -1239,19 +1432,19 @@ var linkDefinition = {
1239
1432
  ],
1240
1433
  validateProps: (props) => {
1241
1434
  const errors = [];
1242
- if (props.text !== void 0 && !(0, import_schema.isVariableBinding)(props.text) && (typeof props.text !== "string" || props.text.trim().length === 0)) {
1435
+ if (props.text !== void 0 && !(0, import_schema4.isVariableBinding)(props.text) && (typeof props.text !== "string" || props.text.trim().length === 0)) {
1243
1436
  errors.push('Link requires a non-empty "text".');
1244
1437
  }
1245
- if (props.href !== void 0 && typeof props.href !== "string" && !(0, import_schema.isVariableBinding)(props.href)) {
1438
+ if (props.href !== void 0 && typeof props.href !== "string" && !(0, import_schema4.isVariableBinding)(props.href)) {
1246
1439
  errors.push('Link "href" must be a string when provided.');
1247
1440
  }
1248
- if (props.target !== void 0 && !(0, import_schema.isVariableBinding)(props.target)) {
1441
+ if (props.target !== void 0 && !(0, import_schema4.isVariableBinding)(props.target)) {
1249
1442
  const allowedTargets = ["_self", "_blank", "_parent", "_top"];
1250
1443
  if (typeof props.target !== "string" || !allowedTargets.includes(props.target)) {
1251
1444
  errors.push(`Link "target" must be one of: ${allowedTargets.join(", ")}.`);
1252
1445
  }
1253
1446
  }
1254
- if (props.rel !== void 0 && typeof props.rel !== "string" && !(0, import_schema.isVariableBinding)(props.rel)) {
1447
+ if (props.rel !== void 0 && typeof props.rel !== "string" && !(0, import_schema4.isVariableBinding)(props.rel)) {
1255
1448
  errors.push('Link "rel" must be a string when provided.');
1256
1449
  }
1257
1450
  return errors.length > 0 ? errors : true;
@@ -1264,6 +1457,9 @@ var linkDefinition = {
1264
1457
  }
1265
1458
  }
1266
1459
  };
1460
+
1461
+ // src/definitions/typography/blockquote.ts
1462
+ var import_schema5 = require("@kubuild/schema");
1267
1463
  var blockquoteDefinition = {
1268
1464
  type: "blockquote",
1269
1465
  label: "Blockquote",
@@ -1303,10 +1499,10 @@ var blockquoteDefinition = {
1303
1499
  ],
1304
1500
  validateProps: (props) => {
1305
1501
  const errors = [];
1306
- if (props.text !== void 0 && typeof props.text !== "string" && !(0, import_schema.isVariableBinding)(props.text)) {
1502
+ if (props.text !== void 0 && typeof props.text !== "string" && !(0, import_schema5.isVariableBinding)(props.text)) {
1307
1503
  errors.push('Blockquote "text" must be a string when provided.');
1308
1504
  }
1309
- if (props.cite !== void 0 && typeof props.cite !== "string" && !(0, import_schema.isVariableBinding)(props.cite)) {
1505
+ if (props.cite !== void 0 && typeof props.cite !== "string" && !(0, import_schema5.isVariableBinding)(props.cite)) {
1310
1506
  errors.push('Blockquote "cite" must be a string when provided.');
1311
1507
  }
1312
1508
  return errors.length > 0 ? errors : true;
@@ -1327,6 +1523,9 @@ var blockquoteDefinition = {
1327
1523
  }
1328
1524
  }
1329
1525
  };
1526
+
1527
+ // src/definitions/typography/badge.ts
1528
+ var import_schema6 = require("@kubuild/schema");
1330
1529
  var badgeDefinition = {
1331
1530
  type: "badge",
1332
1531
  label: "Badge",
@@ -1360,10 +1559,10 @@ var badgeDefinition = {
1360
1559
  ],
1361
1560
  validateProps: (props) => {
1362
1561
  const errors = [];
1363
- if (props.text !== void 0 && !(0, import_schema.isVariableBinding)(props.text) && (typeof props.text !== "string" || props.text.trim().length === 0)) {
1562
+ if (props.text !== void 0 && !(0, import_schema6.isVariableBinding)(props.text) && (typeof props.text !== "string" || props.text.trim().length === 0)) {
1364
1563
  errors.push('Badge requires a non-empty "text".');
1365
1564
  }
1366
- if (props.variant !== void 0 && typeof props.variant !== "string" && !(0, import_schema.isVariableBinding)(props.variant)) {
1565
+ if (props.variant !== void 0 && typeof props.variant !== "string" && !(0, import_schema6.isVariableBinding)(props.variant)) {
1367
1566
  errors.push('Badge "variant" must be a string.');
1368
1567
  }
1369
1568
  return errors.length > 0 ? errors : true;
@@ -1385,6 +1584,9 @@ var badgeDefinition = {
1385
1584
  }
1386
1585
  }
1387
1586
  };
1587
+
1588
+ // src/definitions/typography/code-block.ts
1589
+ var import_schema7 = require("@kubuild/schema");
1388
1590
  var codeBlockDefinition = {
1389
1591
  type: "code-block",
1390
1592
  label: "Code Block",
@@ -1416,10 +1618,10 @@ var codeBlockDefinition = {
1416
1618
  ],
1417
1619
  validateProps: (props) => {
1418
1620
  const errors = [];
1419
- if (props.code !== void 0 && typeof props.code !== "string" && !(0, import_schema.isVariableBinding)(props.code)) {
1621
+ if (props.code !== void 0 && typeof props.code !== "string" && !(0, import_schema7.isVariableBinding)(props.code)) {
1420
1622
  errors.push('Code Block "code" must be a string when provided.');
1421
1623
  }
1422
- if (props.language !== void 0 && typeof props.language !== "string" && !(0, import_schema.isVariableBinding)(props.language)) {
1624
+ if (props.language !== void 0 && typeof props.language !== "string" && !(0, import_schema7.isVariableBinding)(props.language)) {
1423
1625
  errors.push('Code Block "language" must be a string when provided.');
1424
1626
  }
1425
1627
  return errors.length > 0 ? errors : true;
@@ -1439,6 +1641,61 @@ var codeBlockDefinition = {
1439
1641
  }
1440
1642
  }
1441
1643
  };
1644
+
1645
+ // src/definitions/media/image.ts
1646
+ var import_schema8 = require("@kubuild/schema");
1647
+ var imageDefinition = {
1648
+ type: "image",
1649
+ label: "Image",
1650
+ category: "media",
1651
+ icon: "image",
1652
+ acceptsChildren: false,
1653
+ capabilities: ["assetProvider"],
1654
+ defaultProps: {
1655
+ src: "https://images.unsplash.com/photo-1579546929518-9e396f3cc809?w=800&auto=format&fit=crop&q=80",
1656
+ alt: "Default image",
1657
+ width: 600,
1658
+ height: 400
1659
+ },
1660
+ propFields: [
1661
+ { name: "src", label: "Image URL", type: "string" },
1662
+ { name: "asset", label: "Asset Reference", type: "json" },
1663
+ { name: "alt", label: "Alt Text", type: "string", defaultValue: "Default image" },
1664
+ { name: "width", label: "Width", type: "number" },
1665
+ { name: "height", label: "Height", type: "number" }
1666
+ ],
1667
+ traits: [
1668
+ srcTrait(),
1669
+ altTrait({ defaultValue: "Default image" }),
1670
+ loadingTrait(),
1671
+ idTrait(),
1672
+ titleTrait(),
1673
+ ariaLabelTrait({ description: "Override the alt text for assistive technology (rarely needed)." })
1674
+ ],
1675
+ validateProps: (props) => {
1676
+ const errors = [];
1677
+ const hasSrc = typeof props.src === "string" && props.src.trim().length > 0 || (0, import_schema8.isVariableBinding)(props.src);
1678
+ const hasAsset = (0, import_schema8.isAssetReference)(props.asset);
1679
+ if (!hasSrc && !hasAsset) {
1680
+ errors.push('Image requires either a non-empty "src" URL or a valid "asset" reference.');
1681
+ }
1682
+ const hasAlt = typeof props.alt === "string" && props.alt.trim().length > 0 || (0, import_schema8.isVariableBinding)(props.alt);
1683
+ if (!hasAlt) {
1684
+ errors.push('Image requires non-empty "alt" text.');
1685
+ }
1686
+ return errors.length > 0 ? errors : true;
1687
+ },
1688
+ defaultStyles: {
1689
+ base: {
1690
+ maxWidth: "100%",
1691
+ height: "auto",
1692
+ borderRadius: "8px"
1693
+ }
1694
+ }
1695
+ };
1696
+
1697
+ // src/definitions/media/video.ts
1698
+ var import_schema9 = require("@kubuild/schema");
1442
1699
  var videoDefinition = {
1443
1700
  type: "video",
1444
1701
  label: "Video",
@@ -1506,25 +1763,25 @@ var videoDefinition = {
1506
1763
  ],
1507
1764
  validateProps: (props) => {
1508
1765
  const errors = [];
1509
- if (props.src !== void 0 && typeof props.src !== "string" && !(0, import_schema.isVariableBinding)(props.src)) {
1766
+ if (props.src !== void 0 && typeof props.src !== "string" && !(0, import_schema9.isVariableBinding)(props.src)) {
1510
1767
  errors.push('Video "src" must be a string when provided.');
1511
1768
  }
1512
- if (props.provider !== void 0 && !(0, import_schema.isVariableBinding)(props.provider)) {
1769
+ if (props.provider !== void 0 && !(0, import_schema9.isVariableBinding)(props.provider)) {
1513
1770
  const allowed = ["auto", "html5", "youtube", "vimeo"];
1514
1771
  if (typeof props.provider !== "string" || !allowed.includes(props.provider)) {
1515
1772
  errors.push(`Video "provider" must be one of: ${allowed.join(", ")}.`);
1516
1773
  }
1517
1774
  }
1518
- if (props.controls !== void 0 && typeof props.controls !== "boolean" && !(0, import_schema.isVariableBinding)(props.controls)) {
1775
+ if (props.controls !== void 0 && typeof props.controls !== "boolean" && !(0, import_schema9.isVariableBinding)(props.controls)) {
1519
1776
  errors.push('Video "controls" must be a boolean.');
1520
1777
  }
1521
- if (props.autoplay !== void 0 && typeof props.autoplay !== "boolean" && !(0, import_schema.isVariableBinding)(props.autoplay)) {
1778
+ if (props.autoplay !== void 0 && typeof props.autoplay !== "boolean" && !(0, import_schema9.isVariableBinding)(props.autoplay)) {
1522
1779
  errors.push('Video "autoplay" must be a boolean.');
1523
1780
  }
1524
- if (props.loop !== void 0 && typeof props.loop !== "boolean" && !(0, import_schema.isVariableBinding)(props.loop)) {
1781
+ if (props.loop !== void 0 && typeof props.loop !== "boolean" && !(0, import_schema9.isVariableBinding)(props.loop)) {
1525
1782
  errors.push('Video "loop" must be a boolean.');
1526
1783
  }
1527
- if (props.muted !== void 0 && typeof props.muted !== "boolean" && !(0, import_schema.isVariableBinding)(props.muted)) {
1784
+ if (props.muted !== void 0 && typeof props.muted !== "boolean" && !(0, import_schema9.isVariableBinding)(props.muted)) {
1528
1785
  errors.push('Video "muted" must be a boolean.');
1529
1786
  }
1530
1787
  return errors.length > 0 ? errors : true;
@@ -1540,6 +1797,9 @@ var videoDefinition = {
1540
1797
  }
1541
1798
  }
1542
1799
  };
1800
+
1801
+ // src/definitions/media/icon.ts
1802
+ var import_schema10 = require("@kubuild/schema");
1543
1803
  var iconDefinition = {
1544
1804
  type: "icon",
1545
1805
  label: "Icon",
@@ -1565,15 +1825,15 @@ var iconDefinition = {
1565
1825
  ],
1566
1826
  validateProps: (props) => {
1567
1827
  const errors = [];
1568
- if (props.name !== void 0 && !(0, import_schema.isVariableBinding)(props.name) && (typeof props.name !== "string" || props.name.trim().length === 0)) {
1828
+ if (props.name !== void 0 && !(0, import_schema10.isVariableBinding)(props.name) && (typeof props.name !== "string" || props.name.trim().length === 0)) {
1569
1829
  errors.push('Icon requires a non-empty "name".');
1570
1830
  }
1571
- if (props.size !== void 0 && !(0, import_schema.isVariableBinding)(props.size)) {
1831
+ if (props.size !== void 0 && !(0, import_schema10.isVariableBinding)(props.size)) {
1572
1832
  if (typeof props.size !== "number" || props.size < 0) {
1573
1833
  errors.push('Icon "size" must be a non-negative number.');
1574
1834
  }
1575
1835
  }
1576
- if (props.strokeWidth !== void 0 && !(0, import_schema.isVariableBinding)(props.strokeWidth)) {
1836
+ if (props.strokeWidth !== void 0 && !(0, import_schema10.isVariableBinding)(props.strokeWidth)) {
1577
1837
  if (typeof props.strokeWidth !== "number" || props.strokeWidth < 0) {
1578
1838
  errors.push('Icon "strokeWidth" must be a non-negative number.');
1579
1839
  }
@@ -1588,6 +1848,9 @@ var iconDefinition = {
1588
1848
  }
1589
1849
  }
1590
1850
  };
1851
+
1852
+ // src/definitions/media/html-embed.ts
1853
+ var import_schema11 = require("@kubuild/schema");
1591
1854
  var htmlEmbedDefinition = {
1592
1855
  type: "html-embed",
1593
1856
  label: "HTML Embed",
@@ -1611,7 +1874,7 @@ var htmlEmbedDefinition = {
1611
1874
  ],
1612
1875
  validateProps: (props) => {
1613
1876
  const errors = [];
1614
- if (props.html !== void 0 && typeof props.html !== "string" && !(0, import_schema.isVariableBinding)(props.html)) {
1877
+ if (props.html !== void 0 && typeof props.html !== "string" && !(0, import_schema11.isVariableBinding)(props.html)) {
1615
1878
  errors.push('HTML Embed "html" must be a string.');
1616
1879
  }
1617
1880
  return errors.length > 0 ? errors : true;
@@ -1623,6 +1886,9 @@ var htmlEmbedDefinition = {
1623
1886
  }
1624
1887
  }
1625
1888
  };
1889
+
1890
+ // src/definitions/data/table.ts
1891
+ var import_schema12 = require("@kubuild/schema");
1626
1892
  var tableDefinition = {
1627
1893
  type: "table",
1628
1894
  label: "Table",
@@ -1662,13 +1928,13 @@ var tableDefinition = {
1662
1928
  ],
1663
1929
  validateProps: (props) => {
1664
1930
  const errors = [];
1665
- if (props.striped !== void 0 && typeof props.striped !== "boolean" && !(0, import_schema.isVariableBinding)(props.striped)) {
1931
+ if (props.striped !== void 0 && typeof props.striped !== "boolean" && !(0, import_schema12.isVariableBinding)(props.striped)) {
1666
1932
  errors.push('Table "striped" must be a boolean.');
1667
1933
  }
1668
- if (props.bordered !== void 0 && typeof props.bordered !== "boolean" && !(0, import_schema.isVariableBinding)(props.bordered)) {
1934
+ if (props.bordered !== void 0 && typeof props.bordered !== "boolean" && !(0, import_schema12.isVariableBinding)(props.bordered)) {
1669
1935
  errors.push('Table "bordered" must be a boolean.');
1670
1936
  }
1671
- if (props.compact !== void 0 && typeof props.compact !== "boolean" && !(0, import_schema.isVariableBinding)(props.compact)) {
1937
+ if (props.compact !== void 0 && typeof props.compact !== "boolean" && !(0, import_schema12.isVariableBinding)(props.compact)) {
1672
1938
  errors.push('Table "compact" must be a boolean.');
1673
1939
  }
1674
1940
  return errors.length > 0 ? errors : true;
@@ -1698,91 +1964,439 @@ var tableRowDefinition = {
1698
1964
  ariaLabelTrait()
1699
1965
  ],
1700
1966
  defaultStyles: {
1701
- base: {}
1967
+ base: {}
1968
+ }
1969
+ };
1970
+ var tableCellDefinition = {
1971
+ type: "table-cell",
1972
+ label: "Table Cell",
1973
+ category: "layout",
1974
+ icon: "table-cell",
1975
+ acceptsChildren: true,
1976
+ allowedChildren: [
1977
+ "heading",
1978
+ "text",
1979
+ "paragraph",
1980
+ "link",
1981
+ "blockquote",
1982
+ "badge",
1983
+ "code-block",
1984
+ "image",
1985
+ "video",
1986
+ "icon",
1987
+ "html-embed",
1988
+ "button",
1989
+ "list",
1990
+ "custom"
1991
+ ],
1992
+ disallowedParents: ["page"],
1993
+ defaultProps: {
1994
+ tag: "td",
1995
+ text: "Cell",
1996
+ colSpan: 1,
1997
+ rowSpan: 1
1998
+ },
1999
+ propFields: [
2000
+ {
2001
+ name: "tag",
2002
+ label: "Cell Type",
2003
+ type: "select",
2004
+ defaultValue: "td",
2005
+ options: [
2006
+ { label: "Data Cell (td)", value: "td" },
2007
+ { label: "Header Cell (th)", value: "th" }
2008
+ ]
2009
+ },
2010
+ { name: "text", label: "Text", type: "string", defaultValue: "Cell" },
2011
+ { name: "colSpan", label: "Column Span (colSpan)", type: "number", defaultValue: 1 },
2012
+ { name: "rowSpan", label: "Row Span (rowSpan)", type: "number", defaultValue: 1 }
2013
+ ],
2014
+ traits: [
2015
+ colSpanTrait(),
2016
+ rowSpanTrait(),
2017
+ idTrait(),
2018
+ ariaLabelTrait()
2019
+ ],
2020
+ validateProps: (props) => {
2021
+ const errors = [];
2022
+ if (props.tag !== void 0 && !(0, import_schema12.isVariableBinding)(props.tag)) {
2023
+ if (props.tag !== "td" && props.tag !== "th") {
2024
+ errors.push('Table Cell "tag" must be either "td" or "th".');
2025
+ }
2026
+ }
2027
+ if (props.colSpan !== void 0 && !(0, import_schema12.isVariableBinding)(props.colSpan)) {
2028
+ if (typeof props.colSpan !== "number" || props.colSpan < 1 || !Number.isInteger(props.colSpan)) {
2029
+ errors.push('Table Cell "colSpan" must be a positive integer (>= 1).');
2030
+ }
2031
+ }
2032
+ if (props.rowSpan !== void 0 && !(0, import_schema12.isVariableBinding)(props.rowSpan)) {
2033
+ if (typeof props.rowSpan !== "number" || props.rowSpan < 1 || !Number.isInteger(props.rowSpan)) {
2034
+ errors.push('Table Cell "rowSpan" must be a positive integer (>= 1).');
2035
+ }
2036
+ }
2037
+ if (props.text !== void 0 && typeof props.text !== "string" && !(0, import_schema12.isVariableBinding)(props.text)) {
2038
+ errors.push('Table Cell "text" must be a string when provided.');
2039
+ }
2040
+ return errors.length > 0 ? errors : true;
2041
+ },
2042
+ defaultStyles: {
2043
+ base: {
2044
+ padding: "8px 12px",
2045
+ borderWidth: "1px",
2046
+ borderColor: "#e2e8f0",
2047
+ borderStyle: "solid",
2048
+ textAlign: "left"
2049
+ }
2050
+ }
2051
+ };
2052
+
2053
+ // src/definitions/data/list.ts
2054
+ var import_schema13 = require("@kubuild/schema");
2055
+ var listDefinition = {
2056
+ type: "list",
2057
+ label: "List",
2058
+ category: "typography",
2059
+ icon: "list",
2060
+ acceptsChildren: true,
2061
+ allowedChildren: ["list-item"],
2062
+ defaultProps: {
2063
+ tag: "ul",
2064
+ listStyleType: "disc"
2065
+ },
2066
+ defaultChildren: [
2067
+ { type: "list-item", props: { text: "List item 1" } },
2068
+ { type: "list-item", props: { text: "List item 2" } },
2069
+ { type: "list-item", props: { text: "List item 3" } }
2070
+ ],
2071
+ propFields: [
2072
+ {
2073
+ name: "tag",
2074
+ label: "Tag",
2075
+ type: "select",
2076
+ defaultValue: "ul",
2077
+ options: [
2078
+ { label: "Unordered (ul)", value: "ul" },
2079
+ { label: "Ordered (ol)", value: "ol" }
2080
+ ]
2081
+ },
2082
+ {
2083
+ name: "listStyleType",
2084
+ label: "List Style Type",
2085
+ type: "select",
2086
+ defaultValue: "disc",
2087
+ options: [
2088
+ { label: "Disc", value: "disc" },
2089
+ { label: "Circle", value: "circle" },
2090
+ { label: "Square", value: "square" },
2091
+ { label: "Decimal", value: "decimal" },
2092
+ { label: "None", value: "none" },
2093
+ { label: "Custom Icon", value: "custom-icon" }
2094
+ ]
2095
+ }
2096
+ ],
2097
+ traits: [
2098
+ idTrait(),
2099
+ ariaLabelTrait({ description: 'Accessible name for the list (e.g. "Navigation menu", "Features").' })
2100
+ ],
2101
+ validateProps: (props) => {
2102
+ const errors = [];
2103
+ if (props.tag !== void 0 && !(0, import_schema13.isVariableBinding)(props.tag)) {
2104
+ if (props.tag !== "ul" && props.tag !== "ol") {
2105
+ errors.push('List "tag" must be either "ul" or "ol".');
2106
+ }
2107
+ }
2108
+ if (props.listStyleType !== void 0 && !(0, import_schema13.isVariableBinding)(props.listStyleType)) {
2109
+ const allowed = ["disc", "circle", "square", "decimal", "none", "custom-icon"];
2110
+ if (typeof props.listStyleType !== "string" || !allowed.includes(props.listStyleType)) {
2111
+ errors.push(`List "listStyleType" must be one of: ${allowed.join(", ")}.`);
2112
+ }
2113
+ }
2114
+ return errors.length > 0 ? errors : true;
2115
+ },
2116
+ defaultStyles: {
2117
+ base: {
2118
+ margin: "0 0 16px 0",
2119
+ paddingLeft: "24px"
2120
+ }
2121
+ }
2122
+ };
2123
+ var listItemDefinition = {
2124
+ type: "list-item",
2125
+ label: "List Item",
2126
+ category: "typography",
2127
+ icon: "list-item",
2128
+ acceptsChildren: true,
2129
+ allowedChildren: [
2130
+ "heading",
2131
+ "text",
2132
+ "paragraph",
2133
+ "link",
2134
+ "blockquote",
2135
+ "badge",
2136
+ "code-block",
2137
+ "image",
2138
+ "video",
2139
+ "icon",
2140
+ "html-embed",
2141
+ "button",
2142
+ "list",
2143
+ "custom"
2144
+ ],
2145
+ defaultProps: {
2146
+ text: "List item"
2147
+ },
2148
+ propFields: [
2149
+ {
2150
+ name: "text",
2151
+ label: "Text",
2152
+ type: "string",
2153
+ defaultValue: "List item"
2154
+ }
2155
+ ],
2156
+ traits: [
2157
+ idTrait(),
2158
+ titleTrait(),
2159
+ ariaLabelTrait()
2160
+ ],
2161
+ validateProps: (props) => {
2162
+ const errors = [];
2163
+ if (props.text !== void 0 && typeof props.text !== "string" && !(0, import_schema13.isVariableBinding)(props.text)) {
2164
+ errors.push('List Item "text" must be a string when provided.');
2165
+ }
2166
+ return errors.length > 0 ? errors : true;
2167
+ },
2168
+ defaultStyles: {
2169
+ base: {
2170
+ margin: "4px 0",
2171
+ fontSize: "16px",
2172
+ color: "#374151",
2173
+ lineHeight: "1.5"
2174
+ }
2175
+ }
2176
+ };
2177
+
2178
+ // src/definitions/data/collection.ts
2179
+ var collectionDefinition = {
2180
+ type: "collection",
2181
+ label: "Collection",
2182
+ category: "data",
2183
+ icon: "database",
2184
+ acceptsChildren: true,
2185
+ defaultProps: {
2186
+ sourceKey: "items",
2187
+ itemAlias: "item"
2188
+ },
2189
+ propFields: [
2190
+ { name: "sourceKey", label: "Source Variable", type: "string", defaultValue: "items" },
2191
+ { name: "itemAlias", label: "Item Alias", type: "string", defaultValue: "item" }
2192
+ ],
2193
+ traits: [
2194
+ idTrait(),
2195
+ ariaLabelTrait({ description: 'Accessible name summarizing the repeated collection (e.g. "Product list").' })
2196
+ ]
2197
+ };
2198
+
2199
+ // src/definitions/form/button.ts
2200
+ var import_schema14 = require("@kubuild/schema");
2201
+ var buttonDefinition = {
2202
+ type: "button",
2203
+ label: "Button",
2204
+ category: "interactive",
2205
+ icon: "mouse-pointer",
2206
+ acceptsChildren: false,
2207
+ capabilities: ["actionRegistry"],
2208
+ defaultProps: {
2209
+ label: "Click Me",
2210
+ variant: "primary"
2211
+ },
2212
+ propFields: [
2213
+ { name: "label", label: "Label", type: "string", defaultValue: "Click Me" },
2214
+ { name: "href", label: "Link URL", type: "string" },
2215
+ { name: "action", label: "Action", type: "action" },
2216
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
2217
+ {
2218
+ name: "buttonType",
2219
+ label: "Button Type",
2220
+ type: "select",
2221
+ defaultValue: "button",
2222
+ options: [
2223
+ { label: "Button", value: "button" },
2224
+ { label: "Submit Form (submit)", value: "submit" },
2225
+ { label: "Reset Form (reset)", value: "reset" }
2226
+ ]
2227
+ },
2228
+ {
2229
+ name: "variant",
2230
+ label: "Variant",
2231
+ type: "select",
2232
+ defaultValue: "primary",
2233
+ options: [
2234
+ { label: "Primary", value: "primary" },
2235
+ { label: "Secondary", value: "secondary" }
2236
+ ]
2237
+ }
2238
+ ],
2239
+ traits: [
2240
+ buttonTypeTrait(),
2241
+ disabledTrait(),
2242
+ hrefTrait({ description: "Optional URL \u2014 when set, the button renders as an anchor styled like a button." }),
2243
+ targetTrait({ description: "Where to open the href URL (only used when href is set)." }),
2244
+ relTrait({ description: "Relationship tokens (only used when href is set)." }),
2245
+ idTrait(),
2246
+ titleTrait(),
2247
+ ariaLabelTrait()
2248
+ ],
2249
+ validateProps: (props) => {
2250
+ const errors = [];
2251
+ const hasLabel = typeof props.label === "string" && props.label.trim().length > 0 || (0, import_schema14.isVariableBinding)(props.label);
2252
+ if (!hasLabel) {
2253
+ errors.push('Button requires a non-empty "label".');
2254
+ }
2255
+ if (props.href !== void 0 && typeof props.href !== "string" && !(0, import_schema14.isVariableBinding)(props.href)) {
2256
+ errors.push('Button "href" must be a string when provided.');
2257
+ }
2258
+ if (props.buttonType !== void 0 && !(0, import_schema14.isVariableBinding)(props.buttonType)) {
2259
+ if (!["button", "submit", "reset"].includes(props.buttonType)) {
2260
+ errors.push('Button "buttonType" must be one of: "button", "submit", "reset".');
2261
+ }
2262
+ }
2263
+ if (props.action !== void 0 && !(0, import_schema14.isActionBinding)(props.action)) {
2264
+ errors.push('Button "action" must be a valid action binding when provided.');
2265
+ }
2266
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema14.isVariableBinding)(props.disabled)) {
2267
+ errors.push('Button "disabled" must be a boolean when provided.');
2268
+ }
2269
+ return errors.length > 0 ? errors : true;
2270
+ },
2271
+ defaultStyles: {
2272
+ base: {
2273
+ backgroundColor: "#2563eb",
2274
+ color: "#ffffff",
2275
+ paddingTop: "10px",
2276
+ paddingBottom: "10px",
2277
+ paddingLeft: "20px",
2278
+ paddingRight: "20px",
2279
+ borderRadius: "6px",
2280
+ fontWeight: "500",
2281
+ fontSize: "15px",
2282
+ border: "none",
2283
+ cursor: "pointer"
2284
+ }
1702
2285
  }
1703
2286
  };
1704
- var tableCellDefinition = {
1705
- type: "table-cell",
1706
- label: "Table Cell",
1707
- category: "layout",
1708
- icon: "table-cell",
1709
- acceptsChildren: true,
1710
- allowedChildren: [
1711
- "heading",
1712
- "text",
1713
- "paragraph",
1714
- "link",
1715
- "blockquote",
1716
- "badge",
1717
- "code-block",
1718
- "image",
1719
- "video",
1720
- "icon",
1721
- "html-embed",
1722
- "button",
1723
- "list",
1724
- "custom"
1725
- ],
2287
+ var buttonSubmitDefinition = {
2288
+ type: "button-submit",
2289
+ label: "Submit Button",
2290
+ category: "form",
2291
+ icon: "send",
2292
+ acceptsChildren: false,
2293
+ capabilities: ["actionRegistry"],
1726
2294
  disallowedParents: ["page"],
1727
2295
  defaultProps: {
1728
- tag: "td",
1729
- text: "Cell",
1730
- colSpan: 1,
1731
- rowSpan: 1
2296
+ label: "Submit",
2297
+ loadingText: "Submitting...",
2298
+ showSpinner: true,
2299
+ autoDisableOnSubmit: true,
2300
+ variant: "primary",
2301
+ disabled: false,
2302
+ buttonType: "submit"
1732
2303
  },
1733
2304
  propFields: [
2305
+ { name: "label", label: "Label", type: "string", defaultValue: "Submit" },
2306
+ { name: "loadingText", label: "Loading Text", type: "string", defaultValue: "Submitting..." },
2307
+ { name: "showSpinner", label: "Show Loading Spinner", type: "boolean", defaultValue: true },
2308
+ { name: "autoDisableOnSubmit", label: "Auto Disable on Submit", type: "boolean", defaultValue: true },
1734
2309
  {
1735
- name: "tag",
1736
- label: "Cell Type",
2310
+ name: "buttonType",
2311
+ label: "Button Type",
1737
2312
  type: "select",
1738
- defaultValue: "td",
2313
+ defaultValue: "submit",
1739
2314
  options: [
1740
- { label: "Data Cell (td)", value: "td" },
1741
- { label: "Header Cell (th)", value: "th" }
2315
+ { label: "Submit Form (submit)", value: "submit" },
2316
+ { label: "Reset Form (reset)", value: "reset" }
1742
2317
  ]
1743
2318
  },
1744
- { name: "text", label: "Text", type: "string", defaultValue: "Cell" },
1745
- { name: "colSpan", label: "Column Span (colSpan)", type: "number", defaultValue: 1 },
1746
- { name: "rowSpan", label: "Row Span (rowSpan)", type: "number", defaultValue: 1 }
2319
+ {
2320
+ name: "variant",
2321
+ label: "Variant",
2322
+ type: "select",
2323
+ defaultValue: "primary",
2324
+ options: [
2325
+ { label: "Primary", value: "primary" },
2326
+ { label: "Secondary", value: "secondary" }
2327
+ ]
2328
+ },
2329
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
2330
+ { name: "prefixIcon", label: "Prefix Icon", type: "string" },
2331
+ { name: "suffixIcon", label: "Suffix Icon", type: "string" }
1747
2332
  ],
1748
2333
  traits: [
1749
- colSpanTrait(),
1750
- rowSpanTrait(),
2334
+ buttonTypeTrait({
2335
+ defaultValue: "submit",
2336
+ options: [
2337
+ { label: "Submit Form (submit)", value: "submit" },
2338
+ { label: "Reset Form (reset)", value: "reset" }
2339
+ ]
2340
+ }),
2341
+ labelTextTrait({ defaultValue: "Submit", label: "Label" }),
2342
+ loadingTextTrait(),
2343
+ showSpinnerTrait(),
2344
+ autoDisableOnSubmitTrait(),
2345
+ disabledTrait(),
2346
+ prefixIconTrait(),
2347
+ suffixIconTrait(),
1751
2348
  idTrait(),
2349
+ titleTrait(),
1752
2350
  ariaLabelTrait()
1753
2351
  ],
1754
2352
  validateProps: (props) => {
1755
2353
  const errors = [];
1756
- if (props.tag !== void 0 && !(0, import_schema.isVariableBinding)(props.tag)) {
1757
- if (props.tag !== "td" && props.tag !== "th") {
1758
- errors.push('Table Cell "tag" must be either "td" or "th".');
1759
- }
2354
+ const hasLabel = typeof props.label === "string" && props.label.trim().length > 0 || (0, import_schema14.isVariableBinding)(props.label);
2355
+ if (!hasLabel) {
2356
+ errors.push('Submit Button requires a non-empty "label".');
1760
2357
  }
1761
- if (props.colSpan !== void 0 && !(0, import_schema.isVariableBinding)(props.colSpan)) {
1762
- if (typeof props.colSpan !== "number" || props.colSpan < 1 || !Number.isInteger(props.colSpan)) {
1763
- errors.push('Table Cell "colSpan" must be a positive integer (>= 1).');
1764
- }
2358
+ if (props.loadingText !== void 0 && typeof props.loadingText !== "string" && !(0, import_schema14.isVariableBinding)(props.loadingText)) {
2359
+ errors.push('Submit Button "loadingText" must be a string when provided.');
1765
2360
  }
1766
- if (props.rowSpan !== void 0 && !(0, import_schema.isVariableBinding)(props.rowSpan)) {
1767
- if (typeof props.rowSpan !== "number" || props.rowSpan < 1 || !Number.isInteger(props.rowSpan)) {
1768
- errors.push('Table Cell "rowSpan" must be a positive integer (>= 1).');
2361
+ if (props.showSpinner !== void 0 && typeof props.showSpinner !== "boolean" && !(0, import_schema14.isVariableBinding)(props.showSpinner)) {
2362
+ errors.push('Submit Button "showSpinner" must be a boolean when provided.');
2363
+ }
2364
+ if (props.autoDisableOnSubmit !== void 0 && typeof props.autoDisableOnSubmit !== "boolean" && !(0, import_schema14.isVariableBinding)(props.autoDisableOnSubmit)) {
2365
+ errors.push('Submit Button "autoDisableOnSubmit" must be a boolean when provided.');
2366
+ }
2367
+ if (props.buttonType !== void 0 && !(0, import_schema14.isVariableBinding)(props.buttonType)) {
2368
+ if (!["submit", "reset", "button"].includes(props.buttonType)) {
2369
+ errors.push('Submit Button "buttonType" must be one of: "submit", "reset", "button".');
1769
2370
  }
1770
2371
  }
1771
- if (props.text !== void 0 && typeof props.text !== "string" && !(0, import_schema.isVariableBinding)(props.text)) {
1772
- errors.push('Table Cell "text" must be a string when provided.');
2372
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema14.isVariableBinding)(props.disabled)) {
2373
+ errors.push('Submit Button "disabled" must be a boolean when provided.');
1773
2374
  }
1774
2375
  return errors.length > 0 ? errors : true;
1775
2376
  },
1776
2377
  defaultStyles: {
1777
2378
  base: {
1778
- padding: "8px 12px",
1779
- borderWidth: "1px",
1780
- borderColor: "#e2e8f0",
1781
- borderStyle: "solid",
1782
- textAlign: "left"
2379
+ backgroundColor: "#2563eb",
2380
+ color: "#ffffff",
2381
+ paddingTop: "10px",
2382
+ paddingBottom: "10px",
2383
+ paddingLeft: "20px",
2384
+ paddingRight: "20px",
2385
+ borderRadius: "6px",
2386
+ fontWeight: "500",
2387
+ fontSize: "15px",
2388
+ border: "none",
2389
+ cursor: "pointer",
2390
+ display: "inline-flex",
2391
+ alignItems: "center",
2392
+ justifyContent: "center",
2393
+ gap: "8px"
1783
2394
  }
1784
2395
  }
1785
2396
  };
2397
+
2398
+ // src/definitions/form/form.ts
2399
+ var import_schema15 = require("@kubuild/schema");
1786
2400
  var formDefinition = {
1787
2401
  type: "form",
1788
2402
  label: "Form",
@@ -1801,7 +2415,10 @@ var formDefinition = {
1801
2415
  method: "POST",
1802
2416
  action: "",
1803
2417
  target: "_self",
1804
- autoComplete: "on"
2418
+ autoComplete: "on",
2419
+ preventDefault: true,
2420
+ scrollToFirstError: true,
2421
+ resetOnSubmit: false
1805
2422
  },
1806
2423
  defaultChildren: [
1807
2424
  { type: "input", props: { name: "name", type: "text", placeholder: "Your Name", required: true } },
@@ -1842,7 +2459,10 @@ var formDefinition = {
1842
2459
  { label: "On", value: "on" },
1843
2460
  { label: "Off", value: "off" }
1844
2461
  ]
1845
- }
2462
+ },
2463
+ { name: "preventDefault", label: "Prevent Default", type: "boolean", defaultValue: true },
2464
+ { name: "scrollToFirstError", label: "Scroll to First Error", type: "boolean", defaultValue: true },
2465
+ { name: "resetOnSubmit", label: "Reset on Submit", type: "boolean", defaultValue: false }
1846
2466
  ],
1847
2467
  traits: [
1848
2468
  fieldNameTrait({ defaultValue: "contact_form", required: false }),
@@ -1855,32 +2475,44 @@ var formDefinition = {
1855
2475
  { label: "Top (_top)", value: "_top" }
1856
2476
  ] }),
1857
2477
  autoCompleteTrait(),
2478
+ preventDefaultTrait(),
2479
+ scrollToFirstErrorTrait(),
2480
+ resetOnSubmitTrait(),
1858
2481
  idTrait(),
1859
2482
  ariaLabelTrait({ description: "Accessible name for the form landmark." })
1860
2483
  ],
1861
2484
  validateProps: (props) => {
1862
2485
  const errors = [];
1863
- if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema.isVariableBinding)(props.name)) {
2486
+ if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema15.isVariableBinding)(props.name)) {
1864
2487
  errors.push('Form "name" must be a string when provided.');
1865
2488
  }
1866
- if (props.action !== void 0 && typeof props.action !== "string" && !(0, import_schema.isVariableBinding)(props.action)) {
2489
+ if (props.action !== void 0 && typeof props.action !== "string" && !(0, import_schema15.isVariableBinding)(props.action)) {
1867
2490
  errors.push('Form "action" must be a string when provided.');
1868
2491
  }
1869
- if (props.method !== void 0 && !(0, import_schema.isVariableBinding)(props.method)) {
2492
+ if (props.method !== void 0 && !(0, import_schema15.isVariableBinding)(props.method)) {
1870
2493
  if (!["GET", "POST", "get", "post"].includes(props.method)) {
1871
2494
  errors.push('Form "method" must be either "GET" or "POST".');
1872
2495
  }
1873
2496
  }
1874
- if (props.target !== void 0 && !(0, import_schema.isVariableBinding)(props.target)) {
2497
+ if (props.target !== void 0 && !(0, import_schema15.isVariableBinding)(props.target)) {
1875
2498
  if (!["_self", "_blank", "_parent", "_top"].includes(props.target)) {
1876
2499
  errors.push('Form "target" must be one of: "_self", "_blank", "_parent", "_top".');
1877
2500
  }
1878
2501
  }
1879
- if (props.autoComplete !== void 0 && !(0, import_schema.isVariableBinding)(props.autoComplete)) {
2502
+ if (props.autoComplete !== void 0 && !(0, import_schema15.isVariableBinding)(props.autoComplete)) {
1880
2503
  if (!["on", "off"].includes(props.autoComplete)) {
1881
2504
  errors.push('Form "autoComplete" must be either "on" or "off".');
1882
2505
  }
1883
2506
  }
2507
+ if (props.preventDefault !== void 0 && typeof props.preventDefault !== "boolean" && !(0, import_schema15.isVariableBinding)(props.preventDefault)) {
2508
+ errors.push('Form "preventDefault" must be a boolean when provided.');
2509
+ }
2510
+ if (props.scrollToFirstError !== void 0 && typeof props.scrollToFirstError !== "boolean" && !(0, import_schema15.isVariableBinding)(props.scrollToFirstError)) {
2511
+ errors.push('Form "scrollToFirstError" must be a boolean when provided.');
2512
+ }
2513
+ if (props.resetOnSubmit !== void 0 && typeof props.resetOnSubmit !== "boolean" && !(0, import_schema15.isVariableBinding)(props.resetOnSubmit)) {
2514
+ errors.push('Form "resetOnSubmit" must be a boolean when provided.');
2515
+ }
1884
2516
  return errors.length > 0 ? errors : true;
1885
2517
  },
1886
2518
  defaultStyles: {
@@ -1892,6 +2524,9 @@ var formDefinition = {
1892
2524
  }
1893
2525
  }
1894
2526
  };
2527
+
2528
+ // src/definitions/form/input.ts
2529
+ var import_schema16 = require("@kubuild/schema");
1895
2530
  var inputDefinition = {
1896
2531
  type: "input",
1897
2532
  label: "Input",
@@ -1906,7 +2541,13 @@ var inputDefinition = {
1906
2541
  defaultValue: "",
1907
2542
  required: false,
1908
2543
  disabled: false,
1909
- readOnly: false
2544
+ readOnly: false,
2545
+ pattern: "",
2546
+ minLength: void 0,
2547
+ maxLength: void 0,
2548
+ prefixIcon: "",
2549
+ suffixIcon: "",
2550
+ helperText: ""
1910
2551
  },
1911
2552
  propFields: [
1912
2553
  { name: "name", label: "Field Name", type: "string", defaultValue: "input_field" },
@@ -1930,7 +2571,13 @@ var inputDefinition = {
1930
2571
  { name: "defaultValue", label: "Default Value", type: "string" },
1931
2572
  { name: "required", label: "Required", type: "boolean", defaultValue: false },
1932
2573
  { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
1933
- { name: "readOnly", label: "Read Only", type: "boolean", defaultValue: false }
2574
+ { name: "readOnly", label: "Read Only", type: "boolean", defaultValue: false },
2575
+ { name: "pattern", label: "Pattern (regex)", type: "string" },
2576
+ { name: "minLength", label: "Min Length", type: "number" },
2577
+ { name: "maxLength", label: "Max Length", type: "number" },
2578
+ { name: "prefixIcon", label: "Prefix Icon", type: "string" },
2579
+ { name: "suffixIcon", label: "Suffix Icon", type: "string" },
2580
+ { name: "helperText", label: "Helper Text", type: "string" }
1934
2581
  ],
1935
2582
  traits: [
1936
2583
  inputTypeTrait({ options: [
@@ -1948,6 +2595,12 @@ var inputDefinition = {
1948
2595
  placeholderTrait({ defaultValue: "Enter text..." }),
1949
2596
  defaultValueTrait(),
1950
2597
  requiredTrait(),
2598
+ patternTrait(),
2599
+ minLengthTrait(),
2600
+ maxLengthTrait(),
2601
+ prefixIconTrait(),
2602
+ suffixIconTrait(),
2603
+ helperTextTrait(),
1951
2604
  disabledTrait(),
1952
2605
  readOnlyTrait(),
1953
2606
  idTrait(),
@@ -1955,27 +2608,49 @@ var inputDefinition = {
1955
2608
  ],
1956
2609
  validateProps: (props) => {
1957
2610
  const errors = [];
1958
- if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema.isVariableBinding)(props.name)) {
2611
+ if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema16.isVariableBinding)(props.name)) {
1959
2612
  errors.push('Input "name" must be a string when provided.');
1960
2613
  }
1961
- if (props.type !== void 0 && !(0, import_schema.isVariableBinding)(props.type)) {
2614
+ if (props.type !== void 0 && !(0, import_schema16.isVariableBinding)(props.type)) {
1962
2615
  const validTypes = ["text", "email", "number", "password", "tel", "url", "search", "date", "hidden"];
1963
2616
  if (!validTypes.includes(props.type)) {
1964
2617
  errors.push(`Input "type" must be one of: ${validTypes.join(", ")}.`);
1965
2618
  }
1966
2619
  }
1967
- if (props.placeholder !== void 0 && typeof props.placeholder !== "string" && !(0, import_schema.isVariableBinding)(props.placeholder)) {
2620
+ if (props.placeholder !== void 0 && typeof props.placeholder !== "string" && !(0, import_schema16.isVariableBinding)(props.placeholder)) {
1968
2621
  errors.push('Input "placeholder" must be a string when provided.');
1969
2622
  }
1970
- if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema.isVariableBinding)(props.required)) {
2623
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema16.isVariableBinding)(props.required)) {
1971
2624
  errors.push('Input "required" must be a boolean when provided.');
1972
2625
  }
1973
- if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema.isVariableBinding)(props.disabled)) {
2626
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema16.isVariableBinding)(props.disabled)) {
1974
2627
  errors.push('Input "disabled" must be a boolean when provided.');
1975
2628
  }
1976
- if (props.readOnly !== void 0 && typeof props.readOnly !== "boolean" && !(0, import_schema.isVariableBinding)(props.readOnly)) {
2629
+ if (props.readOnly !== void 0 && typeof props.readOnly !== "boolean" && !(0, import_schema16.isVariableBinding)(props.readOnly)) {
1977
2630
  errors.push('Input "readOnly" must be a boolean when provided.');
1978
2631
  }
2632
+ if (props.pattern !== void 0 && typeof props.pattern !== "string" && !(0, import_schema16.isVariableBinding)(props.pattern)) {
2633
+ errors.push('Input "pattern" must be a string when provided.');
2634
+ }
2635
+ if (props.minLength !== void 0 && !(0, import_schema16.isVariableBinding)(props.minLength)) {
2636
+ if (typeof props.minLength !== "number" || props.minLength < 0 || !Number.isInteger(props.minLength)) {
2637
+ errors.push('Input "minLength" must be a non-negative integer when provided.');
2638
+ }
2639
+ }
2640
+ if (props.maxLength !== void 0 && !(0, import_schema16.isVariableBinding)(props.maxLength)) {
2641
+ if (typeof props.maxLength !== "number" || props.maxLength < 0 || !Number.isInteger(props.maxLength)) {
2642
+ errors.push('Input "maxLength" must be a non-negative integer when provided.');
2643
+ }
2644
+ }
2645
+ if (props.prefixIcon !== void 0 && typeof props.prefixIcon !== "string" && !(0, import_schema16.isVariableBinding)(props.prefixIcon)) {
2646
+ errors.push('Input "prefixIcon" must be a string when provided.');
2647
+ }
2648
+ if (props.suffixIcon !== void 0 && typeof props.suffixIcon !== "string" && !(0, import_schema16.isVariableBinding)(props.suffixIcon)) {
2649
+ errors.push('Input "suffixIcon" must be a string when provided.');
2650
+ }
2651
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !(0, import_schema16.isVariableBinding)(props.helperText)) {
2652
+ errors.push('Input "helperText" must be a string when provided.');
2653
+ }
1979
2654
  return errors.length > 0 ? errors : true;
1980
2655
  },
1981
2656
  defaultStyles: {
@@ -1996,6 +2671,9 @@ var inputDefinition = {
1996
2671
  }
1997
2672
  }
1998
2673
  };
2674
+
2675
+ // src/definitions/form/textarea.ts
2676
+ var import_schema17 = require("@kubuild/schema");
1999
2677
  var textareaDefinition = {
2000
2678
  type: "textarea",
2001
2679
  label: "Textarea",
@@ -2010,7 +2688,11 @@ var textareaDefinition = {
2010
2688
  rows: 4,
2011
2689
  required: false,
2012
2690
  disabled: false,
2013
- readOnly: false
2691
+ readOnly: false,
2692
+ resize: "vertical",
2693
+ autoGrow: false,
2694
+ maxCharCount: void 0,
2695
+ helperText: ""
2014
2696
  },
2015
2697
  propFields: [
2016
2698
  { name: "name", label: "Field Name", type: "string", defaultValue: "message" },
@@ -2019,13 +2701,32 @@ var textareaDefinition = {
2019
2701
  { name: "rows", label: "Rows", type: "number", defaultValue: 4 },
2020
2702
  { name: "required", label: "Required", type: "boolean", defaultValue: false },
2021
2703
  { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
2022
- { name: "readOnly", label: "Read Only", type: "boolean", defaultValue: false }
2704
+ { name: "readOnly", label: "Read Only", type: "boolean", defaultValue: false },
2705
+ {
2706
+ name: "resize",
2707
+ label: "Resize",
2708
+ type: "select",
2709
+ defaultValue: "vertical",
2710
+ options: [
2711
+ { label: "Vertical only", value: "vertical" },
2712
+ { label: "Horizontal only", value: "horizontal" },
2713
+ { label: "Both", value: "both" },
2714
+ { label: "None", value: "none" }
2715
+ ]
2716
+ },
2717
+ { name: "autoGrow", label: "Auto Grow", type: "boolean", defaultValue: false },
2718
+ { name: "maxCharCount", label: "Max Character Count", type: "number" },
2719
+ { name: "helperText", label: "Helper Text", type: "string" }
2023
2720
  ],
2024
2721
  traits: [
2025
2722
  fieldNameTrait({ defaultValue: "message" }),
2026
2723
  placeholderTrait({ defaultValue: "Enter your message..." }),
2027
2724
  defaultValueTrait(),
2028
2725
  rowsTrait(),
2726
+ resizeTrait(),
2727
+ autoGrowTrait(),
2728
+ maxCharCountTrait(),
2729
+ helperTextTrait(),
2029
2730
  requiredTrait(),
2030
2731
  disabledTrait(),
2031
2732
  readOnlyTrait(),
@@ -2034,26 +2735,43 @@ var textareaDefinition = {
2034
2735
  ],
2035
2736
  validateProps: (props) => {
2036
2737
  const errors = [];
2037
- if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema.isVariableBinding)(props.name)) {
2738
+ if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema17.isVariableBinding)(props.name)) {
2038
2739
  errors.push('Textarea "name" must be a string when provided.');
2039
2740
  }
2040
- if (props.rows !== void 0 && !(0, import_schema.isVariableBinding)(props.rows)) {
2741
+ if (props.rows !== void 0 && !(0, import_schema17.isVariableBinding)(props.rows)) {
2041
2742
  if (typeof props.rows !== "number" || props.rows < 1 || !Number.isInteger(props.rows)) {
2042
2743
  errors.push('Textarea "rows" must be a positive integer (>= 1).');
2043
2744
  }
2044
2745
  }
2045
- if (props.placeholder !== void 0 && typeof props.placeholder !== "string" && !(0, import_schema.isVariableBinding)(props.placeholder)) {
2746
+ if (props.placeholder !== void 0 && typeof props.placeholder !== "string" && !(0, import_schema17.isVariableBinding)(props.placeholder)) {
2046
2747
  errors.push('Textarea "placeholder" must be a string when provided.');
2047
2748
  }
2048
- if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema.isVariableBinding)(props.required)) {
2749
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema17.isVariableBinding)(props.required)) {
2049
2750
  errors.push('Textarea "required" must be a boolean when provided.');
2050
2751
  }
2051
- if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema.isVariableBinding)(props.disabled)) {
2752
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema17.isVariableBinding)(props.disabled)) {
2052
2753
  errors.push('Textarea "disabled" must be a boolean when provided.');
2053
2754
  }
2054
- if (props.readOnly !== void 0 && typeof props.readOnly !== "boolean" && !(0, import_schema.isVariableBinding)(props.readOnly)) {
2755
+ if (props.readOnly !== void 0 && typeof props.readOnly !== "boolean" && !(0, import_schema17.isVariableBinding)(props.readOnly)) {
2055
2756
  errors.push('Textarea "readOnly" must be a boolean when provided.');
2056
2757
  }
2758
+ if (props.resize !== void 0 && !(0, import_schema17.isVariableBinding)(props.resize)) {
2759
+ const allowedResize = ["vertical", "horizontal", "both", "none"];
2760
+ if (typeof props.resize !== "string" || !allowedResize.includes(props.resize)) {
2761
+ errors.push(`Textarea "resize" must be one of: ${allowedResize.join(", ")}.`);
2762
+ }
2763
+ }
2764
+ if (props.autoGrow !== void 0 && typeof props.autoGrow !== "boolean" && !(0, import_schema17.isVariableBinding)(props.autoGrow)) {
2765
+ errors.push('Textarea "autoGrow" must be a boolean when provided.');
2766
+ }
2767
+ if (props.maxCharCount !== void 0 && !(0, import_schema17.isVariableBinding)(props.maxCharCount)) {
2768
+ if (typeof props.maxCharCount !== "number" || props.maxCharCount < 1 || !Number.isInteger(props.maxCharCount)) {
2769
+ errors.push('Textarea "maxCharCount" must be a positive integer (>= 1) when provided.');
2770
+ }
2771
+ }
2772
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !(0, import_schema17.isVariableBinding)(props.helperText)) {
2773
+ errors.push('Textarea "helperText" must be a string when provided.');
2774
+ }
2057
2775
  return errors.length > 0 ? errors : true;
2058
2776
  },
2059
2777
  defaultStyles: {
@@ -2074,6 +2792,9 @@ var textareaDefinition = {
2074
2792
  }
2075
2793
  }
2076
2794
  };
2795
+
2796
+ // src/definitions/form/select.ts
2797
+ var import_schema18 = require("@kubuild/schema");
2077
2798
  var selectDefinition = {
2078
2799
  type: "select",
2079
2800
  label: "Select",
@@ -2091,7 +2812,8 @@ var selectDefinition = {
2091
2812
  ],
2092
2813
  defaultValue: "",
2093
2814
  required: false,
2094
- disabled: false
2815
+ disabled: false,
2816
+ helperText: ""
2095
2817
  },
2096
2818
  propFields: [
2097
2819
  { name: "name", label: "Field Name", type: "string", defaultValue: "select_field" },
@@ -2108,12 +2830,15 @@ var selectDefinition = {
2108
2830
  },
2109
2831
  { name: "defaultValue", label: "Default Selected Value", type: "string" },
2110
2832
  { name: "required", label: "Required", type: "boolean", defaultValue: false },
2111
- { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false }
2833
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
2834
+ { name: "helperText", label: "Helper Text", type: "string" }
2112
2835
  ],
2113
2836
  traits: [
2114
2837
  fieldNameTrait({ defaultValue: "select_field" }),
2115
2838
  placeholderTrait({ defaultValue: "Select an option..." }),
2839
+ optionsListTrait({ description: "The list of dropdown choices (label + value pairs). Editable via the inspector trait panel." }),
2116
2840
  defaultValueTrait({ description: "The initially selected option value (must match one of the option values)." }),
2841
+ helperTextTrait(),
2117
2842
  requiredTrait(),
2118
2843
  disabledTrait(),
2119
2844
  idTrait(),
@@ -2121,20 +2846,23 @@ var selectDefinition = {
2121
2846
  ],
2122
2847
  validateProps: (props) => {
2123
2848
  const errors = [];
2124
- if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema.isVariableBinding)(props.name)) {
2849
+ if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema18.isVariableBinding)(props.name)) {
2125
2850
  errors.push('Select "name" must be a string when provided.');
2126
2851
  }
2127
- if (props.options !== void 0 && !(0, import_schema.isVariableBinding)(props.options)) {
2852
+ if (props.options !== void 0 && !(0, import_schema18.isVariableBinding)(props.options)) {
2128
2853
  if (!Array.isArray(props.options) && typeof props.options !== "string") {
2129
2854
  errors.push('Select "options" must be an array of option objects or a JSON string.');
2130
2855
  }
2131
2856
  }
2132
- if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema.isVariableBinding)(props.required)) {
2857
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema18.isVariableBinding)(props.required)) {
2133
2858
  errors.push('Select "required" must be a boolean when provided.');
2134
2859
  }
2135
- if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema.isVariableBinding)(props.disabled)) {
2860
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema18.isVariableBinding)(props.disabled)) {
2136
2861
  errors.push('Select "disabled" must be a boolean when provided.');
2137
2862
  }
2863
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !(0, import_schema18.isVariableBinding)(props.helperText)) {
2864
+ errors.push('Select "helperText" must be a string when provided.');
2865
+ }
2138
2866
  return errors.length > 0 ? errors : true;
2139
2867
  },
2140
2868
  defaultStyles: {
@@ -2155,6 +2883,9 @@ var selectDefinition = {
2155
2883
  }
2156
2884
  }
2157
2885
  };
2886
+
2887
+ // src/definitions/form/checkbox.ts
2888
+ var import_schema19 = require("@kubuild/schema");
2158
2889
  var checkboxDefinition = {
2159
2890
  type: "checkbox",
2160
2891
  label: "Checkbox",
@@ -2163,25 +2894,218 @@ var checkboxDefinition = {
2163
2894
  acceptsChildren: false,
2164
2895
  disallowedParents: ["page"],
2165
2896
  defaultProps: {
2166
- name: "checkbox_field",
2167
- label: "I agree to the terms and conditions",
2168
- value: "yes",
2169
- defaultChecked: false,
2897
+ name: "checkbox_field",
2898
+ label: "I agree to the terms and conditions",
2899
+ value: "yes",
2900
+ defaultChecked: false,
2901
+ indeterminate: false,
2902
+ required: false,
2903
+ disabled: false,
2904
+ helperText: ""
2905
+ },
2906
+ propFields: [
2907
+ { name: "name", label: "Field Name", type: "string", defaultValue: "checkbox_field" },
2908
+ { name: "label", label: "Label Text", type: "string", defaultValue: "I agree to the terms and conditions" },
2909
+ { name: "value", label: "Checked Value", type: "string", defaultValue: "yes" },
2910
+ { name: "defaultChecked", label: "Default Checked", type: "boolean", defaultValue: false },
2911
+ { name: "indeterminate", label: "Indeterminate", type: "boolean", defaultValue: false },
2912
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
2913
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
2914
+ { name: "helperText", label: "Helper Text", type: "string" }
2915
+ ],
2916
+ traits: [
2917
+ fieldNameTrait({ defaultValue: "checkbox_field" }),
2918
+ labelTextTrait({ defaultValue: "I agree to the terms and conditions" }),
2919
+ valueTrait({ defaultValue: "yes" }),
2920
+ defaultCheckedTrait(),
2921
+ indeterminateTrait(),
2922
+ helperTextTrait(),
2923
+ requiredTrait(),
2924
+ disabledTrait(),
2925
+ idTrait(),
2926
+ ariaLabelTrait()
2927
+ ],
2928
+ validateProps: (props) => {
2929
+ const errors = [];
2930
+ if (props.label !== void 0 && typeof props.label !== "string" && !(0, import_schema19.isVariableBinding)(props.label)) {
2931
+ errors.push('Checkbox "label" must be a string when provided.');
2932
+ }
2933
+ if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema19.isVariableBinding)(props.name)) {
2934
+ errors.push('Checkbox "name" must be a string when provided.');
2935
+ }
2936
+ if (props.value !== void 0 && typeof props.value !== "string" && !(0, import_schema19.isVariableBinding)(props.value)) {
2937
+ errors.push('Checkbox "value" must be a string when provided.');
2938
+ }
2939
+ if (props.defaultChecked !== void 0 && typeof props.defaultChecked !== "boolean" && !(0, import_schema19.isVariableBinding)(props.defaultChecked)) {
2940
+ errors.push('Checkbox "defaultChecked" must be a boolean when provided.');
2941
+ }
2942
+ if (props.indeterminate !== void 0 && typeof props.indeterminate !== "boolean" && !(0, import_schema19.isVariableBinding)(props.indeterminate)) {
2943
+ errors.push('Checkbox "indeterminate" must be a boolean when provided.');
2944
+ }
2945
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema19.isVariableBinding)(props.required)) {
2946
+ errors.push('Checkbox "required" must be a boolean when provided.');
2947
+ }
2948
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema19.isVariableBinding)(props.disabled)) {
2949
+ errors.push('Checkbox "disabled" must be a boolean when provided.');
2950
+ }
2951
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !(0, import_schema19.isVariableBinding)(props.helperText)) {
2952
+ errors.push('Checkbox "helperText" must be a string when provided.');
2953
+ }
2954
+ return errors.length > 0 ? errors : true;
2955
+ },
2956
+ defaultStyles: {
2957
+ base: {
2958
+ display: "inline-flex",
2959
+ alignItems: "center",
2960
+ gap: "8px",
2961
+ fontSize: "14px",
2962
+ color: "#1e293b",
2963
+ cursor: "pointer",
2964
+ userSelect: "none"
2965
+ }
2966
+ }
2967
+ };
2968
+
2969
+ // src/definitions/form/switch.ts
2970
+ var import_schema20 = require("@kubuild/schema");
2971
+ var switchDefinition = {
2972
+ type: "switch",
2973
+ label: "Switch",
2974
+ category: "form",
2975
+ icon: "switch",
2976
+ acceptsChildren: false,
2977
+ disallowedParents: ["page"],
2978
+ defaultProps: {
2979
+ name: "switch_field",
2980
+ label: "Enable feature",
2981
+ value: "yes",
2982
+ defaultChecked: false,
2983
+ switchSize: "md",
2984
+ required: false,
2985
+ disabled: false,
2986
+ helperText: ""
2987
+ },
2988
+ propFields: [
2989
+ { name: "name", label: "Field Name", type: "string", defaultValue: "switch_field" },
2990
+ { name: "label", label: "Label Text", type: "string", defaultValue: "Enable feature" },
2991
+ { name: "value", label: "Checked Value", type: "string", defaultValue: "yes" },
2992
+ { name: "defaultChecked", label: "Default Checked", type: "boolean", defaultValue: false },
2993
+ {
2994
+ name: "switchSize",
2995
+ label: "Size",
2996
+ type: "select",
2997
+ defaultValue: "md",
2998
+ options: [
2999
+ { label: "Small", value: "sm" },
3000
+ { label: "Medium", value: "md" },
3001
+ { label: "Large", value: "lg" }
3002
+ ]
3003
+ },
3004
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
3005
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
3006
+ { name: "helperText", label: "Helper Text", type: "string" }
3007
+ ],
3008
+ traits: [
3009
+ fieldNameTrait({ defaultValue: "switch_field" }),
3010
+ labelTextTrait({ defaultValue: "Enable feature" }),
3011
+ valueTrait({ defaultValue: "yes" }),
3012
+ defaultCheckedTrait(),
3013
+ switchSizeTrait(),
3014
+ helperTextTrait(),
3015
+ requiredTrait(),
3016
+ disabledTrait(),
3017
+ idTrait(),
3018
+ ariaLabelTrait()
3019
+ ],
3020
+ validateProps: (props) => {
3021
+ const errors = [];
3022
+ if (props.label !== void 0 && typeof props.label !== "string" && !(0, import_schema20.isVariableBinding)(props.label)) {
3023
+ errors.push('Switch "label" must be a string when provided.');
3024
+ }
3025
+ if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema20.isVariableBinding)(props.name)) {
3026
+ errors.push('Switch "name" must be a string when provided.');
3027
+ }
3028
+ if (props.value !== void 0 && typeof props.value !== "string" && !(0, import_schema20.isVariableBinding)(props.value)) {
3029
+ errors.push('Switch "value" must be a string when provided.');
3030
+ }
3031
+ if (props.defaultChecked !== void 0 && typeof props.defaultChecked !== "boolean" && !(0, import_schema20.isVariableBinding)(props.defaultChecked)) {
3032
+ errors.push('Switch "defaultChecked" must be a boolean when provided.');
3033
+ }
3034
+ if (props.switchSize !== void 0 && !(0, import_schema20.isVariableBinding)(props.switchSize)) {
3035
+ const allowedSizes = ["sm", "md", "lg"];
3036
+ if (typeof props.switchSize !== "string" || !allowedSizes.includes(props.switchSize)) {
3037
+ errors.push(`Switch "switchSize" must be one of: ${allowedSizes.join(", ")}.`);
3038
+ }
3039
+ }
3040
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema20.isVariableBinding)(props.required)) {
3041
+ errors.push('Switch "required" must be a boolean when provided.');
3042
+ }
3043
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema20.isVariableBinding)(props.disabled)) {
3044
+ errors.push('Switch "disabled" must be a boolean when provided.');
3045
+ }
3046
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !(0, import_schema20.isVariableBinding)(props.helperText)) {
3047
+ errors.push('Switch "helperText" must be a string when provided.');
3048
+ }
3049
+ return errors.length > 0 ? errors : true;
3050
+ },
3051
+ defaultStyles: {
3052
+ base: {
3053
+ display: "inline-flex",
3054
+ alignItems: "center",
3055
+ gap: "8px",
3056
+ fontSize: "14px",
3057
+ color: "#1e293b",
3058
+ cursor: "pointer",
3059
+ userSelect: "none"
3060
+ }
3061
+ }
3062
+ };
3063
+
3064
+ // src/definitions/form/radio.ts
3065
+ var import_schema21 = require("@kubuild/schema");
3066
+ var radioGroupDefinition = {
3067
+ type: "radio-group",
3068
+ label: "Radio Group",
3069
+ category: "form",
3070
+ icon: "radio-group",
3071
+ acceptsChildren: true,
3072
+ allowedChildren: ["radio", "radio-item", "custom"],
3073
+ disallowedParents: ["page"],
3074
+ defaultProps: {
3075
+ name: "radio_group",
3076
+ defaultSelected: "option1",
3077
+ orientation: "vertical",
2170
3078
  required: false,
2171
- disabled: false
3079
+ disabled: false,
3080
+ helperText: ""
2172
3081
  },
3082
+ defaultChildren: [
3083
+ { type: "radio", props: { name: "radio_group", label: "Option 1", value: "option1", defaultChecked: true } },
3084
+ { type: "radio", props: { name: "radio_group", label: "Option 2", value: "option2", defaultChecked: false } },
3085
+ { type: "radio", props: { name: "radio_group", label: "Option 3", value: "option3", defaultChecked: false } }
3086
+ ],
2173
3087
  propFields: [
2174
- { name: "name", label: "Field Name", type: "string", defaultValue: "checkbox_field" },
2175
- { name: "label", label: "Label Text", type: "string", defaultValue: "I agree to the terms and conditions" },
2176
- { name: "value", label: "Checked Value", type: "string", defaultValue: "yes" },
2177
- { name: "defaultChecked", label: "Default Checked", type: "boolean", defaultValue: false },
3088
+ { name: "name", label: "Group Name", type: "string", defaultValue: "radio_group" },
3089
+ { name: "defaultSelected", label: "Default Selected", type: "string", defaultValue: "option1" },
3090
+ {
3091
+ name: "orientation",
3092
+ label: "Orientation",
3093
+ type: "select",
3094
+ defaultValue: "vertical",
3095
+ options: [
3096
+ { label: "Vertical", value: "vertical" },
3097
+ { label: "Horizontal", value: "horizontal" }
3098
+ ]
3099
+ },
2178
3100
  { name: "required", label: "Required", type: "boolean", defaultValue: false },
2179
- { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false }
3101
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
3102
+ { name: "helperText", label: "Helper Text", type: "string" }
2180
3103
  ],
2181
3104
  traits: [
2182
- fieldNameTrait({ defaultValue: "checkbox_field" }),
2183
- valueTrait({ defaultValue: "yes" }),
2184
- defaultCheckedTrait(),
3105
+ fieldNameTrait({ defaultValue: "radio_group", label: "Group Name" }),
3106
+ defaultSelectedTrait({ defaultValue: "option1" }),
3107
+ orientationTrait(),
3108
+ helperTextTrait(),
2185
3109
  requiredTrait(),
2186
3110
  disabledTrait(),
2187
3111
  idTrait(),
@@ -2189,35 +3113,34 @@ var checkboxDefinition = {
2189
3113
  ],
2190
3114
  validateProps: (props) => {
2191
3115
  const errors = [];
2192
- if (props.label !== void 0 && typeof props.label !== "string" && !(0, import_schema.isVariableBinding)(props.label)) {
2193
- errors.push('Checkbox "label" must be a string when provided.');
3116
+ if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema21.isVariableBinding)(props.name)) {
3117
+ errors.push('RadioGroup "name" must be a string when provided.');
2194
3118
  }
2195
- if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema.isVariableBinding)(props.name)) {
2196
- errors.push('Checkbox "name" must be a string when provided.');
3119
+ if (props.defaultSelected !== void 0 && typeof props.defaultSelected !== "string" && !(0, import_schema21.isVariableBinding)(props.defaultSelected)) {
3120
+ errors.push('RadioGroup "defaultSelected" must be a string when provided.');
2197
3121
  }
2198
- if (props.value !== void 0 && typeof props.value !== "string" && !(0, import_schema.isVariableBinding)(props.value)) {
2199
- errors.push('Checkbox "value" must be a string when provided.');
3122
+ if (props.orientation !== void 0 && !(0, import_schema21.isVariableBinding)(props.orientation)) {
3123
+ const allowedOrientations = ["vertical", "horizontal"];
3124
+ if (typeof props.orientation !== "string" || !allowedOrientations.includes(props.orientation)) {
3125
+ errors.push(`RadioGroup "orientation" must be one of: ${allowedOrientations.join(", ")}.`);
3126
+ }
2200
3127
  }
2201
- if (props.defaultChecked !== void 0 && typeof props.defaultChecked !== "boolean" && !(0, import_schema.isVariableBinding)(props.defaultChecked)) {
2202
- errors.push('Checkbox "defaultChecked" must be a boolean when provided.');
3128
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema21.isVariableBinding)(props.required)) {
3129
+ errors.push('RadioGroup "required" must be a boolean when provided.');
2203
3130
  }
2204
- if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema.isVariableBinding)(props.required)) {
2205
- errors.push('Checkbox "required" must be a boolean when provided.');
3131
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema21.isVariableBinding)(props.disabled)) {
3132
+ errors.push('RadioGroup "disabled" must be a boolean when provided.');
2206
3133
  }
2207
- if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema.isVariableBinding)(props.disabled)) {
2208
- errors.push('Checkbox "disabled" must be a boolean when provided.');
3134
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !(0, import_schema21.isVariableBinding)(props.helperText)) {
3135
+ errors.push('RadioGroup "helperText" must be a string when provided.');
2209
3136
  }
2210
3137
  return errors.length > 0 ? errors : true;
2211
3138
  },
2212
3139
  defaultStyles: {
2213
3140
  base: {
2214
- display: "inline-flex",
2215
- alignItems: "center",
2216
- gap: "8px",
2217
- fontSize: "14px",
2218
- color: "#1e293b",
2219
- cursor: "pointer",
2220
- userSelect: "none"
3141
+ display: "flex",
3142
+ flexDirection: "column",
3143
+ gap: "8px"
2221
3144
  }
2222
3145
  }
2223
3146
  };
@@ -2234,7 +3157,8 @@ var radioDefinition = {
2234
3157
  value: "option1",
2235
3158
  defaultChecked: false,
2236
3159
  required: false,
2237
- disabled: false
3160
+ disabled: false,
3161
+ helperText: ""
2238
3162
  },
2239
3163
  propFields: [
2240
3164
  { name: "name", label: "Group Name", type: "string", defaultValue: "radio_group" },
@@ -2242,12 +3166,15 @@ var radioDefinition = {
2242
3166
  { name: "value", label: "Radio Value", type: "string", defaultValue: "option1" },
2243
3167
  { name: "defaultChecked", label: "Default Selected", type: "boolean", defaultValue: false },
2244
3168
  { name: "required", label: "Required", type: "boolean", defaultValue: false },
2245
- { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false }
3169
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
3170
+ { name: "helperText", label: "Helper Text", type: "string" }
2246
3171
  ],
2247
3172
  traits: [
2248
3173
  fieldNameTrait({ defaultValue: "radio_group", label: "Group Name" }),
3174
+ labelTextTrait({ defaultValue: "Option 1" }),
2249
3175
  valueTrait({ defaultValue: "option1" }),
2250
3176
  defaultCheckedTrait(),
3177
+ helperTextTrait(),
2251
3178
  requiredTrait(),
2252
3179
  disabledTrait(),
2253
3180
  idTrait(),
@@ -2255,24 +3182,27 @@ var radioDefinition = {
2255
3182
  ],
2256
3183
  validateProps: (props) => {
2257
3184
  const errors = [];
2258
- if (props.label !== void 0 && typeof props.label !== "string" && !(0, import_schema.isVariableBinding)(props.label)) {
3185
+ if (props.label !== void 0 && typeof props.label !== "string" && !(0, import_schema21.isVariableBinding)(props.label)) {
2259
3186
  errors.push('Radio "label" must be a string when provided.');
2260
3187
  }
2261
- if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema.isVariableBinding)(props.name)) {
3188
+ if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema21.isVariableBinding)(props.name)) {
2262
3189
  errors.push('Radio "name" must be a string when provided.');
2263
3190
  }
2264
- if (props.value !== void 0 && typeof props.value !== "string" && !(0, import_schema.isVariableBinding)(props.value)) {
3191
+ if (props.value !== void 0 && typeof props.value !== "string" && !(0, import_schema21.isVariableBinding)(props.value)) {
2265
3192
  errors.push('Radio "value" must be a string when provided.');
2266
3193
  }
2267
- if (props.defaultChecked !== void 0 && typeof props.defaultChecked !== "boolean" && !(0, import_schema.isVariableBinding)(props.defaultChecked)) {
3194
+ if (props.defaultChecked !== void 0 && typeof props.defaultChecked !== "boolean" && !(0, import_schema21.isVariableBinding)(props.defaultChecked)) {
2268
3195
  errors.push('Radio "defaultChecked" must be a boolean when provided.');
2269
3196
  }
2270
- if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema.isVariableBinding)(props.required)) {
3197
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema21.isVariableBinding)(props.required)) {
2271
3198
  errors.push('Radio "required" must be a boolean when provided.');
2272
3199
  }
2273
- if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema.isVariableBinding)(props.disabled)) {
3200
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema21.isVariableBinding)(props.disabled)) {
2274
3201
  errors.push('Radio "disabled" must be a boolean when provided.');
2275
3202
  }
3203
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !(0, import_schema21.isVariableBinding)(props.helperText)) {
3204
+ errors.push('Radio "helperText" must be a string when provided.');
3205
+ }
2276
3206
  return errors.length > 0 ? errors : true;
2277
3207
  },
2278
3208
  defaultStyles: {
@@ -2287,11 +3217,332 @@ var radioDefinition = {
2287
3217
  }
2288
3218
  }
2289
3219
  };
3220
+ var radioItemDefinition = {
3221
+ ...radioDefinition,
3222
+ type: "radio-item",
3223
+ label: "Radio Item"
3224
+ };
3225
+
3226
+ // src/definitions/form/file-upload.ts
3227
+ var import_schema22 = require("@kubuild/schema");
3228
+ var fileUploadDefinition = {
3229
+ type: "file-upload",
3230
+ label: "File Upload",
3231
+ category: "form",
3232
+ icon: "upload",
3233
+ acceptsChildren: false,
3234
+ disallowedParents: ["page"],
3235
+ defaultProps: {
3236
+ name: "file_upload",
3237
+ label: "Upload File",
3238
+ accept: "*/*",
3239
+ maxFileSize: 10,
3240
+ multiple: false,
3241
+ showPreview: true,
3242
+ required: false,
3243
+ disabled: false,
3244
+ helperText: ""
3245
+ },
3246
+ propFields: [
3247
+ { name: "name", label: "Field Name", type: "string", defaultValue: "file_upload" },
3248
+ { name: "label", label: "Label Text", type: "string", defaultValue: "Upload File" },
3249
+ { name: "accept", label: "Accepted File Types", type: "string", defaultValue: "*/*" },
3250
+ { name: "maxFileSize", label: "Max File Size (MB)", type: "number", defaultValue: 10 },
3251
+ { name: "multiple", label: "Allow Multiple Files", type: "boolean", defaultValue: false },
3252
+ { name: "showPreview", label: "Show Preview", type: "boolean", defaultValue: true },
3253
+ { name: "required", label: "Required", type: "boolean", defaultValue: false },
3254
+ { name: "disabled", label: "Disabled", type: "boolean", defaultValue: false },
3255
+ { name: "helperText", label: "Helper Text", type: "string" }
3256
+ ],
3257
+ traits: [
3258
+ fieldNameTrait({ defaultValue: "file_upload" }),
3259
+ labelTextTrait({ defaultValue: "Upload File" }),
3260
+ acceptTrait(),
3261
+ maxFileSizeTrait(),
3262
+ multipleTrait(),
3263
+ showPreviewTrait(),
3264
+ helperTextTrait(),
3265
+ requiredTrait(),
3266
+ disabledTrait(),
3267
+ idTrait(),
3268
+ ariaLabelTrait()
3269
+ ],
3270
+ validateProps: (props) => {
3271
+ const errors = [];
3272
+ if (props.label !== void 0 && typeof props.label !== "string" && !(0, import_schema22.isVariableBinding)(props.label)) {
3273
+ errors.push('FileUpload "label" must be a string when provided.');
3274
+ }
3275
+ if (props.name !== void 0 && typeof props.name !== "string" && !(0, import_schema22.isVariableBinding)(props.name)) {
3276
+ errors.push('FileUpload "name" must be a string when provided.');
3277
+ }
3278
+ if (props.accept !== void 0 && typeof props.accept !== "string" && !(0, import_schema22.isVariableBinding)(props.accept)) {
3279
+ errors.push('FileUpload "accept" must be a string when provided.');
3280
+ }
3281
+ if (props.maxFileSize !== void 0 && !(0, import_schema22.isVariableBinding)(props.maxFileSize)) {
3282
+ if (typeof props.maxFileSize !== "number" || props.maxFileSize <= 0) {
3283
+ errors.push('FileUpload "maxFileSize" must be a positive number when provided.');
3284
+ }
3285
+ }
3286
+ if (props.multiple !== void 0 && typeof props.multiple !== "boolean" && !(0, import_schema22.isVariableBinding)(props.multiple)) {
3287
+ errors.push('FileUpload "multiple" must be a boolean when provided.');
3288
+ }
3289
+ if (props.showPreview !== void 0 && typeof props.showPreview !== "boolean" && !(0, import_schema22.isVariableBinding)(props.showPreview)) {
3290
+ errors.push('FileUpload "showPreview" must be a boolean when provided.');
3291
+ }
3292
+ if (props.required !== void 0 && typeof props.required !== "boolean" && !(0, import_schema22.isVariableBinding)(props.required)) {
3293
+ errors.push('FileUpload "required" must be a boolean when provided.');
3294
+ }
3295
+ if (props.disabled !== void 0 && typeof props.disabled !== "boolean" && !(0, import_schema22.isVariableBinding)(props.disabled)) {
3296
+ errors.push('FileUpload "disabled" must be a boolean when provided.');
3297
+ }
3298
+ if (props.helperText !== void 0 && typeof props.helperText !== "string" && !(0, import_schema22.isVariableBinding)(props.helperText)) {
3299
+ errors.push('FileUpload "helperText" must be a string when provided.');
3300
+ }
3301
+ return errors.length > 0 ? errors : true;
3302
+ },
3303
+ defaultStyles: {
3304
+ base: {
3305
+ display: "flex",
3306
+ flexDirection: "column",
3307
+ gap: "8px",
3308
+ fontSize: "14px",
3309
+ color: "#1e293b"
3310
+ }
3311
+ }
3312
+ };
3313
+
3314
+ // src/definitions/interactive/modal.ts
3315
+ var modalDefinition = {
3316
+ type: "modal",
3317
+ label: "Modal",
3318
+ category: "interactive",
3319
+ icon: "layout",
3320
+ description: "Pop-up overlay dialog container with backdrop and close controls.",
3321
+ acceptsChildren: true,
3322
+ allowedChildren: ["*"],
3323
+ defaultProps: {
3324
+ modalId: "modal-dialog",
3325
+ title: "Modal Title",
3326
+ backdrop: true,
3327
+ closeOnBackdrop: true,
3328
+ closeOnEscape: true,
3329
+ size: "md",
3330
+ showCloseButton: true
3331
+ },
3332
+ propFields: [
3333
+ {
3334
+ name: "modalId",
3335
+ label: "Modal Target ID",
3336
+ type: "string",
3337
+ defaultValue: "modal-dialog",
3338
+ description: "Unique identifier targeted by open_modal and close_modal actions."
3339
+ },
3340
+ {
3341
+ name: "title",
3342
+ label: "Modal Title",
3343
+ type: "string",
3344
+ defaultValue: "Modal Title",
3345
+ description: "Header title text displayed at the top of the dialog."
3346
+ },
3347
+ {
3348
+ name: "size",
3349
+ label: "Size",
3350
+ type: "select",
3351
+ defaultValue: "md",
3352
+ options: [
3353
+ { label: "Small (400px)", value: "sm" },
3354
+ { label: "Medium (560px)", value: "md" },
3355
+ { label: "Large (768px)", value: "lg" },
3356
+ { label: "Full Screen", value: "fullscreen" }
3357
+ ]
3358
+ },
3359
+ {
3360
+ name: "backdrop",
3361
+ label: "Show Backdrop",
3362
+ type: "boolean",
3363
+ defaultValue: true
3364
+ },
3365
+ {
3366
+ name: "closeOnBackdrop",
3367
+ label: "Close on Backdrop Click",
3368
+ type: "boolean",
3369
+ defaultValue: true
3370
+ },
3371
+ {
3372
+ name: "closeOnEscape",
3373
+ label: "Close on Escape Key",
3374
+ type: "boolean",
3375
+ defaultValue: true
3376
+ },
3377
+ {
3378
+ name: "showCloseButton",
3379
+ label: "Show Close Button",
3380
+ type: "boolean",
3381
+ defaultValue: true
3382
+ }
3383
+ ],
3384
+ traits: [
3385
+ idTrait(),
3386
+ titleTrait(),
3387
+ ariaLabelTrait({ description: "Accessible name for the modal dialog." })
3388
+ ],
3389
+ defaultStyles: {
3390
+ base: {
3391
+ backgroundColor: "#ffffff",
3392
+ borderRadius: "12px",
3393
+ boxShadow: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
3394
+ padding: "24px",
3395
+ maxWidth: "560px",
3396
+ width: "100%"
3397
+ }
3398
+ }
3399
+ };
3400
+
3401
+ // src/definitions/interactive/drawer.ts
3402
+ var drawerDefinition = {
3403
+ type: "drawer",
3404
+ label: "Drawer",
3405
+ category: "interactive",
3406
+ icon: "sidebar",
3407
+ description: "Off-canvas slide-over panel container, ideal for mobile navigation and side sheets.",
3408
+ acceptsChildren: true,
3409
+ allowedChildren: ["*"],
3410
+ defaultProps: {
3411
+ modalId: "mobile-drawer",
3412
+ title: "Navigation Menu",
3413
+ placement: "right",
3414
+ backdrop: true,
3415
+ closeOnBackdrop: true,
3416
+ closeOnEscape: true,
3417
+ showCloseButton: true
3418
+ },
3419
+ propFields: [
3420
+ {
3421
+ name: "modalId",
3422
+ label: "Drawer Target ID",
3423
+ type: "string",
3424
+ defaultValue: "mobile-drawer",
3425
+ description: "Unique identifier targeted by open_modal and close_modal actions."
3426
+ },
3427
+ {
3428
+ name: "placement",
3429
+ label: "Placement",
3430
+ type: "select",
3431
+ defaultValue: "right",
3432
+ options: [
3433
+ { label: "Slide from Right", value: "right" },
3434
+ { label: "Slide from Left", value: "left" },
3435
+ { label: "Slide from Top (Dropdown)", value: "top" },
3436
+ { label: "Slide from Bottom", value: "bottom" }
3437
+ ]
3438
+ },
3439
+ {
3440
+ name: "title",
3441
+ label: "Drawer Title",
3442
+ type: "string",
3443
+ defaultValue: "Navigation Menu",
3444
+ description: "Header title text displayed at the top of the drawer."
3445
+ },
3446
+ {
3447
+ name: "backdrop",
3448
+ label: "Show Backdrop",
3449
+ type: "boolean",
3450
+ defaultValue: true
3451
+ },
3452
+ {
3453
+ name: "closeOnBackdrop",
3454
+ label: "Close on Backdrop Click",
3455
+ type: "boolean",
3456
+ defaultValue: true
3457
+ },
3458
+ {
3459
+ name: "closeOnEscape",
3460
+ label: "Close on Escape Key",
3461
+ type: "boolean",
3462
+ defaultValue: true
3463
+ },
3464
+ {
3465
+ name: "showCloseButton",
3466
+ label: "Show Close Button",
3467
+ type: "boolean",
3468
+ defaultValue: true
3469
+ }
3470
+ ],
3471
+ traits: [
3472
+ idTrait(),
3473
+ titleTrait(),
3474
+ ariaLabelTrait({ description: "Accessible name for the off-canvas drawer." })
3475
+ ],
3476
+ defaultStyles: {
3477
+ base: {
3478
+ backgroundColor: "#ffffff",
3479
+ boxShadow: "-4px 0 24px rgba(0, 0, 0, 0.15)",
3480
+ padding: "24px",
3481
+ width: "320px",
3482
+ maxWidth: "100%"
3483
+ },
3484
+ mobile: {
3485
+ width: "100%"
3486
+ }
3487
+ }
3488
+ };
3489
+
3490
+ // src/definitions/interactive/collapsible.ts
3491
+ var collapsibleDefinition = {
3492
+ type: "collapsible",
3493
+ label: "Collapsible",
3494
+ category: "interactive",
3495
+ icon: "chevron-down",
3496
+ description: "In-flow expandable container that toggles visibility without a fullscreen overlay.",
3497
+ acceptsChildren: true,
3498
+ allowedChildren: ["*"],
3499
+ defaultProps: {
3500
+ modalId: "collapsible-content",
3501
+ defaultOpen: false,
3502
+ animated: true
3503
+ },
3504
+ propFields: [
3505
+ {
3506
+ name: "modalId",
3507
+ label: "Target ID",
3508
+ type: "string",
3509
+ defaultValue: "collapsible-content",
3510
+ description: 'Identifier targeted by Open Modal (with "Toggle" enabled) or Close Modal actions.'
3511
+ },
3512
+ {
3513
+ name: "defaultOpen",
3514
+ label: "Default Open",
3515
+ type: "boolean",
3516
+ defaultValue: false,
3517
+ description: "Whether the collapsible container starts expanded on initial render."
3518
+ },
3519
+ {
3520
+ name: "animated",
3521
+ label: "Smooth Transition",
3522
+ type: "boolean",
3523
+ defaultValue: true
3524
+ }
3525
+ ],
3526
+ traits: [
3527
+ idTrait(),
3528
+ ariaLabelTrait({ description: "Accessible name for the collapsible container." })
3529
+ ],
3530
+ defaultStyles: {
3531
+ base: {
3532
+ width: "100%",
3533
+ overflow: "hidden"
3534
+ }
3535
+ }
3536
+ };
3537
+
3538
+ // src/definitions/index.ts
2290
3539
  var coreComponentDefinitions = [
2291
3540
  pageDefinition,
2292
3541
  sectionDefinition,
2293
3542
  containerDefinition,
2294
3543
  columnsDefinition,
3544
+ flexDefinition,
3545
+ gridDefinition,
2295
3546
  headingDefinition,
2296
3547
  textDefinition,
2297
3548
  paragraphDefinition,
@@ -2304,18 +3555,26 @@ var coreComponentDefinitions = [
2304
3555
  iconDefinition,
2305
3556
  htmlEmbedDefinition,
2306
3557
  buttonDefinition,
3558
+ buttonSubmitDefinition,
2307
3559
  formDefinition,
2308
3560
  inputDefinition,
2309
3561
  textareaDefinition,
2310
3562
  selectDefinition,
2311
3563
  checkboxDefinition,
3564
+ switchDefinition,
3565
+ radioGroupDefinition,
2312
3566
  radioDefinition,
3567
+ radioItemDefinition,
3568
+ fileUploadDefinition,
2313
3569
  collectionDefinition,
2314
3570
  listDefinition,
2315
3571
  listItemDefinition,
2316
3572
  tableDefinition,
2317
3573
  tableRowDefinition,
2318
- tableCellDefinition
3574
+ tableCellDefinition,
3575
+ modalDefinition,
3576
+ drawerDefinition,
3577
+ collapsibleDefinition
2319
3578
  ];
2320
3579
  function createDefaultComponentRegistry() {
2321
3580
  const registry = new ComponentRegistry();
@@ -2365,13 +3624,14 @@ function isBindableField(field) {
2365
3624
  return primitiveTypeForField(field) !== void 0;
2366
3625
  }
2367
3626
 
2368
- // src/blocks.ts
3627
+ // src/blocks/types.ts
2369
3628
  var nextId = 1;
2370
3629
  function defaultGenId(prefix = "node") {
2371
3630
  return `${prefix}-${Date.now().toString(36)}-${(nextId++).toString(36)}`;
2372
3631
  }
2373
- var STARTER_BLOCKS = [
2374
- // --- Layout Blocks (STORA-241) ---
3632
+
3633
+ // src/blocks/layout.ts
3634
+ var LAYOUT_STARTER_BLOCKS = [
2375
3635
  {
2376
3636
  id: "layout-1-col",
2377
3637
  name: "1 Column",
@@ -2531,39 +3791,384 @@ var STARTER_BLOCKS = [
2531
3791
  styles: { base: { display: "flex", gap: "16px", width: "100%", maxWidth: "1200px", margin: "0 auto" } },
2532
3792
  children: [
2533
3793
  {
2534
- id: gen("container"),
2535
- type: "container",
2536
- props: { tag: "div" },
2537
- styles: { base: { flex: "1 1 0%", minWidth: "0" } },
2538
- children: []
3794
+ id: gen("container"),
3795
+ type: "container",
3796
+ props: { tag: "div" },
3797
+ styles: { base: { flex: "1 1 0%", minWidth: "0" } },
3798
+ children: []
3799
+ },
3800
+ {
3801
+ id: gen("container"),
3802
+ type: "container",
3803
+ props: { tag: "div" },
3804
+ styles: { base: { flex: "1 1 0%", minWidth: "0" } },
3805
+ children: []
3806
+ },
3807
+ {
3808
+ id: gen("container"),
3809
+ type: "container",
3810
+ props: { tag: "div" },
3811
+ styles: { base: { flex: "1 1 0%", minWidth: "0" } },
3812
+ children: []
3813
+ },
3814
+ {
3815
+ id: gen("container"),
3816
+ type: "container",
3817
+ props: { tag: "div" },
3818
+ styles: { base: { flex: "1 1 0%", minWidth: "0" } },
3819
+ children: []
3820
+ }
3821
+ ]
3822
+ }
3823
+ ]
3824
+ })
3825
+ }
3826
+ ];
3827
+
3828
+ // src/blocks/sections.ts
3829
+ var UI_STARTER_BLOCKS = [
3830
+ {
3831
+ id: "navbar",
3832
+ name: "Navbar",
3833
+ category: "sections",
3834
+ categoryLabel: "Navigation & Headers",
3835
+ description: "Responsive top navigation bar with brand logo, nav links, CTA button, and mobile hamburger menu",
3836
+ icon: "layout",
3837
+ createNodeTree: (gen = defaultGenId) => ({
3838
+ id: gen("section"),
3839
+ type: "section",
3840
+ styles: {
3841
+ base: {
3842
+ paddingTop: "16px",
3843
+ paddingBottom: "16px",
3844
+ paddingLeft: "24px",
3845
+ paddingRight: "24px",
3846
+ backgroundColor: "#ffffff",
3847
+ borderBottom: "1px solid #e2e8f0",
3848
+ width: "100%"
3849
+ },
3850
+ mobile: {
3851
+ paddingLeft: "16px",
3852
+ paddingRight: "16px",
3853
+ paddingTop: "12px",
3854
+ paddingBottom: "12px"
3855
+ }
3856
+ },
3857
+ children: [
3858
+ {
3859
+ id: gen("container"),
3860
+ type: "container",
3861
+ props: { tag: "div" },
3862
+ styles: {
3863
+ base: {
3864
+ maxWidth: "1200px",
3865
+ margin: "0 auto",
3866
+ display: "flex",
3867
+ alignItems: "center",
3868
+ justifyContent: "space-between",
3869
+ width: "100%",
3870
+ flexWrap: "wrap"
3871
+ }
3872
+ },
3873
+ children: [
3874
+ // 1. Brand Logo
3875
+ {
3876
+ id: gen("heading"),
3877
+ type: "heading",
3878
+ props: { text: "Brand", level: 3 },
3879
+ styles: {
3880
+ base: {
3881
+ fontSize: "20px",
3882
+ fontWeight: "800",
3883
+ color: "#0f172a",
3884
+ margin: "0"
3885
+ }
3886
+ }
2539
3887
  },
3888
+ // 2. Desktop Navigation Links (hidden on mobile)
2540
3889
  {
2541
- id: gen("container"),
2542
- type: "container",
2543
- props: { tag: "div" },
2544
- styles: { base: { flex: "1 1 0%", minWidth: "0" } },
2545
- children: []
3890
+ id: gen("flex"),
3891
+ type: "flex",
3892
+ styles: {
3893
+ base: {
3894
+ display: "flex",
3895
+ flexDirection: "row",
3896
+ alignItems: "center",
3897
+ gap: "24px"
3898
+ },
3899
+ mobile: {
3900
+ display: "none"
3901
+ }
3902
+ },
3903
+ children: [
3904
+ {
3905
+ id: gen("link"),
3906
+ type: "link",
3907
+ props: { text: "Home", href: "#home" },
3908
+ styles: {
3909
+ base: {
3910
+ fontSize: "14px",
3911
+ fontWeight: "500",
3912
+ color: "#0f172a",
3913
+ textDecoration: "none"
3914
+ }
3915
+ }
3916
+ },
3917
+ {
3918
+ id: gen("link"),
3919
+ type: "link",
3920
+ props: { text: "Features", href: "#features" },
3921
+ styles: {
3922
+ base: {
3923
+ fontSize: "14px",
3924
+ fontWeight: "500",
3925
+ color: "#64748b",
3926
+ textDecoration: "none"
3927
+ }
3928
+ }
3929
+ },
3930
+ {
3931
+ id: gen("link"),
3932
+ type: "link",
3933
+ props: { text: "Pricing", href: "#pricing" },
3934
+ styles: {
3935
+ base: {
3936
+ fontSize: "14px",
3937
+ fontWeight: "500",
3938
+ color: "#64748b",
3939
+ textDecoration: "none"
3940
+ }
3941
+ }
3942
+ },
3943
+ {
3944
+ id: gen("link"),
3945
+ type: "link",
3946
+ props: { text: "About", href: "#about" },
3947
+ styles: {
3948
+ base: {
3949
+ fontSize: "14px",
3950
+ fontWeight: "500",
3951
+ color: "#64748b",
3952
+ textDecoration: "none"
3953
+ }
3954
+ }
3955
+ }
3956
+ ]
2546
3957
  },
3958
+ // 3. Desktop CTA Buttons (hidden on mobile)
2547
3959
  {
2548
- id: gen("container"),
2549
- type: "container",
2550
- props: { tag: "div" },
2551
- styles: { base: { flex: "1 1 0%", minWidth: "0" } },
2552
- children: []
3960
+ id: gen("flex"),
3961
+ type: "flex",
3962
+ styles: {
3963
+ base: {
3964
+ display: "flex",
3965
+ flexDirection: "row",
3966
+ alignItems: "center",
3967
+ gap: "12px"
3968
+ },
3969
+ mobile: {
3970
+ display: "none"
3971
+ }
3972
+ },
3973
+ children: [
3974
+ {
3975
+ id: gen("link"),
3976
+ type: "link",
3977
+ props: { text: "Sign In", href: "#signin" },
3978
+ styles: {
3979
+ base: {
3980
+ fontSize: "14px",
3981
+ fontWeight: "500",
3982
+ color: "#475569",
3983
+ textDecoration: "none",
3984
+ padding: "8px 12px"
3985
+ }
3986
+ }
3987
+ },
3988
+ {
3989
+ id: gen("button"),
3990
+ type: "button",
3991
+ props: { label: "Get Started", href: "#signup" },
3992
+ styles: {
3993
+ base: {
3994
+ backgroundColor: "#2563eb",
3995
+ color: "#ffffff",
3996
+ padding: "8px 18px",
3997
+ borderRadius: "8px",
3998
+ fontSize: "14px",
3999
+ fontWeight: "600",
4000
+ display: "inline-block"
4001
+ },
4002
+ states: {
4003
+ ":hover": { backgroundColor: "#1d4ed8" }
4004
+ }
4005
+ }
4006
+ }
4007
+ ]
2553
4008
  },
4009
+ // 4. Mobile Hamburger Button (hidden on desktop, visible on mobile)
2554
4010
  {
2555
- id: gen("container"),
2556
- type: "container",
2557
- props: { tag: "div" },
2558
- styles: { base: { flex: "1 1 0%", minWidth: "0" } },
2559
- children: []
4011
+ id: gen("button"),
4012
+ type: "button",
4013
+ props: {
4014
+ label: "\u2630",
4015
+ activeLabel: "\u2715",
4016
+ isEditable: false,
4017
+ modalId: "mobile-nav-drawer",
4018
+ ariaLabel: "Toggle navigation menu",
4019
+ variant: "secondary"
4020
+ },
4021
+ styles: {
4022
+ base: {
4023
+ display: "none"
4024
+ },
4025
+ mobile: {
4026
+ display: "inline-flex",
4027
+ alignItems: "center",
4028
+ justifyContent: "center",
4029
+ padding: "6px 12px",
4030
+ fontSize: "18px",
4031
+ backgroundColor: "#f8fafc",
4032
+ border: "1px solid #e2e8f0",
4033
+ borderRadius: "6px",
4034
+ color: "#0f172a",
4035
+ cursor: "pointer"
4036
+ }
4037
+ },
4038
+ actions: [
4039
+ {
4040
+ id: gen("pipeline"),
4041
+ trigger: "click",
4042
+ label: "Toggle Mobile Menu",
4043
+ enabled: true,
4044
+ steps: [
4045
+ {
4046
+ id: gen("step"),
4047
+ type: "open_modal",
4048
+ label: "Toggle Navigation Drawer",
4049
+ payload: {
4050
+ modalId: "mobile-nav-drawer",
4051
+ toggle: true
4052
+ }
4053
+ }
4054
+ ]
4055
+ }
4056
+ ]
4057
+ },
4058
+ // 5. Mobile Navigation Dropdown (hidden on desktop, stacked on mobile)
4059
+ // A `collapsible`, not a plain flex: this is an in-flow disclosure that expands
4060
+ // inside the navbar (its width/border styles depend on staying there), so it must
4061
+ // not be treated as a floating overlay. The dedicated renderer also keeps it
4062
+ // visible while editing, so the menu's links stay reachable on the canvas, and
4063
+ // only honours the open/closed state at runtime.
4064
+ {
4065
+ id: gen("collapsible"),
4066
+ type: "collapsible",
4067
+ props: {
4068
+ modalId: "mobile-nav-drawer",
4069
+ ariaLabel: "Mobile navigation menu",
4070
+ defaultOpen: false,
4071
+ animated: true
4072
+ },
4073
+ styles: {
4074
+ base: {
4075
+ display: "none"
4076
+ },
4077
+ mobile: {
4078
+ display: "flex",
4079
+ flexDirection: "column",
4080
+ width: "100%",
4081
+ gap: "8px",
4082
+ paddingTop: "16px",
4083
+ marginTop: "12px",
4084
+ borderTop: "1px solid #f1f5f9"
4085
+ }
4086
+ },
4087
+ children: [
4088
+ {
4089
+ id: gen("link"),
4090
+ type: "link",
4091
+ props: { text: "Home", href: "#home" },
4092
+ styles: {
4093
+ base: {
4094
+ fontSize: "14px",
4095
+ fontWeight: "500",
4096
+ color: "#0f172a",
4097
+ textDecoration: "none",
4098
+ padding: "6px 0"
4099
+ }
4100
+ }
4101
+ },
4102
+ {
4103
+ id: gen("link"),
4104
+ type: "link",
4105
+ props: { text: "Features", href: "#features" },
4106
+ styles: {
4107
+ base: {
4108
+ fontSize: "14px",
4109
+ fontWeight: "500",
4110
+ color: "#64748b",
4111
+ textDecoration: "none",
4112
+ padding: "6px 0"
4113
+ }
4114
+ }
4115
+ },
4116
+ {
4117
+ id: gen("link"),
4118
+ type: "link",
4119
+ props: { text: "Pricing", href: "#pricing" },
4120
+ styles: {
4121
+ base: {
4122
+ fontSize: "14px",
4123
+ fontWeight: "500",
4124
+ color: "#64748b",
4125
+ textDecoration: "none",
4126
+ padding: "6px 0"
4127
+ }
4128
+ }
4129
+ },
4130
+ {
4131
+ id: gen("link"),
4132
+ type: "link",
4133
+ props: { text: "About", href: "#about" },
4134
+ styles: {
4135
+ base: {
4136
+ fontSize: "14px",
4137
+ fontWeight: "500",
4138
+ color: "#64748b",
4139
+ textDecoration: "none",
4140
+ padding: "6px 0"
4141
+ }
4142
+ }
4143
+ },
4144
+ {
4145
+ id: gen("button"),
4146
+ type: "button",
4147
+ props: { label: "Get Started", href: "#signup" },
4148
+ styles: {
4149
+ base: {
4150
+ backgroundColor: "#2563eb",
4151
+ color: "#ffffff",
4152
+ padding: "10px 16px",
4153
+ borderRadius: "8px",
4154
+ fontSize: "14px",
4155
+ fontWeight: "600",
4156
+ textAlign: "center",
4157
+ display: "block",
4158
+ marginTop: "8px"
4159
+ },
4160
+ states: {
4161
+ ":hover": { backgroundColor: "#1d4ed8" }
4162
+ }
4163
+ }
4164
+ }
4165
+ ]
2560
4166
  }
2561
4167
  ]
2562
4168
  }
2563
4169
  ]
2564
4170
  })
2565
4171
  },
2566
- // --- Pre-composed UI Blocks (STORA-242) ---
2567
4172
  {
2568
4173
  id: "hero-section",
2569
4174
  name: "Hero Section",
@@ -2882,25 +4487,794 @@ var STARTER_BLOCKS = [
2882
4487
  })
2883
4488
  }
2884
4489
  ];
4490
+
4491
+ // src/blocks/forms.ts
4492
+ var FORM_STARTER_BLOCKS = [
4493
+ {
4494
+ id: "form-contact-us",
4495
+ name: "Contact Us Form",
4496
+ category: "forms",
4497
+ categoryLabel: "Form Templates",
4498
+ description: "Contact form with Name, Email, Subject, Message, and submit action pipeline with API request and toast notifications",
4499
+ icon: "form",
4500
+ createNodeTree: (gen = defaultGenId) => ({
4501
+ id: gen("section"),
4502
+ type: "section",
4503
+ styles: {
4504
+ base: {
4505
+ padding: "64px 20px",
4506
+ backgroundColor: "#f8fafc",
4507
+ width: "100%"
4508
+ }
4509
+ },
4510
+ children: [
4511
+ {
4512
+ id: gen("container"),
4513
+ type: "container",
4514
+ props: { tag: "div", maxWidth: "640px" },
4515
+ styles: {
4516
+ base: {
4517
+ maxWidth: "640px",
4518
+ margin: "0 auto",
4519
+ width: "100%",
4520
+ backgroundColor: "#ffffff",
4521
+ padding: "36px",
4522
+ borderRadius: "16px",
4523
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05)",
4524
+ border: "1px solid #e2e8f0"
4525
+ }
4526
+ },
4527
+ children: [
4528
+ {
4529
+ id: gen("heading"),
4530
+ type: "heading",
4531
+ props: { text: "Contact Us", level: 2 },
4532
+ styles: {
4533
+ base: {
4534
+ fontSize: "28px",
4535
+ fontWeight: "700",
4536
+ color: "#0f172a",
4537
+ marginBottom: "8px",
4538
+ textAlign: "center"
4539
+ }
4540
+ }
4541
+ },
4542
+ {
4543
+ id: gen("paragraph"),
4544
+ type: "paragraph",
4545
+ props: {
4546
+ content: "Have questions or need assistance? Fill out the form below and we will get back to you shortly."
4547
+ },
4548
+ styles: {
4549
+ base: {
4550
+ fontSize: "15px",
4551
+ color: "#64748b",
4552
+ marginBottom: "28px",
4553
+ textAlign: "center",
4554
+ lineHeight: "1.5"
4555
+ }
4556
+ }
4557
+ },
4558
+ {
4559
+ id: gen("form"),
4560
+ type: "form",
4561
+ props: {
4562
+ name: "contact_us_form",
4563
+ method: "POST",
4564
+ preventDefault: true,
4565
+ scrollToFirstError: true,
4566
+ resetOnSubmit: true
4567
+ },
4568
+ styles: {
4569
+ base: {
4570
+ display: "flex",
4571
+ flexDirection: "column",
4572
+ gap: "20px",
4573
+ width: "100%"
4574
+ }
4575
+ },
4576
+ actions: [
4577
+ {
4578
+ id: gen("pipeline"),
4579
+ trigger: "submit",
4580
+ label: "Submit Contact Form",
4581
+ enabled: true,
4582
+ steps: [
4583
+ {
4584
+ id: gen("step"),
4585
+ type: "api_request",
4586
+ label: "Send Contact Message",
4587
+ payload: {
4588
+ url: "/api/mock/submit-lead",
4589
+ method: "POST",
4590
+ bodyFormat: "json"
4591
+ },
4592
+ onSuccess: [
4593
+ {
4594
+ id: gen("step"),
4595
+ type: "show_toast",
4596
+ label: "Show Success Toast",
4597
+ payload: {
4598
+ message: "Thank you! Your message has been sent successfully.",
4599
+ type: "success",
4600
+ title: "Message Sent",
4601
+ duration: 4e3
4602
+ }
4603
+ },
4604
+ {
4605
+ id: gen("step"),
4606
+ type: "reset_form",
4607
+ label: "Reset Form",
4608
+ payload: {}
4609
+ }
4610
+ ],
4611
+ onError: [
4612
+ {
4613
+ id: gen("step"),
4614
+ type: "show_toast",
4615
+ label: "Show Error Toast",
4616
+ payload: {
4617
+ message: "Failed to send message. Please check your connection and try again.",
4618
+ type: "error",
4619
+ title: "Submission Failed",
4620
+ duration: 5e3
4621
+ }
4622
+ }
4623
+ ]
4624
+ }
4625
+ ]
4626
+ }
4627
+ ],
4628
+ children: [
4629
+ {
4630
+ id: gen("input"),
4631
+ type: "input",
4632
+ props: {
4633
+ name: "name",
4634
+ label: "Your Name",
4635
+ type: "text",
4636
+ placeholder: "Jane Doe",
4637
+ required: true,
4638
+ rules: [
4639
+ { type: "required", message: "Please enter your name" },
4640
+ { type: "min_length", value: 2, message: "Name must be at least 2 characters" }
4641
+ ]
4642
+ },
4643
+ styles: {
4644
+ base: {
4645
+ width: "100%",
4646
+ padding: "10px 14px",
4647
+ borderRadius: "8px",
4648
+ border: "1px solid #cbd5e1",
4649
+ fontSize: "14px"
4650
+ }
4651
+ }
4652
+ },
4653
+ {
4654
+ id: gen("input"),
4655
+ type: "input",
4656
+ props: {
4657
+ name: "email",
4658
+ label: "Email Address",
4659
+ type: "email",
4660
+ placeholder: "jane@example.com",
4661
+ required: true,
4662
+ rules: [
4663
+ { type: "required", message: "Please enter your email" },
4664
+ { type: "email", message: "Please enter a valid email address" }
4665
+ ]
4666
+ },
4667
+ styles: {
4668
+ base: {
4669
+ width: "100%",
4670
+ padding: "10px 14px",
4671
+ borderRadius: "8px",
4672
+ border: "1px solid #cbd5e1",
4673
+ fontSize: "14px"
4674
+ }
4675
+ }
4676
+ },
4677
+ {
4678
+ id: gen("input"),
4679
+ type: "input",
4680
+ props: {
4681
+ name: "subject",
4682
+ label: "Subject",
4683
+ type: "text",
4684
+ placeholder: "How can we help you?",
4685
+ required: true,
4686
+ rules: [
4687
+ { type: "required", message: "Please enter a subject" }
4688
+ ]
4689
+ },
4690
+ styles: {
4691
+ base: {
4692
+ width: "100%",
4693
+ padding: "10px 14px",
4694
+ borderRadius: "8px",
4695
+ border: "1px solid #cbd5e1",
4696
+ fontSize: "14px"
4697
+ }
4698
+ }
4699
+ },
4700
+ {
4701
+ id: gen("textarea"),
4702
+ type: "textarea",
4703
+ props: {
4704
+ name: "message",
4705
+ label: "Message",
4706
+ placeholder: "Write your message here...",
4707
+ rows: 4,
4708
+ required: true,
4709
+ rules: [
4710
+ { type: "required", message: "Please enter your message" },
4711
+ { type: "min_length", value: 10, message: "Message must be at least 10 characters" }
4712
+ ]
4713
+ },
4714
+ styles: {
4715
+ base: {
4716
+ width: "100%",
4717
+ padding: "10px 14px",
4718
+ borderRadius: "8px",
4719
+ border: "1px solid #cbd5e1",
4720
+ fontSize: "14px"
4721
+ }
4722
+ }
4723
+ },
4724
+ {
4725
+ id: gen("button"),
4726
+ type: "button",
4727
+ props: {
4728
+ label: "Send Message",
4729
+ variant: "primary",
4730
+ buttonType: "submit"
4731
+ },
4732
+ styles: {
4733
+ base: {
4734
+ width: "100%",
4735
+ backgroundColor: "#2563eb",
4736
+ color: "#ffffff",
4737
+ padding: "12px",
4738
+ borderRadius: "8px",
4739
+ fontWeight: "600",
4740
+ fontSize: "15px",
4741
+ display: "inline-block",
4742
+ textAlign: "center"
4743
+ },
4744
+ states: {
4745
+ ":hover": { backgroundColor: "#1d4ed8" }
4746
+ }
4747
+ }
4748
+ }
4749
+ ]
4750
+ }
4751
+ ]
4752
+ }
4753
+ ]
4754
+ })
4755
+ },
4756
+ {
4757
+ id: "form-newsletter",
4758
+ name: "Newsletter Subscribe Form",
4759
+ category: "forms",
4760
+ categoryLabel: "Form Templates",
4761
+ description: "Inline email newsletter subscription form with real-time feedback",
4762
+ icon: "mail",
4763
+ createNodeTree: (gen = defaultGenId) => ({
4764
+ id: gen("section"),
4765
+ type: "section",
4766
+ styles: {
4767
+ base: {
4768
+ padding: "48px 20px",
4769
+ backgroundColor: "#f1f5f9",
4770
+ width: "100%"
4771
+ }
4772
+ },
4773
+ children: [
4774
+ {
4775
+ id: gen("container"),
4776
+ type: "container",
4777
+ props: { tag: "div", maxWidth: "580px" },
4778
+ styles: {
4779
+ base: {
4780
+ maxWidth: "580px",
4781
+ margin: "0 auto",
4782
+ width: "100%",
4783
+ textAlign: "center"
4784
+ }
4785
+ },
4786
+ children: [
4787
+ {
4788
+ id: gen("heading"),
4789
+ type: "heading",
4790
+ props: { text: "Stay in the Loop", level: 3 },
4791
+ styles: {
4792
+ base: {
4793
+ fontSize: "26px",
4794
+ fontWeight: "700",
4795
+ color: "#0f172a",
4796
+ marginBottom: "8px"
4797
+ }
4798
+ }
4799
+ },
4800
+ {
4801
+ id: gen("paragraph"),
4802
+ type: "paragraph",
4803
+ props: {
4804
+ content: "Subscribe to our newsletter for weekly curated insights, updates, and best practices."
4805
+ },
4806
+ styles: {
4807
+ base: {
4808
+ fontSize: "15px",
4809
+ color: "#64748b",
4810
+ marginBottom: "24px",
4811
+ lineHeight: "1.5"
4812
+ }
4813
+ }
4814
+ },
4815
+ {
4816
+ id: gen("form"),
4817
+ type: "form",
4818
+ props: {
4819
+ name: "newsletter_form",
4820
+ method: "POST",
4821
+ preventDefault: true,
4822
+ resetOnSubmit: true
4823
+ },
4824
+ styles: {
4825
+ base: {
4826
+ display: "flex",
4827
+ flexDirection: "row",
4828
+ gap: "8px",
4829
+ alignItems: "center",
4830
+ width: "100%"
4831
+ },
4832
+ mobile: {
4833
+ flexDirection: "column"
4834
+ }
4835
+ },
4836
+ actions: [
4837
+ {
4838
+ id: gen("pipeline"),
4839
+ trigger: "submit",
4840
+ label: "Subscribe to Newsletter",
4841
+ enabled: true,
4842
+ steps: [
4843
+ {
4844
+ id: gen("step"),
4845
+ type: "api_request",
4846
+ label: "Submit Subscription",
4847
+ payload: {
4848
+ url: "/api/mock/submit-lead",
4849
+ method: "POST",
4850
+ bodyFormat: "json"
4851
+ },
4852
+ onSuccess: [
4853
+ {
4854
+ id: gen("step"),
4855
+ type: "show_toast",
4856
+ label: "Show Success Toast",
4857
+ payload: {
4858
+ message: "Thank you for subscribing to our newsletter!",
4859
+ type: "success",
4860
+ title: "Subscription Confirmed",
4861
+ duration: 4e3
4862
+ }
4863
+ },
4864
+ {
4865
+ id: gen("step"),
4866
+ type: "reset_form",
4867
+ label: "Reset Form",
4868
+ payload: {}
4869
+ }
4870
+ ],
4871
+ onError: [
4872
+ {
4873
+ id: gen("step"),
4874
+ type: "show_toast",
4875
+ label: "Show Error Toast",
4876
+ payload: {
4877
+ message: "Unable to subscribe right now. Please try again later.",
4878
+ type: "error",
4879
+ title: "Error",
4880
+ duration: 5e3
4881
+ }
4882
+ }
4883
+ ]
4884
+ }
4885
+ ]
4886
+ }
4887
+ ],
4888
+ children: [
4889
+ {
4890
+ id: gen("input"),
4891
+ type: "input",
4892
+ props: {
4893
+ name: "email",
4894
+ type: "email",
4895
+ placeholder: "Enter your email address...",
4896
+ required: true,
4897
+ rules: [
4898
+ { type: "required", message: "Email address is required" },
4899
+ { type: "email", message: "Please enter a valid email address" }
4900
+ ]
4901
+ },
4902
+ styles: {
4903
+ base: {
4904
+ flex: "1 1 0%",
4905
+ minWidth: "0",
4906
+ padding: "12px 16px",
4907
+ borderRadius: "8px",
4908
+ border: "1px solid #cbd5e1",
4909
+ backgroundColor: "#ffffff",
4910
+ fontSize: "14px"
4911
+ }
4912
+ }
4913
+ },
4914
+ {
4915
+ id: gen("button"),
4916
+ type: "button",
4917
+ props: {
4918
+ label: "Subscribe",
4919
+ variant: "primary",
4920
+ buttonType: "submit"
4921
+ },
4922
+ styles: {
4923
+ base: {
4924
+ backgroundColor: "#2563eb",
4925
+ color: "#ffffff",
4926
+ padding: "12px 24px",
4927
+ borderRadius: "8px",
4928
+ fontWeight: "600",
4929
+ fontSize: "14px",
4930
+ whiteSpace: "nowrap"
4931
+ },
4932
+ states: {
4933
+ ":hover": { backgroundColor: "#1d4ed8" }
4934
+ }
4935
+ }
4936
+ }
4937
+ ]
4938
+ }
4939
+ ]
4940
+ }
4941
+ ]
4942
+ })
4943
+ },
4944
+ {
4945
+ id: "form-lead-gen",
4946
+ name: "Lead Generation Form",
4947
+ category: "forms",
4948
+ categoryLabel: "Form Templates",
4949
+ description: "Multi-field lead generation form with phone validation, interest dropdown, and API submission pipeline",
4950
+ icon: "users",
4951
+ createNodeTree: (gen = defaultGenId) => ({
4952
+ id: gen("section"),
4953
+ type: "section",
4954
+ styles: {
4955
+ base: {
4956
+ padding: "64px 20px",
4957
+ backgroundColor: "#ffffff",
4958
+ width: "100%"
4959
+ }
4960
+ },
4961
+ children: [
4962
+ {
4963
+ id: gen("container"),
4964
+ type: "container",
4965
+ props: { tag: "div", maxWidth: "640px" },
4966
+ styles: {
4967
+ base: {
4968
+ maxWidth: "640px",
4969
+ margin: "0 auto",
4970
+ width: "100%",
4971
+ backgroundColor: "#ffffff",
4972
+ padding: "36px",
4973
+ borderRadius: "16px",
4974
+ border: "1px solid #e2e8f0",
4975
+ boxShadow: "0 10px 25px -5px rgba(0, 0, 0, 0.05)"
4976
+ }
4977
+ },
4978
+ children: [
4979
+ {
4980
+ id: gen("badge"),
4981
+ type: "badge",
4982
+ props: { label: "FREE CONSULTATION", variant: "primary" },
4983
+ styles: { base: { marginBottom: "12px", display: "inline-block" } }
4984
+ },
4985
+ {
4986
+ id: gen("heading"),
4987
+ type: "heading",
4988
+ props: { text: "Schedule a Consultation", level: 2 },
4989
+ styles: {
4990
+ base: {
4991
+ fontSize: "28px",
4992
+ fontWeight: "700",
4993
+ color: "#0f172a",
4994
+ marginBottom: "8px"
4995
+ }
4996
+ }
4997
+ },
4998
+ {
4999
+ id: gen("paragraph"),
5000
+ type: "paragraph",
5001
+ props: {
5002
+ content: "Share your project details with our solutions team. We will analyze your needs and provide a personalized roadmap."
5003
+ },
5004
+ styles: {
5005
+ base: {
5006
+ fontSize: "15px",
5007
+ color: "#64748b",
5008
+ marginBottom: "28px",
5009
+ lineHeight: "1.5"
5010
+ }
5011
+ }
5012
+ },
5013
+ {
5014
+ id: gen("form"),
5015
+ type: "form",
5016
+ props: {
5017
+ name: "lead_generation_form",
5018
+ method: "POST",
5019
+ preventDefault: true,
5020
+ scrollToFirstError: true,
5021
+ resetOnSubmit: true
5022
+ },
5023
+ styles: {
5024
+ base: {
5025
+ display: "flex",
5026
+ flexDirection: "column",
5027
+ gap: "18px",
5028
+ width: "100%"
5029
+ }
5030
+ },
5031
+ actions: [
5032
+ {
5033
+ id: gen("pipeline"),
5034
+ trigger: "submit",
5035
+ label: "Submit Lead Form",
5036
+ enabled: true,
5037
+ steps: [
5038
+ {
5039
+ id: gen("step"),
5040
+ type: "api_request",
5041
+ label: "Send Lead Data",
5042
+ payload: {
5043
+ url: "/api/mock/submit-lead",
5044
+ method: "POST",
5045
+ bodyFormat: "json"
5046
+ },
5047
+ onSuccess: [
5048
+ {
5049
+ id: gen("step"),
5050
+ type: "show_toast",
5051
+ label: "Show Success Toast",
5052
+ payload: {
5053
+ message: "Thank you! Your request has been received. Our team will contact you shortly.",
5054
+ type: "success",
5055
+ title: "Request Submitted",
5056
+ duration: 4e3
5057
+ }
5058
+ },
5059
+ {
5060
+ id: gen("step"),
5061
+ type: "reset_form",
5062
+ label: "Reset Form",
5063
+ payload: {}
5064
+ }
5065
+ ],
5066
+ onError: [
5067
+ {
5068
+ id: gen("step"),
5069
+ type: "show_toast",
5070
+ label: "Show Error Toast",
5071
+ payload: {
5072
+ message: "Submission failed. Please verify your information and try again.",
5073
+ type: "error",
5074
+ title: "Submission Error",
5075
+ duration: 5e3
5076
+ }
5077
+ }
5078
+ ]
5079
+ }
5080
+ ]
5081
+ }
5082
+ ],
5083
+ children: [
5084
+ {
5085
+ id: gen("input"),
5086
+ type: "input",
5087
+ props: {
5088
+ name: "full_name",
5089
+ label: "Full Name",
5090
+ type: "text",
5091
+ placeholder: "Alex Morgan",
5092
+ required: true,
5093
+ rules: [
5094
+ { type: "required", message: "Full name is required" },
5095
+ { type: "min_length", value: 2, message: "Name must be at least 2 characters" }
5096
+ ]
5097
+ },
5098
+ styles: {
5099
+ base: {
5100
+ width: "100%",
5101
+ padding: "10px 14px",
5102
+ borderRadius: "8px",
5103
+ border: "1px solid #cbd5e1",
5104
+ fontSize: "14px"
5105
+ }
5106
+ }
5107
+ },
5108
+ {
5109
+ id: gen("input"),
5110
+ type: "input",
5111
+ props: {
5112
+ name: "email",
5113
+ label: "Business Email",
5114
+ type: "email",
5115
+ placeholder: "alex@company.com",
5116
+ required: true,
5117
+ rules: [
5118
+ { type: "required", message: "Business email is required" },
5119
+ { type: "email", message: "Please enter a valid email address" }
5120
+ ]
5121
+ },
5122
+ styles: {
5123
+ base: {
5124
+ width: "100%",
5125
+ padding: "10px 14px",
5126
+ borderRadius: "8px",
5127
+ border: "1px solid #cbd5e1",
5128
+ fontSize: "14px"
5129
+ }
5130
+ }
5131
+ },
5132
+ {
5133
+ id: gen("input"),
5134
+ type: "input",
5135
+ props: {
5136
+ name: "phone",
5137
+ label: "Phone Number",
5138
+ type: "tel",
5139
+ placeholder: "+62 812-3456-7890",
5140
+ required: true,
5141
+ rules: [
5142
+ { type: "required", message: "Phone number is required" },
5143
+ {
5144
+ type: "custom_regex",
5145
+ value: "^[+]?[0-9\\s-()]{8,20}$",
5146
+ message: "Please enter a valid phone number (min 8 digits)"
5147
+ }
5148
+ ]
5149
+ },
5150
+ styles: {
5151
+ base: {
5152
+ width: "100%",
5153
+ padding: "10px 14px",
5154
+ borderRadius: "8px",
5155
+ border: "1px solid #cbd5e1",
5156
+ fontSize: "14px"
5157
+ }
5158
+ }
5159
+ },
5160
+ {
5161
+ id: gen("select"),
5162
+ type: "select",
5163
+ props: {
5164
+ name: "interest",
5165
+ label: "Area of Interest",
5166
+ placeholder: "Select your interest / service...",
5167
+ required: true,
5168
+ defaultValue: "",
5169
+ options: [
5170
+ { label: "Web Platform Development", value: "web_platform" },
5171
+ { label: "Mobile Application", value: "mobile_app" },
5172
+ { label: "Cloud Architecture & DevOps", value: "cloud_devops" },
5173
+ { label: "UI/UX Product Design", value: "product_design" },
5174
+ { label: "General Inquiry", value: "general" }
5175
+ ],
5176
+ rules: [
5177
+ { type: "required", message: "Please select an area of interest" }
5178
+ ]
5179
+ },
5180
+ styles: {
5181
+ base: {
5182
+ width: "100%",
5183
+ padding: "10px 14px",
5184
+ borderRadius: "8px",
5185
+ border: "1px solid #cbd5e1",
5186
+ fontSize: "14px",
5187
+ backgroundColor: "#ffffff"
5188
+ }
5189
+ }
5190
+ },
5191
+ {
5192
+ id: gen("input"),
5193
+ type: "input",
5194
+ props: {
5195
+ name: "company",
5196
+ label: "Company Name (Optional)",
5197
+ type: "text",
5198
+ placeholder: "Company / Organization"
5199
+ },
5200
+ styles: {
5201
+ base: {
5202
+ width: "100%",
5203
+ padding: "10px 14px",
5204
+ borderRadius: "8px",
5205
+ border: "1px solid #cbd5e1",
5206
+ fontSize: "14px"
5207
+ }
5208
+ }
5209
+ },
5210
+ {
5211
+ id: gen("button"),
5212
+ type: "button",
5213
+ props: {
5214
+ label: "Request Consultation",
5215
+ variant: "primary",
5216
+ buttonType: "submit"
5217
+ },
5218
+ styles: {
5219
+ base: {
5220
+ width: "100%",
5221
+ backgroundColor: "#2563eb",
5222
+ color: "#ffffff",
5223
+ padding: "12px 24px",
5224
+ borderRadius: "8px",
5225
+ fontWeight: "600",
5226
+ fontSize: "15px",
5227
+ marginTop: "4px"
5228
+ },
5229
+ states: {
5230
+ ":hover": { backgroundColor: "#1d4ed8" }
5231
+ }
5232
+ }
5233
+ }
5234
+ ]
5235
+ }
5236
+ ]
5237
+ }
5238
+ ]
5239
+ })
5240
+ }
5241
+ ];
5242
+
5243
+ // src/blocks/index.ts
5244
+ var STARTER_BLOCKS = [
5245
+ ...LAYOUT_STARTER_BLOCKS,
5246
+ ...UI_STARTER_BLOCKS,
5247
+ ...FORM_STARTER_BLOCKS
5248
+ ];
2885
5249
  // Annotate the CommonJS export names for ESM import in node:
2886
5250
  0 && (module.exports = {
5251
+ CONTENT_CHILD_TYPES,
2887
5252
  ComponentRegistry,
5253
+ FORM_STARTER_BLOCKS,
5254
+ LAYOUT_PARENTS,
5255
+ LAYOUT_STARTER_BLOCKS,
2888
5256
  STARTER_BLOCKS,
2889
5257
  TRAIT_GROUP_LABELS,
2890
5258
  TRAIT_GROUP_ORDER,
5259
+ UI_STARTER_BLOCKS,
5260
+ acceptTrait,
2891
5261
  actionTrait,
2892
5262
  altTrait,
2893
5263
  ariaLabelTrait,
2894
5264
  autoCompleteTrait,
5265
+ autoDisableOnSubmitTrait,
5266
+ autoGrowTrait,
2895
5267
  autoplayTrait,
2896
5268
  badgeDefinition,
2897
5269
  blockquoteDefinition,
2898
5270
  buttonDefinition,
5271
+ buttonSubmitDefinition,
2899
5272
  buttonTypeTrait,
2900
5273
  checkboxDefinition,
2901
5274
  citeTrait,
2902
5275
  codeBlockDefinition,
2903
5276
  colSpanTrait,
5277
+ collapsibleDefinition,
2904
5278
  collectTraitNames,
2905
5279
  collectionDefinition,
2906
5280
  columnsDefinition,
@@ -2909,42 +5283,73 @@ var STARTER_BLOCKS = [
2909
5283
  coreComponentDefinitions,
2910
5284
  createDefaultComponentRegistry,
2911
5285
  defaultCheckedTrait,
5286
+ defaultGenId,
5287
+ defaultSelectedTrait,
2912
5288
  defaultValueTrait,
2913
5289
  disabledTrait,
5290
+ drawerDefinition,
2914
5291
  extractComponentRequirements,
2915
5292
  fieldNameTrait,
5293
+ fileUploadDefinition,
5294
+ flexDefinition,
2916
5295
  formDefinition,
5296
+ gridDefinition,
2917
5297
  headingDefinition,
5298
+ helperTextTrait,
2918
5299
  hrefTrait,
2919
5300
  htmlEmbedDefinition,
2920
5301
  iconDefinition,
2921
5302
  idTrait,
2922
5303
  imageDefinition,
5304
+ indeterminateTrait,
2923
5305
  inputDefinition,
2924
5306
  inputTypeTrait,
2925
5307
  isBindableField,
5308
+ labelTextTrait,
2926
5309
  linkDefinition,
2927
5310
  listDefinition,
2928
5311
  listItemDefinition,
5312
+ loadingTextTrait,
2929
5313
  loadingTrait,
2930
5314
  loopTrait,
5315
+ maxCharCountTrait,
5316
+ maxFileSizeTrait,
5317
+ maxLengthTrait,
2931
5318
  methodTrait,
5319
+ minLengthTrait,
5320
+ modalDefinition,
5321
+ multipleTrait,
2932
5322
  mutedTrait,
5323
+ optionsListTrait,
5324
+ orientationTrait,
2933
5325
  pageDefinition,
2934
5326
  paragraphDefinition,
5327
+ patternTrait,
2935
5328
  placeholderTrait,
2936
5329
  posterTrait,
5330
+ prefixIconTrait,
5331
+ preventDefaultTrait,
2937
5332
  primitiveTypeForField,
2938
5333
  radioDefinition,
5334
+ radioGroupDefinition,
5335
+ radioItemDefinition,
2939
5336
  readOnlyTrait,
2940
5337
  relTrait,
2941
5338
  requiredTrait,
5339
+ resetOnSubmitTrait,
5340
+ resizeTrait,
2942
5341
  rowSpanTrait,
2943
5342
  rowsTrait,
5343
+ scrollToFirstErrorTrait,
2944
5344
  sectionDefinition,
2945
5345
  selectDefinition,
5346
+ showPreviewTrait,
5347
+ showSpinnerTrait,
2946
5348
  sortTraits,
2947
5349
  srcTrait,
5350
+ suffixIconTrait,
5351
+ switchDefinition,
5352
+ switchSizeTrait,
2948
5353
  tableCellDefinition,
2949
5354
  tableDefinition,
2950
5355
  tableRowDefinition,
@@ -2954,6 +5359,7 @@ var STARTER_BLOCKS = [
2954
5359
  textareaDefinition,
2955
5360
  titleTrait,
2956
5361
  valueTrait,
2957
- videoDefinition
5362
+ videoDefinition,
5363
+ withOverrides
2958
5364
  });
2959
5365
  //# sourceMappingURL=index.cjs.map