@btst/components 0.0.0-stage → 1.0.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 (161) hide show
  1. package/LICENSE.md +17 -0
  2. package/dist/_private/ui/styles/markdown-editor.css +31 -0
  3. package/dist/auto-form/index.cjs +8 -0
  4. package/dist/auto-form/index.d.cts +26 -0
  5. package/dist/auto-form/index.d.mts +26 -0
  6. package/dist/auto-form/index.d.ts +26 -0
  7. package/dist/auto-form/index.mjs +1 -0
  8. package/dist/empty/index.cjs +12 -0
  9. package/dist/empty/index.d.cts +15 -0
  10. package/dist/empty/index.d.mts +15 -0
  11. package/dist/empty/index.d.ts +15 -0
  12. package/dist/empty/index.mjs +1 -0
  13. package/dist/form-builder/index.cjs +16 -0
  14. package/dist/form-builder/index.d.cts +395 -0
  15. package/dist/form-builder/index.d.mts +395 -0
  16. package/dist/form-builder/index.d.ts +395 -0
  17. package/dist/form-builder/index.mjs +4 -0
  18. package/dist/markdown/index.cjs +9 -0
  19. package/dist/markdown/index.d.cts +46 -0
  20. package/dist/markdown/index.d.mts +46 -0
  21. package/dist/markdown/index.d.ts +46 -0
  22. package/dist/markdown/index.mjs +2 -0
  23. package/dist/multi-select/index.cjs +7 -0
  24. package/dist/multi-select/index.d.cts +78 -0
  25. package/dist/multi-select/index.d.mts +78 -0
  26. package/dist/multi-select/index.d.ts +78 -0
  27. package/dist/multi-select/index.mjs +1 -0
  28. package/dist/search-select/index.cjs +7 -0
  29. package/dist/search-select/index.d.cts +16 -0
  30. package/dist/search-select/index.d.mts +16 -0
  31. package/dist/search-select/index.d.ts +16 -0
  32. package/dist/search-select/index.mjs +1 -0
  33. package/dist/shared/components.BdvBiegH.d.cts +291 -0
  34. package/dist/shared/components.BdvBiegH.d.mts +291 -0
  35. package/dist/shared/components.BdvBiegH.d.ts +291 -0
  36. package/dist/shared/components.CZMWR72v.d.cts +10 -0
  37. package/dist/shared/components.CZMWR72v.d.mts +10 -0
  38. package/dist/shared/components.CZMWR72v.d.ts +10 -0
  39. package/dist/stepped-auto-form/index.cjs +7 -0
  40. package/dist/stepped-auto-form/index.d.cts +37 -0
  41. package/dist/stepped-auto-form/index.d.mts +37 -0
  42. package/dist/stepped-auto-form/index.d.ts +37 -0
  43. package/dist/stepped-auto-form/index.mjs +1 -0
  44. package/dist/style.css +440 -0
  45. package/dist/ui/src/components/accordion.cjs +81 -0
  46. package/dist/ui/src/components/accordion.mjs +62 -0
  47. package/dist/ui/src/components/auto-form/common/label.cjs +18 -0
  48. package/dist/ui/src/components/auto-form/common/label.mjs +16 -0
  49. package/dist/ui/src/components/auto-form/common/tooltip.cjs +9 -0
  50. package/dist/ui/src/components/auto-form/common/tooltip.mjs +7 -0
  51. package/dist/ui/src/components/auto-form/config.cjs +40 -0
  52. package/dist/ui/src/components/auto-form/config.mjs +37 -0
  53. package/dist/ui/src/components/auto-form/dependencies.cjs +48 -0
  54. package/dist/ui/src/components/auto-form/dependencies.mjs +46 -0
  55. package/dist/ui/src/components/auto-form/fields/array.cjs +266 -0
  56. package/dist/ui/src/components/auto-form/fields/array.mjs +264 -0
  57. package/dist/ui/src/components/auto-form/fields/checkbox.cjs +38 -0
  58. package/dist/ui/src/components/auto-form/fields/checkbox.mjs +36 -0
  59. package/dist/ui/src/components/auto-form/fields/date.cjs +67 -0
  60. package/dist/ui/src/components/auto-form/fields/date.mjs +65 -0
  61. package/dist/ui/src/components/auto-form/fields/enum.cjs +73 -0
  62. package/dist/ui/src/components/auto-form/fields/enum.mjs +71 -0
  63. package/dist/ui/src/components/auto-form/fields/input.cjs +32 -0
  64. package/dist/ui/src/components/auto-form/fields/input.mjs +30 -0
  65. package/dist/ui/src/components/auto-form/fields/number.cjs +31 -0
  66. package/dist/ui/src/components/auto-form/fields/number.mjs +29 -0
  67. package/dist/ui/src/components/auto-form/fields/object.cjs +233 -0
  68. package/dist/ui/src/components/auto-form/fields/object.mjs +217 -0
  69. package/dist/ui/src/components/auto-form/fields/radio-group.cjs +67 -0
  70. package/dist/ui/src/components/auto-form/fields/radio-group.mjs +65 -0
  71. package/dist/ui/src/components/auto-form/fields/switch.cjs +38 -0
  72. package/dist/ui/src/components/auto-form/fields/switch.mjs +36 -0
  73. package/dist/ui/src/components/auto-form/fields/textarea.cjs +31 -0
  74. package/dist/ui/src/components/auto-form/fields/textarea.mjs +29 -0
  75. package/dist/ui/src/components/auto-form/helpers.cjs +270 -0
  76. package/dist/ui/src/components/auto-form/helpers.mjs +259 -0
  77. package/dist/ui/src/components/auto-form/index.cjs +102 -0
  78. package/dist/ui/src/components/auto-form/index.mjs +93 -0
  79. package/dist/ui/src/components/auto-form/stepped-auto-form.cjs +374 -0
  80. package/dist/ui/src/components/auto-form/stepped-auto-form.mjs +368 -0
  81. package/dist/ui/src/components/auto-form/types.cjs +11 -0
  82. package/dist/ui/src/components/auto-form/types.mjs +9 -0
  83. package/dist/ui/src/components/badge.cjs +42 -0
  84. package/dist/ui/src/components/badge.mjs +39 -0
  85. package/dist/ui/src/components/button.cjs +56 -0
  86. package/dist/ui/src/components/button.mjs +53 -0
  87. package/dist/ui/src/components/calendar.cjs +207 -0
  88. package/dist/ui/src/components/calendar.mjs +190 -0
  89. package/dist/ui/src/components/checkbox.cjs +48 -0
  90. package/dist/ui/src/components/checkbox.mjs +32 -0
  91. package/dist/ui/src/components/command.cjs +118 -0
  92. package/dist/ui/src/components/command.mjs +111 -0
  93. package/dist/ui/src/components/date-picker.cjs +41 -0
  94. package/dist/ui/src/components/date-picker.mjs +39 -0
  95. package/dist/ui/src/components/dialog.cjs +141 -0
  96. package/dist/ui/src/components/dialog.mjs +118 -0
  97. package/dist/ui/src/components/empty.cjs +104 -0
  98. package/dist/ui/src/components/empty.mjs +97 -0
  99. package/dist/ui/src/components/form-builder/canvas.cjs +111 -0
  100. package/dist/ui/src/components/form-builder/canvas.mjs +109 -0
  101. package/dist/ui/src/components/form-builder/components/index.cjs +571 -0
  102. package/dist/ui/src/components/form-builder/components/index.mjs +554 -0
  103. package/dist/ui/src/components/form-builder/edit-field-dialog.cjs +131 -0
  104. package/dist/ui/src/components/form-builder/edit-field-dialog.mjs +129 -0
  105. package/dist/ui/src/components/form-builder/form-preview.cjs +73 -0
  106. package/dist/ui/src/components/form-builder/form-preview.mjs +71 -0
  107. package/dist/ui/src/components/form-builder/index.cjs +350 -0
  108. package/dist/ui/src/components/form-builder/index.mjs +344 -0
  109. package/dist/ui/src/components/form-builder/nested-field-editor-dialog.cjs +263 -0
  110. package/dist/ui/src/components/form-builder/nested-field-editor-dialog.mjs +261 -0
  111. package/dist/ui/src/components/form-builder/palette.cjs +52 -0
  112. package/dist/ui/src/components/form-builder/palette.mjs +49 -0
  113. package/dist/ui/src/components/form-builder/schema-utils.cjs +128 -0
  114. package/dist/ui/src/components/form-builder/schema-utils.mjs +122 -0
  115. package/dist/ui/src/components/form-builder/sortable-field.cjs +151 -0
  116. package/dist/ui/src/components/form-builder/sortable-field.mjs +148 -0
  117. package/dist/ui/src/components/form-builder/step-tabs.cjs +180 -0
  118. package/dist/ui/src/components/form-builder/step-tabs.mjs +178 -0
  119. package/dist/ui/src/components/form-builder/types.cjs +7 -0
  120. package/dist/ui/src/components/form-builder/types.mjs +5 -0
  121. package/dist/ui/src/components/form-builder/validation-schemas.cjs +67 -0
  122. package/dist/ui/src/components/form-builder/validation-schemas.mjs +56 -0
  123. package/dist/ui/src/components/form.cjs +120 -0
  124. package/dist/ui/src/components/form.mjs +98 -0
  125. package/dist/ui/src/components/input.cjs +23 -0
  126. package/dist/ui/src/components/input.mjs +21 -0
  127. package/dist/ui/src/components/label.cjs +39 -0
  128. package/dist/ui/src/components/label.mjs +23 -0
  129. package/dist/ui/src/components/markdown-content.cjs +334 -0
  130. package/dist/ui/src/components/markdown-content.mjs +325 -0
  131. package/dist/ui/src/components/markdown-editor.cjs +180 -0
  132. package/dist/ui/src/components/markdown-editor.mjs +178 -0
  133. package/dist/ui/src/components/multi-select.cjs +555 -0
  134. package/dist/ui/src/components/multi-select.mjs +540 -0
  135. package/dist/ui/src/components/popover.cjs +60 -0
  136. package/dist/ui/src/components/popover.mjs +42 -0
  137. package/dist/ui/src/components/radio-group.cjs +62 -0
  138. package/dist/ui/src/components/radio-group.mjs +45 -0
  139. package/dist/ui/src/components/search-select.cjs +99 -0
  140. package/dist/ui/src/components/search-select.mjs +83 -0
  141. package/dist/ui/src/components/select.cjs +161 -0
  142. package/dist/ui/src/components/select.mjs +139 -0
  143. package/dist/ui/src/components/separator.cjs +43 -0
  144. package/dist/ui/src/components/separator.mjs +27 -0
  145. package/dist/ui/src/components/switch.cjs +48 -0
  146. package/dist/ui/src/components/switch.mjs +32 -0
  147. package/dist/ui/src/components/tabs.cjs +84 -0
  148. package/dist/ui/src/components/tabs.mjs +65 -0
  149. package/dist/ui/src/components/textarea.cjs +20 -0
  150. package/dist/ui/src/components/textarea.mjs +18 -0
  151. package/dist/ui/src/hooks/use-debounce.cjs +16 -0
  152. package/dist/ui/src/hooks/use-debounce.mjs +14 -0
  153. package/dist/ui/src/lib/schema-converter.cjs +94 -0
  154. package/dist/ui/src/lib/schema-converter.mjs +92 -0
  155. package/dist/ui/src/lib/throttle.cjs +56 -0
  156. package/dist/ui/src/lib/throttle.mjs +54 -0
  157. package/dist/ui/src/lib/utils.cjs +10 -0
  158. package/dist/ui/src/lib/utils.mjs +8 -0
  159. package/dist/ui.css +131 -0
  160. package/package.json +176 -3
  161. package/README.md +0 -3
