@btst/components 0.0.0-stage → 1.0.0-beta.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,261 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useId, useMemo, useState, useCallback } from 'react';
4
+ import { createPortal } from 'react-dom';
5
+ import { useSensors, useSensor, PointerSensor, TouchSensor, KeyboardSensor, DndContext, closestCenter, DragOverlay } from '@dnd-kit/core';
6
+ import { snapCenterToCursor } from '@dnd-kit/modifiers';
7
+ import { sortableKeyboardCoordinates, arrayMove } from '@dnd-kit/sortable';
8
+ import { FolderOpen, List } from 'lucide-react';
9
+ import { Button } from '../button.mjs';
10
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '../dialog.mjs';
11
+ import { Palette, PaletteDragOverlay } from './palette.mjs';
12
+ import { Canvas } from './canvas.mjs';
13
+ import { EditFieldDialog } from './edit-field-dialog.mjs';
14
+ import { FieldDragOverlay } from './sortable-field.mjs';
15
+ import { getComponentByType } from './components/index.mjs';
16
+ import { generateFieldId } from './schema-utils.mjs';
17
+
18
+ function NestedFieldEditorDialog({
19
+ open,
20
+ onOpenChange,
21
+ field,
22
+ components,
23
+ onSave
24
+ }) {
25
+ const dndContextId = useId();
26
+ const initialFields = useMemo(() => {
27
+ if (!field) return [];
28
+ if (field.type === "object") return field.children || [];
29
+ if (field.type === "array") return field.itemTemplate || [];
30
+ return [];
31
+ }, [field]);
32
+ const [nestedFields, setNestedFields] = useState(initialFields);
33
+ const [activeId, setActiveId] = useState(null);
34
+ const [editDialogFieldId, setEditDialogFieldId] = useState(null);
35
+ const [prevField, setPrevField] = useState(field);
36
+ const [prevOpen, setPrevOpen] = useState(open);
37
+ if (prevField !== field || open && !prevOpen) {
38
+ setPrevField(field);
39
+ setPrevOpen(open);
40
+ setNestedFields(initialFields);
41
+ setEditDialogFieldId(null);
42
+ }
43
+ if (prevOpen !== open) {
44
+ setPrevOpen(open);
45
+ }
46
+ const sensors = useSensors(
47
+ useSensor(PointerSensor, {
48
+ activationConstraint: { distance: 8 }
49
+ }),
50
+ useSensor(TouchSensor, {
51
+ activationConstraint: { distance: 8 }
52
+ }),
53
+ useSensor(KeyboardSensor, {
54
+ coordinateGetter: sortableKeyboardCoordinates
55
+ })
56
+ );
57
+ const activeDragData = useMemo(() => {
58
+ if (!activeId) return null;
59
+ const idStr = String(activeId);
60
+ if (idStr.startsWith("palette-")) {
61
+ const componentType = idStr.replace("palette-", "");
62
+ return {
63
+ type: "palette",
64
+ componentType,
65
+ component: getComponentByType(componentType, components)
66
+ };
67
+ }
68
+ const nestedField = nestedFields.find((f) => f.id === idStr);
69
+ if (nestedField) {
70
+ return {
71
+ type: "field",
72
+ field: nestedField,
73
+ component: getComponentByType(nestedField.type, components)
74
+ };
75
+ }
76
+ return null;
77
+ }, [activeId, nestedFields, components]);
78
+ const handleDragStart = (event) => {
79
+ setActiveId(event.active.id);
80
+ };
81
+ const handleDragEnd = (event) => {
82
+ const { active, over } = event;
83
+ setActiveId(null);
84
+ if (!over) return;
85
+ const activeData = active.data.current;
86
+ if (activeData?.type === "palette") {
87
+ const { componentType } = activeData;
88
+ const component = getComponentByType(componentType, components);
89
+ if (component) {
90
+ const newField = {
91
+ id: generateFieldId(componentType),
92
+ type: componentType,
93
+ props: {
94
+ label: component.defaultProps.label || component.label,
95
+ ...component.defaultProps
96
+ }
97
+ };
98
+ let insertIndex = nestedFields.length;
99
+ const overId = String(over.id);
100
+ if (overId === "drop-zone-start") {
101
+ insertIndex = 0;
102
+ } else if (overId.startsWith("drop-zone-")) {
103
+ const fieldId = overId.replace("drop-zone-", "");
104
+ const overIndex = nestedFields.findIndex((f) => f.id === fieldId);
105
+ if (overIndex !== -1) {
106
+ insertIndex = overIndex + 1;
107
+ }
108
+ } else if (overId !== "canvas") {
109
+ const overIndex = nestedFields.findIndex((f) => f.id === overId);
110
+ if (overIndex !== -1) {
111
+ insertIndex = overIndex + 1;
112
+ }
113
+ }
114
+ const newFields = [...nestedFields];
115
+ newFields.splice(insertIndex, 0, newField);
116
+ setNestedFields(newFields);
117
+ }
118
+ return;
119
+ }
120
+ if (activeData?.type === "field" && active.id !== over.id) {
121
+ const oldIndex = nestedFields.findIndex((f) => f.id === active.id);
122
+ const newIndex = nestedFields.findIndex((f) => f.id === over.id);
123
+ if (oldIndex !== -1 && newIndex !== -1) {
124
+ setNestedFields(arrayMove(nestedFields, oldIndex, newIndex));
125
+ }
126
+ }
127
+ };
128
+ const handleDeleteField = useCallback((id) => {
129
+ setNestedFields((fields) => fields.filter((f) => f.id !== id));
130
+ }, []);
131
+ const handleEditField = useCallback((id) => {
132
+ setEditDialogFieldId(id);
133
+ }, []);
134
+ const handleUpdateField = useCallback(
135
+ (id, props, newId) => {
136
+ if (newId && newId !== id) {
137
+ const idExists = nestedFields.some((f) => f.id === newId && f.id !== id);
138
+ if (idExists) {
139
+ console.warn(`Cannot rename field "${id}" to "${newId}": a field with that ID already exists`);
140
+ return;
141
+ }
142
+ }
143
+ setNestedFields(
144
+ (fields) => fields.map((f) => {
145
+ if (f.id !== id) return f;
146
+ return {
147
+ ...f,
148
+ id: newId || f.id,
149
+ props: { ...f.props, ...props }
150
+ };
151
+ })
152
+ );
153
+ },
154
+ [nestedFields]
155
+ );
156
+ const handleSave = useCallback(() => {
157
+ if (!field) return;
158
+ onSave(field.id, nestedFields);
159
+ onOpenChange(false);
160
+ }, [field, nestedFields, onSave, onOpenChange]);
161
+ if (!field) return null;
162
+ const isObjectField = field.type === "object";
163
+ const Icon = isObjectField ? FolderOpen : List;
164
+ const fieldTypeLabel = isObjectField ? "Field Group" : "Repeating Group";
165
+ const nestedLabel = isObjectField ? "nested fields" : "item fields";
166
+ const editDialogField = nestedFields.find((f) => f.id === editDialogFieldId) || null;
167
+ const editDialogComponent = editDialogField ? getComponentByType(editDialogField.type, components) || null : null;
168
+ return /* @__PURE__ */ jsxs(Dialog, { open, onOpenChange, children: [
169
+ /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-6xl! max-h-[90vh] overflow-hidden flex flex-col", children: [
170
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
171
+ /* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
172
+ /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5 text-muted-foreground" }),
173
+ "Configure ",
174
+ fieldTypeLabel,
175
+ ": ",
176
+ field.props.label
177
+ ] }),
178
+ /* @__PURE__ */ jsxs(DialogDescription, { children: [
179
+ "Add and arrange the ",
180
+ nestedLabel,
181
+ " for this ",
182
+ fieldTypeLabel.toLowerCase(),
183
+ ".",
184
+ isObjectField ? " These fields will be grouped together." : " Each item in the array will have these fields."
185
+ ] })
186
+ ] }),
187
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxs(
188
+ DndContext,
189
+ {
190
+ id: dndContextId,
191
+ sensors,
192
+ collisionDetection: closestCenter,
193
+ onDragStart: handleDragStart,
194
+ onDragEnd: handleDragEnd,
195
+ children: [
196
+ /* @__PURE__ */ jsxs("div", { className: "flex h-[50vh] gap-4", children: [
197
+ /* @__PURE__ */ jsx("div", { className: "w-48 overflow-auto shrink-0 border-r pr-4", children: /* @__PURE__ */ jsx(Palette, { components }) }),
198
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ jsx(
199
+ Canvas,
200
+ {
201
+ fields: nestedFields,
202
+ components,
203
+ onEditField: handleEditField,
204
+ onDeleteField: handleDeleteField,
205
+ isDraggingFromPalette: activeDragData?.type === "palette",
206
+ steps: [],
207
+ activeStepIndex: 0,
208
+ onActiveStepChange: () => {
209
+ },
210
+ onAddStep: () => {
211
+ },
212
+ onDeleteStep: () => {
213
+ },
214
+ onRenameStep: () => {
215
+ },
216
+ hideStepControls: true
217
+ }
218
+ ) })
219
+ ] }),
220
+ typeof document !== "undefined" && createPortal(
221
+ /* @__PURE__ */ jsxs(DragOverlay, { dropAnimation: null, modifiers: [snapCenterToCursor], children: [
222
+ activeDragData?.type === "palette" && activeDragData.component && /* @__PURE__ */ jsx(PaletteDragOverlay, { component: activeDragData.component }),
223
+ activeDragData?.type === "field" && activeDragData.field && /* @__PURE__ */ jsx(
224
+ FieldDragOverlay,
225
+ {
226
+ field: activeDragData.field,
227
+ component: activeDragData.component
228
+ }
229
+ )
230
+ ] }),
231
+ document.body
232
+ )
233
+ ]
234
+ }
235
+ ) }),
236
+ /* @__PURE__ */ jsxs(DialogFooter, { className: "border-t pt-4", children: [
237
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground mr-auto", children: [
238
+ nestedFields.length,
239
+ " ",
240
+ nestedFields.length === 1 ? "field" : "fields"
241
+ ] }),
242
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
243
+ /* @__PURE__ */ jsx(Button, { onClick: handleSave, children: "Save Fields" })
244
+ ] })
245
+ ] }),
246
+ /* @__PURE__ */ jsx(
247
+ EditFieldDialog,
248
+ {
249
+ open: editDialogFieldId !== null,
250
+ onOpenChange: (open2) => !open2 && setEditDialogFieldId(null),
251
+ field: editDialogField,
252
+ component: editDialogComponent,
253
+ onUpdate: handleUpdateField,
254
+ steps: [],
255
+ allFieldIds: nestedFields.map((f) => f.id)
256
+ }
257
+ )
258
+ ] });
259
+ }
260
+
261
+ export { NestedFieldEditorDialog };
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const core = require('@dnd-kit/core');
6
+ const utils = require('../../lib/utils.cjs');
7
+
8
+ function PaletteItem({ component }) {
9
+ const { attributes, listeners, setNodeRef, isDragging } = core.useDraggable({
10
+ id: `palette-${component.type}`,
11
+ data: {
12
+ type: "palette",
13
+ componentType: component.type
14
+ }
15
+ });
16
+ const Icon = component.icon;
17
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18
+ "div",
19
+ {
20
+ ref: setNodeRef,
21
+ ...listeners,
22
+ ...attributes,
23
+ className: utils.cn(
24
+ "flex items-center gap-3 p-3 rounded-lg border bg-card cursor-grab active:cursor-grabbing",
25
+ "hover:bg-accent hover:border-accent-foreground/20 transition-colors",
26
+ "touch-none select-none",
27
+ isDragging && "opacity-50"
28
+ ),
29
+ children: [
30
+ Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
31
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: component.label })
32
+ ]
33
+ }
34
+ );
35
+ }
36
+ function Palette({ components, className }) {
37
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("flex flex-col gap-2", className), "data-testid": "form-builder-palette", children: [
38
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold text-muted-foreground mb-2", children: "Components" }),
39
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row flex-wrap lg:flex-col gap-2", children: components.map((component) => /* @__PURE__ */ jsxRuntime.jsx(PaletteItem, { component }, component.type)) })
40
+ ] });
41
+ }
42
+ function PaletteDragOverlay({ component }) {
43
+ if (!component) return null;
44
+ const Icon = component.icon;
45
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 p-3 rounded-lg border bg-card shadow-lg cursor-grabbing", children: [
46
+ Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
47
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: component.label })
48
+ ] });
49
+ }
50
+
51
+ exports.Palette = Palette;
52
+ exports.PaletteDragOverlay = PaletteDragOverlay;
@@ -0,0 +1,49 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useDraggable } from '@dnd-kit/core';
4
+ import { cn } from '../../lib/utils.mjs';
5
+
6
+ function PaletteItem({ component }) {
7
+ const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
8
+ id: `palette-${component.type}`,
9
+ data: {
10
+ type: "palette",
11
+ componentType: component.type
12
+ }
13
+ });
14
+ const Icon = component.icon;
15
+ return /* @__PURE__ */ jsxs(
16
+ "div",
17
+ {
18
+ ref: setNodeRef,
19
+ ...listeners,
20
+ ...attributes,
21
+ className: cn(
22
+ "flex items-center gap-3 p-3 rounded-lg border bg-card cursor-grab active:cursor-grabbing",
23
+ "hover:bg-accent hover:border-accent-foreground/20 transition-colors",
24
+ "touch-none select-none",
25
+ isDragging && "opacity-50"
26
+ ),
27
+ children: [
28
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
29
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: component.label })
30
+ ]
31
+ }
32
+ );
33
+ }
34
+ function Palette({ components, className }) {
35
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), "data-testid": "form-builder-palette", children: [
36
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-muted-foreground mb-2", children: "Components" }),
37
+ /* @__PURE__ */ jsx("div", { className: "flex flex-row flex-wrap lg:flex-col gap-2", children: components.map((component) => /* @__PURE__ */ jsx(PaletteItem, { component }, component.type)) })
38
+ ] });
39
+ }
40
+ function PaletteDragOverlay({ component }) {
41
+ if (!component) return null;
42
+ const Icon = component.icon;
43
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 p-3 rounded-lg border bg-card shadow-lg cursor-grabbing", children: [
44
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
45
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: component.label })
46
+ ] });
47
+ }
48
+
49
+ export { Palette, PaletteDragOverlay };
@@ -0,0 +1,128 @@
1
+ 'use strict';
2
+
3
+ const helpers = require('../auto-form/helpers.cjs');
4
+
5
+ function fieldsToProperties(fields, components, includeStepGroup = false) {
6
+ const properties = {};
7
+ for (const field of fields) {
8
+ const component = components.find((c) => c.type === field.type);
9
+ if (!component) {
10
+ console.warn(`Unknown component type: ${field.type}`);
11
+ continue;
12
+ }
13
+ const isRequired = field.props.required ?? false;
14
+ const schemaProp = component.toJSONSchema(field.props, isRequired);
15
+ if (includeStepGroup && field.stepGroup !== void 0) {
16
+ schemaProp.stepGroup = field.stepGroup;
17
+ }
18
+ if (field.type === "object" && field.children && field.children.length > 0) {
19
+ schemaProp.properties = fieldsToProperties(field.children, components, false);
20
+ const childRequired = field.children.filter((child) => child.props.required).map((child) => child.id);
21
+ if (childRequired.length > 0) {
22
+ schemaProp.required = childRequired;
23
+ }
24
+ }
25
+ if (field.type === "array" && field.itemTemplate && field.itemTemplate.length > 0) {
26
+ schemaProp.items = {
27
+ type: "object",
28
+ properties: fieldsToProperties(field.itemTemplate, components, false)
29
+ };
30
+ const itemRequired = field.itemTemplate.filter((item) => item.props.required).map((item) => item.id);
31
+ if (itemRequired.length > 0) {
32
+ schemaProp.items.required = itemRequired;
33
+ }
34
+ }
35
+ properties[field.id] = schemaProp;
36
+ }
37
+ return properties;
38
+ }
39
+ function getRequiredFieldIds(fields) {
40
+ return fields.filter((f) => f.props.required).map((f) => f.id);
41
+ }
42
+ function fieldsToJSONSchema(fields, components, steps) {
43
+ const hasMultipleSteps = steps && steps.length > 1;
44
+ const properties = fieldsToProperties(fields, components, hasMultipleSteps);
45
+ const required = getRequiredFieldIds(fields);
46
+ return {
47
+ type: "object",
48
+ properties,
49
+ ...required.length > 0 ? { required } : {},
50
+ // Only include steps if there are multiple steps
51
+ ...hasMultipleSteps ? { steps } : {}
52
+ };
53
+ }
54
+ function propertiesToFields(properties, requiredSet, components, stepGroupMap) {
55
+ const fields = [];
56
+ for (const [key, prop] of Object.entries(properties)) {
57
+ const isRequired = requiredSet.has(key);
58
+ let field = null;
59
+ for (const component of components) {
60
+ field = component.fromJSONSchema(prop, key, isRequired);
61
+ if (field) {
62
+ break;
63
+ }
64
+ }
65
+ const resolvedStepGroup = prop.stepGroup !== void 0 ? prop.stepGroup : stepGroupMap?.[key];
66
+ if (field) {
67
+ if (resolvedStepGroup !== void 0) {
68
+ field.stepGroup = resolvedStepGroup;
69
+ }
70
+ if (field.type === "object" && prop.properties) {
71
+ const childRequiredSet = new Set(prop.required || []);
72
+ field.children = propertiesToFields(prop.properties, childRequiredSet, components);
73
+ }
74
+ if (field.type === "array" && prop.items?.properties) {
75
+ const itemRequiredSet = new Set(prop.items.required || []);
76
+ field.itemTemplate = propertiesToFields(prop.items.properties, itemRequiredSet, components);
77
+ }
78
+ fields.push(field);
79
+ } else {
80
+ console.warn(`Could not parse JSON Schema property: ${key}`, prop);
81
+ fields.push({
82
+ id: key,
83
+ type: "text",
84
+ props: {
85
+ label: prop.label || prop.title || helpers.beautifyObjectName(key),
86
+ description: prop.description,
87
+ placeholder: prop.placeholder,
88
+ required: isRequired
89
+ },
90
+ // Include stepGroup even for fallback fields
91
+ ...resolvedStepGroup !== void 0 ? { stepGroup: resolvedStepGroup } : {}
92
+ });
93
+ }
94
+ }
95
+ return fields;
96
+ }
97
+ function jsonSchemaToFieldsAndSteps(schema, components) {
98
+ if (!schema || !schema.properties) {
99
+ return { fields: [], steps: [] };
100
+ }
101
+ const requiredSet = new Set(schema.required || []);
102
+ const fields = propertiesToFields(
103
+ schema.properties,
104
+ requiredSet,
105
+ components,
106
+ schema.stepGroupMap
107
+ );
108
+ const steps = schema.steps || [];
109
+ return { fields, steps };
110
+ }
111
+ function generateFieldId(prefix = "field") {
112
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
113
+ }
114
+ function generateStepId() {
115
+ return `step_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
116
+ }
117
+ function createStep(index) {
118
+ return {
119
+ id: generateStepId(),
120
+ title: `Step ${index + 1}`
121
+ };
122
+ }
123
+
124
+ exports.createStep = createStep;
125
+ exports.fieldsToJSONSchema = fieldsToJSONSchema;
126
+ exports.generateFieldId = generateFieldId;
127
+ exports.generateStepId = generateStepId;
128
+ exports.jsonSchemaToFieldsAndSteps = jsonSchemaToFieldsAndSteps;
@@ -0,0 +1,122 @@
1
+ import { beautifyObjectName } from '../auto-form/helpers.mjs';
2
+
3
+ function fieldsToProperties(fields, components, includeStepGroup = false) {
4
+ const properties = {};
5
+ for (const field of fields) {
6
+ const component = components.find((c) => c.type === field.type);
7
+ if (!component) {
8
+ console.warn(`Unknown component type: ${field.type}`);
9
+ continue;
10
+ }
11
+ const isRequired = field.props.required ?? false;
12
+ const schemaProp = component.toJSONSchema(field.props, isRequired);
13
+ if (includeStepGroup && field.stepGroup !== void 0) {
14
+ schemaProp.stepGroup = field.stepGroup;
15
+ }
16
+ if (field.type === "object" && field.children && field.children.length > 0) {
17
+ schemaProp.properties = fieldsToProperties(field.children, components, false);
18
+ const childRequired = field.children.filter((child) => child.props.required).map((child) => child.id);
19
+ if (childRequired.length > 0) {
20
+ schemaProp.required = childRequired;
21
+ }
22
+ }
23
+ if (field.type === "array" && field.itemTemplate && field.itemTemplate.length > 0) {
24
+ schemaProp.items = {
25
+ type: "object",
26
+ properties: fieldsToProperties(field.itemTemplate, components, false)
27
+ };
28
+ const itemRequired = field.itemTemplate.filter((item) => item.props.required).map((item) => item.id);
29
+ if (itemRequired.length > 0) {
30
+ schemaProp.items.required = itemRequired;
31
+ }
32
+ }
33
+ properties[field.id] = schemaProp;
34
+ }
35
+ return properties;
36
+ }
37
+ function getRequiredFieldIds(fields) {
38
+ return fields.filter((f) => f.props.required).map((f) => f.id);
39
+ }
40
+ function fieldsToJSONSchema(fields, components, steps) {
41
+ const hasMultipleSteps = steps && steps.length > 1;
42
+ const properties = fieldsToProperties(fields, components, hasMultipleSteps);
43
+ const required = getRequiredFieldIds(fields);
44
+ return {
45
+ type: "object",
46
+ properties,
47
+ ...required.length > 0 ? { required } : {},
48
+ // Only include steps if there are multiple steps
49
+ ...hasMultipleSteps ? { steps } : {}
50
+ };
51
+ }
52
+ function propertiesToFields(properties, requiredSet, components, stepGroupMap) {
53
+ const fields = [];
54
+ for (const [key, prop] of Object.entries(properties)) {
55
+ const isRequired = requiredSet.has(key);
56
+ let field = null;
57
+ for (const component of components) {
58
+ field = component.fromJSONSchema(prop, key, isRequired);
59
+ if (field) {
60
+ break;
61
+ }
62
+ }
63
+ const resolvedStepGroup = prop.stepGroup !== void 0 ? prop.stepGroup : stepGroupMap?.[key];
64
+ if (field) {
65
+ if (resolvedStepGroup !== void 0) {
66
+ field.stepGroup = resolvedStepGroup;
67
+ }
68
+ if (field.type === "object" && prop.properties) {
69
+ const childRequiredSet = new Set(prop.required || []);
70
+ field.children = propertiesToFields(prop.properties, childRequiredSet, components);
71
+ }
72
+ if (field.type === "array" && prop.items?.properties) {
73
+ const itemRequiredSet = new Set(prop.items.required || []);
74
+ field.itemTemplate = propertiesToFields(prop.items.properties, itemRequiredSet, components);
75
+ }
76
+ fields.push(field);
77
+ } else {
78
+ console.warn(`Could not parse JSON Schema property: ${key}`, prop);
79
+ fields.push({
80
+ id: key,
81
+ type: "text",
82
+ props: {
83
+ label: prop.label || prop.title || beautifyObjectName(key),
84
+ description: prop.description,
85
+ placeholder: prop.placeholder,
86
+ required: isRequired
87
+ },
88
+ // Include stepGroup even for fallback fields
89
+ ...resolvedStepGroup !== void 0 ? { stepGroup: resolvedStepGroup } : {}
90
+ });
91
+ }
92
+ }
93
+ return fields;
94
+ }
95
+ function jsonSchemaToFieldsAndSteps(schema, components) {
96
+ if (!schema || !schema.properties) {
97
+ return { fields: [], steps: [] };
98
+ }
99
+ const requiredSet = new Set(schema.required || []);
100
+ const fields = propertiesToFields(
101
+ schema.properties,
102
+ requiredSet,
103
+ components,
104
+ schema.stepGroupMap
105
+ );
106
+ const steps = schema.steps || [];
107
+ return { fields, steps };
108
+ }
109
+ function generateFieldId(prefix = "field") {
110
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
111
+ }
112
+ function generateStepId() {
113
+ return `step_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
114
+ }
115
+ function createStep(index) {
116
+ return {
117
+ id: generateStepId(),
118
+ title: `Step ${index + 1}`
119
+ };
120
+ }
121
+
122
+ export { createStep, fieldsToJSONSchema, generateFieldId, generateStepId, jsonSchemaToFieldsAndSteps };