@@ -0,0 +1,571 @@
1
+ 'use strict';
2
+
3
+ const lucideReact = require('lucide-react');
4
+ const z = require('zod');
5
+ const types = require('../types.cjs');
6
+ const validationSchemas = require('../validation-schemas.cjs');
7
+ const helpers = require('../../auto-form/helpers.cjs');
8
+
9
+ function toNumber(value) {
10
+ if (value == null || value === "") return void 0;
11
+ const num = Number(value);
12
+ return isNaN(num) ? void 0 : num;
13
+ }
14
+ function buildInputProps(placeholder, inputType) {
15
+ const props = {};
16
+ if (placeholder) props.placeholder = placeholder;
17
+ if (inputType) props.type = inputType;
18
+ return Object.keys(props).length > 0 ? props : void 0;
19
+ }
20
+ function getPlaceholder(prop) {
21
+ return prop.inputProps?.placeholder || prop.placeholder;
22
+ }
23
+ function getLabel(prop, key) {
24
+ return prop.label || prop.title || helpers.beautifyObjectName(key);
25
+ }
26
+ const textFieldDefinition = types.defineComponent({
27
+ type: "text",
28
+ backingType: "string",
29
+ label: "Text Input",
30
+ icon: lucideReact.Type,
31
+ defaultProps: {
32
+ label: "Text Field",
33
+ placeholder: "",
34
+ required: false
35
+ },
36
+ propertiesSchema: validationSchemas.baseMetaSchemaWithPlaceholder.merge(validationSchemas.stringValidationSchema).merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.string })),
37
+ toJSONSchema: (props) => ({
38
+ type: "string",
39
+ label: props.label,
40
+ description: props.description,
41
+ inputProps: buildInputProps(props.placeholder),
42
+ default: props.defaultValue,
43
+ minLength: toNumber(props.minLength),
44
+ maxLength: toNumber(props.maxLength)
45
+ }),
46
+ fromJSONSchema: (prop, key, isRequired) => {
47
+ if (prop.type !== "string" || prop.enum || prop.fieldType || prop.inputType || prop.format || prop.inputProps?.type) {
48
+ return null;
49
+ }
50
+ return {
51
+ id: key,
52
+ type: "text",
53
+ props: {
54
+ label: getLabel(prop, key),
55
+ placeholder: getPlaceholder(prop),
56
+ description: prop.description,
57
+ required: isRequired,
58
+ defaultValue: prop.default,
59
+ minLength: prop.minLength,
60
+ maxLength: prop.maxLength
61
+ }
62
+ };
63
+ }
64
+ });
65
+ const emailFieldDefinition = types.defineComponent({
66
+ type: "email",
67
+ backingType: "string",
68
+ label: "Email",
69
+ icon: lucideReact.Mail,
70
+ defaultProps: {
71
+ label: "Email",
72
+ placeholder: "email@example.com",
73
+ required: false
74
+ },
75
+ propertiesSchema: validationSchemas.baseMetaSchemaWithPlaceholder.merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.string })),
76
+ toJSONSchema: (props) => ({
77
+ type: "string",
78
+ label: props.label,
79
+ description: props.description,
80
+ inputProps: buildInputProps(props.placeholder, "email"),
81
+ default: props.defaultValue,
82
+ format: "email"
83
+ }),
84
+ fromJSONSchema: (prop, key, isRequired) => {
85
+ if (prop.type !== "string" || prop.format !== "email" && prop.inputType !== "email" && prop.inputProps?.type !== "email") {
86
+ return null;
87
+ }
88
+ return {
89
+ id: key,
90
+ type: "email",
91
+ props: {
92
+ label: getLabel(prop, key),
93
+ placeholder: getPlaceholder(prop),
94
+ description: prop.description,
95
+ required: isRequired,
96
+ defaultValue: prop.default
97
+ }
98
+ };
99
+ }
100
+ });
101
+ const numberFieldDefinition = types.defineComponent({
102
+ type: "number",
103
+ backingType: "number",
104
+ label: "Number",
105
+ icon: lucideReact.Hash,
106
+ defaultProps: {
107
+ label: "Number",
108
+ required: false
109
+ },
110
+ propertiesSchema: validationSchemas.baseMetaSchemaWithPlaceholder.merge(validationSchemas.numberValidationSchema).merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.number })),
111
+ toJSONSchema: (props) => ({
112
+ type: "number",
113
+ label: props.label,
114
+ description: props.description,
115
+ inputProps: buildInputProps(props.placeholder),
116
+ default: props.defaultValue,
117
+ // toNumber handles form input which may come as strings
118
+ minimum: toNumber(props.min),
119
+ maximum: toNumber(props.max)
120
+ }),
121
+ fromJSONSchema: (prop, key, isRequired) => {
122
+ if (prop.type !== "number" && prop.type !== "integer") {
123
+ return null;
124
+ }
125
+ return {
126
+ id: key,
127
+ type: "number",
128
+ props: {
129
+ label: getLabel(prop, key),
130
+ placeholder: getPlaceholder(prop),
131
+ description: prop.description,
132
+ required: isRequired,
133
+ defaultValue: prop.default,
134
+ min: prop.minimum,
135
+ max: prop.maximum
136
+ }
137
+ };
138
+ }
139
+ });
140
+ const textareaFieldDefinition = types.defineComponent({
141
+ type: "textarea",
142
+ backingType: "string",
143
+ label: "Text Area",
144
+ icon: lucideReact.AlignLeft,
145
+ defaultProps: {
146
+ label: "Text Area",
147
+ placeholder: "",
148
+ required: false
149
+ },
150
+ propertiesSchema: validationSchemas.baseMetaSchemaWithPlaceholder.merge(validationSchemas.stringValidationSchema).merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.string })),
151
+ toJSONSchema: (props) => ({
152
+ type: "string",
153
+ label: props.label,
154
+ description: props.description,
155
+ fieldType: "textarea",
156
+ inputProps: buildInputProps(props.placeholder),
157
+ default: props.defaultValue,
158
+ minLength: toNumber(props.minLength),
159
+ maxLength: toNumber(props.maxLength)
160
+ }),
161
+ fromJSONSchema: (prop, key, isRequired) => {
162
+ if (prop.type !== "string" || prop.fieldType !== "textarea") {
163
+ return null;
164
+ }
165
+ return {
166
+ id: key,
167
+ type: "textarea",
168
+ props: {
169
+ label: getLabel(prop, key),
170
+ placeholder: getPlaceholder(prop),
171
+ description: prop.description,
172
+ required: isRequired,
173
+ defaultValue: prop.default,
174
+ minLength: prop.minLength,
175
+ maxLength: prop.maxLength
176
+ }
177
+ };
178
+ }
179
+ });
180
+ const checkboxFieldDefinition = types.defineComponent({
181
+ type: "checkbox",
182
+ backingType: "boolean",
183
+ label: "Checkbox",
184
+ icon: lucideReact.CheckSquare,
185
+ defaultProps: {
186
+ label: "Checkbox",
187
+ required: false
188
+ },
189
+ propertiesSchema: validationSchemas.baseMetaSchema.merge(validationSchemas.booleanValidationSchema).merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.boolean })),
190
+ toJSONSchema: (props) => ({
191
+ type: "boolean",
192
+ label: props.label,
193
+ description: props.description,
194
+ default: props.defaultValue
195
+ }),
196
+ fromJSONSchema: (prop, key, isRequired) => {
197
+ if (prop.type !== "boolean" || prop.fieldType === "switch") {
198
+ return null;
199
+ }
200
+ return {
201
+ id: key,
202
+ type: "checkbox",
203
+ props: {
204
+ label: getLabel(prop, key),
205
+ description: prop.description,
206
+ required: isRequired,
207
+ defaultValue: prop.default
208
+ }
209
+ };
210
+ }
211
+ });
212
+ const switchFieldDefinition = types.defineComponent({
213
+ type: "switch",
214
+ backingType: "boolean",
215
+ label: "Switch",
216
+ icon: lucideReact.ToggleLeft,
217
+ defaultProps: {
218
+ label: "Switch",
219
+ required: false
220
+ },
221
+ propertiesSchema: validationSchemas.baseMetaSchema.merge(validationSchemas.booleanValidationSchema).merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.boolean })),
222
+ toJSONSchema: (props) => ({
223
+ type: "boolean",
224
+ label: props.label,
225
+ description: props.description,
226
+ fieldType: "switch",
227
+ default: props.defaultValue
228
+ }),
229
+ fromJSONSchema: (prop, key, isRequired) => {
230
+ if (prop.type !== "boolean" || prop.fieldType !== "switch") {
231
+ return null;
232
+ }
233
+ return {
234
+ id: key,
235
+ type: "switch",
236
+ props: {
237
+ label: getLabel(prop, key),
238
+ description: prop.description,
239
+ required: isRequired,
240
+ defaultValue: prop.default
241
+ }
242
+ };
243
+ }
244
+ });
245
+ const selectFieldDefinition = types.defineComponent({
246
+ type: "select",
247
+ backingType: "enum",
248
+ label: "Select",
249
+ icon: lucideReact.ChevronDown,
250
+ defaultProps: {
251
+ label: "Select Field",
252
+ required: false,
253
+ options: ["Option 1", "Option 2", "Option 3"]
254
+ },
255
+ propertiesSchema: validationSchemas.baseMetaSchemaWithPlaceholder.merge(validationSchemas.enumOptionsSchema).merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.enum })),
256
+ toJSONSchema: (props) => ({
257
+ type: "string",
258
+ label: props.label,
259
+ description: props.description,
260
+ inputProps: buildInputProps(props.placeholder),
261
+ default: props.defaultValue,
262
+ enum: props.options
263
+ }),
264
+ fromJSONSchema: (prop, key, isRequired) => {
265
+ if (prop.type !== "string" || !prop.enum || prop.fieldType === "radio") {
266
+ return null;
267
+ }
268
+ return {
269
+ id: key,
270
+ type: "select",
271
+ props: {
272
+ label: getLabel(prop, key),
273
+ placeholder: getPlaceholder(prop),
274
+ description: prop.description,
275
+ required: isRequired,
276
+ defaultValue: prop.default,
277
+ options: prop.enum
278
+ }
279
+ };
280
+ }
281
+ });
282
+ const radioFieldDefinition = types.defineComponent({
283
+ type: "radio",
284
+ backingType: "enum",
285
+ label: "Radio Group",
286
+ icon: lucideReact.Circle,
287
+ defaultProps: {
288
+ label: "Radio Group",
289
+ required: false,
290
+ options: ["Option 1", "Option 2", "Option 3"]
291
+ },
292
+ propertiesSchema: validationSchemas.baseMetaSchema.merge(validationSchemas.enumOptionsSchema).merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.enum })),
293
+ toJSONSchema: (props) => ({
294
+ type: "string",
295
+ label: props.label,
296
+ description: props.description,
297
+ fieldType: "radio",
298
+ default: props.defaultValue,
299
+ enum: props.options
300
+ }),
301
+ fromJSONSchema: (prop, key, isRequired) => {
302
+ if (prop.type !== "string" || !prop.enum || prop.fieldType !== "radio") {
303
+ return null;
304
+ }
305
+ return {
306
+ id: key,
307
+ type: "radio",
308
+ props: {
309
+ label: getLabel(prop, key),
310
+ description: prop.description,
311
+ required: isRequired,
312
+ defaultValue: prop.default,
313
+ options: prop.enum
314
+ }
315
+ };
316
+ }
317
+ });
318
+ const passwordFieldDefinition = types.defineComponent({
319
+ type: "password",
320
+ backingType: "string",
321
+ label: "Password",
322
+ icon: lucideReact.Lock,
323
+ defaultProps: {
324
+ label: "Password",
325
+ placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
326
+ required: false
327
+ },
328
+ propertiesSchema: validationSchemas.baseMetaSchemaWithPlaceholder.merge(validationSchemas.stringValidationSchema).merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.string })),
329
+ toJSONSchema: (props) => ({
330
+ type: "string",
331
+ label: props.label,
332
+ description: props.description,
333
+ inputProps: buildInputProps(props.placeholder, "password"),
334
+ default: props.defaultValue,
335
+ minLength: toNumber(props.minLength),
336
+ maxLength: toNumber(props.maxLength)
337
+ }),
338
+ fromJSONSchema: (prop, key, isRequired) => {
339
+ if (prop.type !== "string" || prop.inputType !== "password" && prop.inputProps?.type !== "password") {
340
+ return null;
341
+ }
342
+ return {
343
+ id: key,
344
+ type: "password",
345
+ props: {
346
+ label: getLabel(prop, key),
347
+ placeholder: getPlaceholder(prop),
348
+ description: prop.description,
349
+ required: isRequired,
350
+ defaultValue: prop.default,
351
+ minLength: prop.minLength,
352
+ maxLength: prop.maxLength
353
+ }
354
+ };
355
+ }
356
+ });
357
+ const urlFieldDefinition = types.defineComponent({
358
+ type: "url",
359
+ backingType: "string",
360
+ label: "Website URL",
361
+ icon: lucideReact.Globe,
362
+ defaultProps: {
363
+ label: "Website",
364
+ placeholder: "https://example.com",
365
+ required: false
366
+ },
367
+ propertiesSchema: validationSchemas.baseMetaSchemaWithPlaceholder.merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.string })),
368
+ toJSONSchema: (props) => ({
369
+ type: "string",
370
+ label: props.label,
371
+ description: props.description,
372
+ inputProps: buildInputProps(props.placeholder),
373
+ default: props.defaultValue,
374
+ format: "uri"
375
+ }),
376
+ fromJSONSchema: (prop, key, isRequired) => {
377
+ if (prop.type !== "string" || prop.format !== "uri") {
378
+ return null;
379
+ }
380
+ return {
381
+ id: key,
382
+ type: "url",
383
+ props: {
384
+ label: getLabel(prop, key),
385
+ placeholder: getPlaceholder(prop),
386
+ description: prop.description,
387
+ required: isRequired,
388
+ defaultValue: prop.default
389
+ }
390
+ };
391
+ }
392
+ });
393
+ const phoneFieldDefinition = types.defineComponent({
394
+ type: "phone",
395
+ backingType: "string",
396
+ label: "Phone Number",
397
+ icon: lucideReact.Phone,
398
+ defaultProps: {
399
+ label: "Phone Number",
400
+ placeholder: "+1 (555) 123-4567",
401
+ required: false
402
+ },
403
+ propertiesSchema: validationSchemas.baseMetaSchemaWithPlaceholder.merge(z.z.object({ defaultValue: validationSchemas.DEFAULT_VALUE_SCHEMAS.string })),
404
+ toJSONSchema: (props) => ({
405
+ type: "string",
406
+ label: props.label,
407
+ description: props.description,
408
+ inputProps: buildInputProps(props.placeholder, "tel"),
409
+ default: props.defaultValue
410
+ }),
411
+ fromJSONSchema: (prop, key, isRequired) => {
412
+ if (prop.type !== "string" || prop.inputType !== "tel" && prop.inputProps?.type !== "tel") {
413
+ return null;
414
+ }
415
+ return {
416
+ id: key,
417
+ type: "phone",
418
+ props: {
419
+ label: getLabel(prop, key),
420
+ placeholder: getPlaceholder(prop),
421
+ description: prop.description,
422
+ required: isRequired,
423
+ defaultValue: prop.default
424
+ }
425
+ };
426
+ }
427
+ });
428
+ const dateFieldDefinition = types.defineComponent({
429
+ type: "date",
430
+ backingType: "date",
431
+ label: "Date Picker",
432
+ icon: lucideReact.Calendar,
433
+ defaultProps: {
434
+ label: "Date",
435
+ required: false
436
+ },
437
+ propertiesSchema: validationSchemas.baseMetaSchema.merge(validationSchemas.dateValidationSchema),
438
+ toJSONSchema: (props) => ({
439
+ type: "string",
440
+ format: "date-time",
441
+ fieldType: "date",
442
+ label: props.label,
443
+ description: props.description
444
+ }),
445
+ fromJSONSchema: (prop, key, isRequired) => {
446
+ if (prop.type !== "string" || prop.format !== "date-time" && prop.fieldType !== "date") {
447
+ return null;
448
+ }
449
+ return {
450
+ id: key,
451
+ type: "date",
452
+ props: {
453
+ label: getLabel(prop, key),
454
+ description: prop.description,
455
+ required: isRequired
456
+ }
457
+ };
458
+ }
459
+ });
460
+ const objectFieldDefinition = {
461
+ type: "object",
462
+ label: "Field Group",
463
+ icon: lucideReact.FolderOpen,
464
+ defaultProps: {
465
+ label: "Field Group",
466
+ required: false
467
+ },
468
+ propertiesSchema: validationSchemas.baseMetaSchema.extend(validationSchemas.objectValidationSchema.shape),
469
+ toJSONSchema: (props) => ({
470
+ type: "object",
471
+ label: props.label,
472
+ description: props.description,
473
+ // properties will be filled in by schema-utils from field.children
474
+ properties: {}
475
+ }),
476
+ fromJSONSchema: (prop, key, isRequired) => {
477
+ if (prop.type !== "object" || !prop.properties) {
478
+ return null;
479
+ }
480
+ return {
481
+ id: key,
482
+ type: "object",
483
+ props: {
484
+ label: getLabel(prop, key),
485
+ description: prop.description,
486
+ required: isRequired
487
+ },
488
+ // children will be filled in by schema-utils
489
+ children: []
490
+ };
491
+ }
492
+ };
493
+ const arrayFieldDefinition = {
494
+ type: "array",
495
+ label: "Repeating Group",
496
+ icon: lucideReact.List,
497
+ defaultProps: {
498
+ label: "Items",
499
+ required: false
500
+ },
501
+ propertiesSchema: validationSchemas.baseMetaSchema.extend(validationSchemas.arrayValidationSchema.shape),
502
+ toJSONSchema: (props) => ({
503
+ type: "array",
504
+ label: props.label,
505
+ description: props.description,
506
+ minItems: props.minItems,
507
+ maxItems: props.maxItems,
508
+ // items will be filled in by schema-utils from field.itemTemplate
509
+ items: {
510
+ type: "object",
511
+ properties: {}
512
+ }
513
+ }),
514
+ fromJSONSchema: (prop, key, isRequired) => {
515
+ if (prop.type !== "array" || !prop.items) {
516
+ return null;
517
+ }
518
+ return {
519
+ id: key,
520
+ type: "array",
521
+ props: {
522
+ label: getLabel(prop, key),
523
+ description: prop.description,
524
+ required: isRequired,
525
+ minItems: prop.minItems,
526
+ maxItems: prop.maxItems
527
+ },
528
+ // itemTemplate will be filled in by schema-utils
529
+ itemTemplate: []
530
+ };
531
+ }
532
+ };
533
+ const defaultComponents = [
534
+ // Container types (must be before primitives to match object/array JSON Schema)
535
+ objectFieldDefinition,
536
+ arrayFieldDefinition,
537
+ // Specific types first
538
+ emailFieldDefinition,
539
+ passwordFieldDefinition,
540
+ urlFieldDefinition,
541
+ phoneFieldDefinition,
542
+ dateFieldDefinition,
543
+ textareaFieldDefinition,
544
+ switchFieldDefinition,
545
+ radioFieldDefinition,
546
+ selectFieldDefinition,
547
+ checkboxFieldDefinition,
548
+ numberFieldDefinition,
549
+ // Generic fallback last
550
+ textFieldDefinition
551
+ ];
552
+ function getComponentByType(type, components = defaultComponents) {
553
+ return components.find((c) => c.type === type);
554
+ }
555
+
556
+ exports.arrayFieldDefinition = arrayFieldDefinition;
557
+ exports.checkboxFieldDefinition = checkboxFieldDefinition;
558
+ exports.dateFieldDefinition = dateFieldDefinition;
559
+ exports.defaultComponents = defaultComponents;
560
+ exports.emailFieldDefinition = emailFieldDefinition;
561
+ exports.getComponentByType = getComponentByType;
562
+ exports.numberFieldDefinition = numberFieldDefinition;
563
+ exports.objectFieldDefinition = objectFieldDefinition;
564
+ exports.passwordFieldDefinition = passwordFieldDefinition;
565
+ exports.phoneFieldDefinition = phoneFieldDefinition;
566
+ exports.radioFieldDefinition = radioFieldDefinition;
567
+ exports.selectFieldDefinition = selectFieldDefinition;
568
+ exports.switchFieldDefinition = switchFieldDefinition;
569
+ exports.textFieldDefinition = textFieldDefinition;
570
+ exports.textareaFieldDefinition = textareaFieldDefinition;
571
+ exports.urlFieldDefinition = urlFieldDefinition;