config-driven-form 1.1.2 → 1.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.
package/dist/index.mjs CHANGED
@@ -1,20 +1,34 @@
1
1
  import { useForm, FormProvider, useFormContext } from 'react-hook-form';
2
2
  import { ajvResolver } from '@hookform/resolvers/ajv';
3
- import { EyeOff, Eye, AlertCircle, Bold, Italic, Heading2, List, ListOrdered } from 'lucide-react';
4
- import { jsx, jsxs } from 'react/jsx-runtime';
5
- import { useState, useEffect } from 'react';
3
+ import { createContext, useState, useCallback, useMemo, useEffect, useContext } from 'react';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+ import { Code2, LayoutTemplate, Eye, Save, Palette, Settings, CheckCircle2, Paintbrush, EyeOff, AlertCircle, Bold, Italic, Heading2, List, ListOrdered, Type, Hash, Mail, Key, AlignLeft, ChevronDown, CheckSquare, FileUp, GripVertical, Copy, Trash2 } from 'lucide-react';
6
6
  import { useEditor, EditorContent } from '@tiptap/react';
7
7
  import StarterKit from '@tiptap/starter-kit';
8
+ import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter, DragOverlay, useDroppable, useDraggable } from '@dnd-kit/core';
9
+ import { sortableKeyboardCoordinates, arrayMove, SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
10
+ import { v4 } from 'uuid';
11
+ import { CSS } from '@dnd-kit/utilities';
8
12
 
9
13
  // src/components/SchemaForm.tsx
10
- var TextField = ({ name, schema, isRequired }) => {
14
+ var ClassNamesContext = createContext({});
15
+ var ClassNamesProvider = ({ value = {}, children }) => {
16
+ return /* @__PURE__ */ jsx(ClassNamesContext.Provider, { value, children });
17
+ };
18
+ var useClassNames = () => useContext(ClassNamesContext);
19
+ var cx = (...classes) => {
20
+ return classes.filter(Boolean).join(" ").trim();
21
+ };
22
+ var TextField = ({ name, schema, uiSchema, isRequired }) => {
23
+ const globalClasses = useClassNames();
24
+ const localClasses = (uiSchema == null ? void 0 : uiSchema["ui:classNames"]) || {};
11
25
  const {
12
26
  register,
13
27
  formState: { errors }
14
28
  } = useFormContext();
15
29
  const error = errors[name];
16
- return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
17
- /* @__PURE__ */ jsxs("label", { className: "cdf-label", htmlFor: name, children: [
30
+ return /* @__PURE__ */ jsxs("div", { className: cx("cdf-field-group", globalClasses.fieldGroup, localClasses.fieldGroup), children: [
31
+ /* @__PURE__ */ jsxs("label", { className: cx("cdf-label", globalClasses.label, localClasses.label), htmlFor: name, children: [
18
32
  schema.title || name,
19
33
  isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
20
34
  ] }),
@@ -23,26 +37,40 @@ var TextField = ({ name, schema, isRequired }) => {
23
37
  {
24
38
  id: name,
25
39
  type: schema.format === "email" ? "email" : "text",
26
- className: `cdf-input ${error ? "cdf-input--error" : ""}`,
40
+ className: cx(
41
+ "cdf-input",
42
+ globalClasses.input,
43
+ localClasses.input,
44
+ error && "cdf-input--error",
45
+ error && globalClasses.inputError,
46
+ error && localClasses.inputError
47
+ ),
27
48
  placeholder: `Enter ${schema.title || name}`,
28
49
  ...register(name)
29
50
  }
30
51
  ) }),
31
- error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
52
+ error && /* @__PURE__ */ jsxs("span", { className: cx("cdf-error-message", globalClasses.errorText, localClasses.errorText), children: [
32
53
  /* @__PURE__ */ jsx(AlertCircle, { size: 14 }),
33
54
  error.message
34
55
  ] })
35
56
  ] });
36
57
  };
37
- var PasswordField = ({ name, schema, isRequired }) => {
58
+ var PasswordField = ({
59
+ name,
60
+ schema,
61
+ uiSchema,
62
+ isRequired
63
+ }) => {
64
+ const globalClasses = useClassNames();
65
+ const localClasses = (uiSchema == null ? void 0 : uiSchema["ui:classNames"]) || {};
38
66
  const {
39
67
  register,
40
68
  formState: { errors }
41
69
  } = useFormContext();
42
70
  const [showPassword, setShowPassword] = useState(false);
43
71
  const error = errors[name];
44
- return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
45
- /* @__PURE__ */ jsxs("label", { className: "cdf-label", htmlFor: name, children: [
72
+ return /* @__PURE__ */ jsxs("div", { className: cx("cdf-field-group", globalClasses.fieldGroup, localClasses.fieldGroup), children: [
73
+ /* @__PURE__ */ jsxs("label", { className: cx("cdf-label", globalClasses.label, localClasses.label), htmlFor: name, children: [
46
74
  schema.title || name,
47
75
  isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
48
76
  ] }),
@@ -52,7 +80,14 @@ var PasswordField = ({ name, schema, isRequired }) => {
52
80
  {
53
81
  id: name,
54
82
  type: showPassword ? "text" : "password",
55
- className: `cdf-input ${error ? "cdf-input--error" : ""}`,
83
+ className: cx(
84
+ "cdf-input",
85
+ globalClasses.input,
86
+ localClasses.input,
87
+ error && "cdf-input--error",
88
+ error && globalClasses.inputError,
89
+ error && localClasses.inputError
90
+ ),
56
91
  style: { paddingRight: "2.5rem" },
57
92
  placeholder: `Enter ${schema.title || name}`,
58
93
  ...register(name)
@@ -69,20 +104,22 @@ var PasswordField = ({ name, schema, isRequired }) => {
69
104
  }
70
105
  )
71
106
  ] }),
72
- error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
107
+ error && /* @__PURE__ */ jsxs("span", { className: cx("cdf-error-message", globalClasses.errorText, localClasses.errorText), children: [
73
108
  /* @__PURE__ */ jsx(AlertCircle, { size: 14 }),
74
109
  error.message
75
110
  ] })
76
111
  ] });
77
112
  };
78
- var NumberField = ({ name, schema, isRequired }) => {
113
+ var NumberField = ({ name, schema, uiSchema, isRequired }) => {
114
+ const globalClasses = useClassNames();
115
+ const localClasses = (uiSchema == null ? void 0 : uiSchema["ui:classNames"]) || {};
79
116
  const {
80
117
  register,
81
118
  formState: { errors }
82
119
  } = useFormContext();
83
120
  const error = errors[name];
84
- return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
85
- /* @__PURE__ */ jsxs("label", { className: "cdf-label", htmlFor: name, children: [
121
+ return /* @__PURE__ */ jsxs("div", { className: cx("cdf-field-group", globalClasses.fieldGroup, localClasses.fieldGroup), children: [
122
+ /* @__PURE__ */ jsxs("label", { className: cx("cdf-label", globalClasses.label, localClasses.label), htmlFor: name, children: [
86
123
  schema.title || name,
87
124
  isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
88
125
  ] }),
@@ -91,20 +128,34 @@ var NumberField = ({ name, schema, isRequired }) => {
91
128
  {
92
129
  id: name,
93
130
  type: "number",
94
- className: `cdf-input ${error ? "cdf-input--error" : ""}`,
131
+ className: cx(
132
+ "cdf-input",
133
+ globalClasses.input,
134
+ localClasses.input,
135
+ error && "cdf-input--error",
136
+ error && globalClasses.inputError,
137
+ error && localClasses.inputError
138
+ ),
95
139
  placeholder: `Enter ${schema.title || name}`,
96
140
  ...register(name, {
97
141
  valueAsNumber: true
98
142
  })
99
143
  }
100
144
  ) }),
101
- error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
145
+ error && /* @__PURE__ */ jsxs("span", { className: cx("cdf-error-message", globalClasses.errorText, localClasses.errorText), children: [
102
146
  /* @__PURE__ */ jsx(AlertCircle, { size: 14 }),
103
147
  error.message
104
148
  ] })
105
149
  ] });
106
150
  };
107
- var RichTextField = ({ name, schema, isRequired }) => {
151
+ var RichTextField = ({
152
+ name,
153
+ schema,
154
+ uiSchema,
155
+ isRequired
156
+ }) => {
157
+ const globalClasses = useClassNames();
158
+ const localClasses = (uiSchema == null ? void 0 : uiSchema["ui:classNames"]) || {};
108
159
  const {
109
160
  setValue,
110
161
  watch,
@@ -124,76 +175,89 @@ var RichTextField = ({ name, schema, isRequired }) => {
124
175
  editor.commands.setContent(value || "");
125
176
  }
126
177
  }, [value, editor]);
127
- return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
128
- /* @__PURE__ */ jsxs("label", { className: "cdf-label", htmlFor: name, children: [
178
+ return /* @__PURE__ */ jsxs("div", { className: cx("cdf-field-group", globalClasses.fieldGroup, localClasses.fieldGroup), children: [
179
+ /* @__PURE__ */ jsxs("label", { className: cx("cdf-label", globalClasses.label, localClasses.label), htmlFor: name, children: [
129
180
  schema.title || name,
130
181
  isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
131
182
  ] }),
132
- /* @__PURE__ */ jsxs("div", { className: `cdf-rich-text-wrapper ${error ? "cdf-input--error" : ""}`, children: [
133
- /* @__PURE__ */ jsxs("div", { className: "cdf-rich-text-toolbar", children: [
134
- /* @__PURE__ */ jsx(
135
- "button",
136
- {
137
- type: "button",
138
- onClick: () => editor == null ? void 0 : editor.chain().focus().toggleBold().run(),
139
- className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("bold")) ? "is-active" : ""}`,
140
- children: /* @__PURE__ */ jsx(Bold, { size: 16 })
141
- }
142
- ),
143
- /* @__PURE__ */ jsx(
144
- "button",
145
- {
146
- type: "button",
147
- onClick: () => editor == null ? void 0 : editor.chain().focus().toggleItalic().run(),
148
- className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("italic")) ? "is-active" : ""}`,
149
- children: /* @__PURE__ */ jsx(Italic, { size: 16 })
150
- }
151
- ),
152
- /* @__PURE__ */ jsx(
153
- "button",
154
- {
155
- type: "button",
156
- onClick: () => editor == null ? void 0 : editor.chain().focus().toggleHeading({ level: 2 }).run(),
157
- className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("heading", { level: 2 })) ? "is-active" : ""}`,
158
- children: /* @__PURE__ */ jsx(Heading2, { size: 16 })
159
- }
160
- ),
161
- /* @__PURE__ */ jsx(
162
- "button",
163
- {
164
- type: "button",
165
- onClick: () => editor == null ? void 0 : editor.chain().focus().toggleBulletList().run(),
166
- className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("bulletList")) ? "is-active" : ""}`,
167
- children: /* @__PURE__ */ jsx(List, { size: 16 })
168
- }
183
+ /* @__PURE__ */ jsxs(
184
+ "div",
185
+ {
186
+ className: cx(
187
+ "cdf-rich-text-wrapper",
188
+ error && "cdf-input--error",
189
+ error && globalClasses.inputError,
190
+ error && localClasses.inputError
169
191
  ),
170
- /* @__PURE__ */ jsx(
171
- "button",
172
- {
173
- type: "button",
174
- onClick: () => editor == null ? void 0 : editor.chain().focus().toggleOrderedList().run(),
175
- className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("orderedList")) ? "is-active" : ""}`,
176
- children: /* @__PURE__ */ jsx(ListOrdered, { size: 16 })
177
- }
178
- )
179
- ] }),
180
- /* @__PURE__ */ jsx(EditorContent, { editor, className: "cdf-rich-text-content" })
181
- ] }),
182
- error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
192
+ children: [
193
+ /* @__PURE__ */ jsxs("div", { className: "cdf-rich-text-toolbar", children: [
194
+ /* @__PURE__ */ jsx(
195
+ "button",
196
+ {
197
+ type: "button",
198
+ onClick: () => editor == null ? void 0 : editor.chain().focus().toggleBold().run(),
199
+ className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("bold")) ? "is-active" : ""}`,
200
+ children: /* @__PURE__ */ jsx(Bold, { size: 16 })
201
+ }
202
+ ),
203
+ /* @__PURE__ */ jsx(
204
+ "button",
205
+ {
206
+ type: "button",
207
+ onClick: () => editor == null ? void 0 : editor.chain().focus().toggleItalic().run(),
208
+ className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("italic")) ? "is-active" : ""}`,
209
+ children: /* @__PURE__ */ jsx(Italic, { size: 16 })
210
+ }
211
+ ),
212
+ /* @__PURE__ */ jsx(
213
+ "button",
214
+ {
215
+ type: "button",
216
+ onClick: () => editor == null ? void 0 : editor.chain().focus().toggleHeading({ level: 2 }).run(),
217
+ className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("heading", { level: 2 })) ? "is-active" : ""}`,
218
+ children: /* @__PURE__ */ jsx(Heading2, { size: 16 })
219
+ }
220
+ ),
221
+ /* @__PURE__ */ jsx(
222
+ "button",
223
+ {
224
+ type: "button",
225
+ onClick: () => editor == null ? void 0 : editor.chain().focus().toggleBulletList().run(),
226
+ className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("bulletList")) ? "is-active" : ""}`,
227
+ children: /* @__PURE__ */ jsx(List, { size: 16 })
228
+ }
229
+ ),
230
+ /* @__PURE__ */ jsx(
231
+ "button",
232
+ {
233
+ type: "button",
234
+ onClick: () => editor == null ? void 0 : editor.chain().focus().toggleOrderedList().run(),
235
+ className: `cdf-toolbar-btn ${(editor == null ? void 0 : editor.isActive("orderedList")) ? "is-active" : ""}`,
236
+ children: /* @__PURE__ */ jsx(ListOrdered, { size: 16 })
237
+ }
238
+ )
239
+ ] }),
240
+ /* @__PURE__ */ jsx(EditorContent, { editor, className: "cdf-rich-text-content" })
241
+ ]
242
+ }
243
+ ),
244
+ error && /* @__PURE__ */ jsxs("span", { className: cx("cdf-error-message", globalClasses.errorText, localClasses.errorText), children: [
183
245
  /* @__PURE__ */ jsx(AlertCircle, { size: 14 }),
184
246
  error.message
185
247
  ] })
186
248
  ] });
187
249
  };
188
- var SelectField = ({ name, schema, isRequired }) => {
250
+ var SelectField = ({ name, schema, uiSchema, isRequired }) => {
189
251
  var _a;
252
+ const globalClasses = useClassNames();
253
+ const localClasses = (uiSchema == null ? void 0 : uiSchema["ui:classNames"]) || {};
190
254
  const {
191
255
  register,
192
256
  formState: { errors }
193
257
  } = useFormContext();
194
258
  const error = errors[name];
195
- return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
196
- /* @__PURE__ */ jsxs("label", { htmlFor: name, className: "cdf-label", children: [
259
+ return /* @__PURE__ */ jsxs("div", { className: cx("cdf-field-group", globalClasses.fieldGroup, localClasses.fieldGroup), children: [
260
+ /* @__PURE__ */ jsxs("label", { htmlFor: name, className: cx("cdf-label", globalClasses.label, localClasses.label), children: [
197
261
  schema.title || name,
198
262
  isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
199
263
  ] }),
@@ -202,14 +266,22 @@ var SelectField = ({ name, schema, isRequired }) => {
202
266
  {
203
267
  id: name,
204
268
  ...register(name),
205
- className: `cdf-input cdf-select ${error ? "cdf-input--error" : ""}`,
269
+ className: cx(
270
+ "cdf-input",
271
+ "cdf-select",
272
+ globalClasses.input,
273
+ localClasses.input,
274
+ error && "cdf-input--error",
275
+ error && globalClasses.inputError,
276
+ error && localClasses.inputError
277
+ ),
206
278
  children: [
207
279
  /* @__PURE__ */ jsx("option", { value: "", children: "Select an option..." }),
208
280
  (_a = schema.enum) == null ? void 0 : _a.map((option) => /* @__PURE__ */ jsx("option", { value: option, children: option }, option))
209
281
  ]
210
282
  }
211
283
  ) }),
212
- error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
284
+ error && /* @__PURE__ */ jsxs("span", { className: cx("cdf-error-message", globalClasses.errorText, localClasses.errorText), children: [
213
285
  /* @__PURE__ */ jsxs(
214
286
  "svg",
215
287
  {
@@ -230,23 +302,40 @@ var SelectField = ({ name, schema, isRequired }) => {
230
302
  ] })
231
303
  ] });
232
304
  };
233
- var RadioField = ({ name, schema, isRequired }) => {
305
+ var RadioField = ({ name, schema, uiSchema, isRequired }) => {
234
306
  var _a;
307
+ const globalClasses = useClassNames();
308
+ const localClasses = (uiSchema == null ? void 0 : uiSchema["ui:classNames"]) || {};
235
309
  const {
236
310
  register,
237
311
  formState: { errors }
238
312
  } = useFormContext();
239
313
  const error = errors[name];
240
- return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
241
- /* @__PURE__ */ jsxs("label", { className: "cdf-label", children: [
314
+ return /* @__PURE__ */ jsxs("div", { className: cx("cdf-field-group", globalClasses.fieldGroup, localClasses.fieldGroup), children: [
315
+ /* @__PURE__ */ jsxs("label", { className: cx("cdf-label", globalClasses.label, localClasses.label), children: [
242
316
  schema.title || name,
243
317
  isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
244
318
  ] }),
245
- /* @__PURE__ */ jsx("div", { className: "cdf-radio-group", children: (_a = schema.enum) == null ? void 0 : _a.map((option) => /* @__PURE__ */ jsxs("label", { className: "cdf-radio-label", children: [
246
- /* @__PURE__ */ jsx("input", { type: "radio", value: option, ...register(name), className: "cdf-radio-input" }),
319
+ /* @__PURE__ */ jsx("div", { className: cx("cdf-radio-group", globalClasses.radioGroup, localClasses.radioGroup), children: (_a = schema.enum) == null ? void 0 : _a.map((option) => /* @__PURE__ */ jsxs(
320
+ "label",
321
+ {
322
+ className: cx("cdf-radio-label", globalClasses.radioLabel, localClasses.radioLabel),
323
+ children: [
324
+ /* @__PURE__ */ jsx(
325
+ "input",
326
+ {
327
+ type: "radio",
328
+ value: option,
329
+ ...register(name),
330
+ className: cx("cdf-radio-input", globalClasses.radioInput, localClasses.radioInput)
331
+ }
332
+ ),
333
+ option
334
+ ]
335
+ },
247
336
  option
248
- ] }, option)) }),
249
- error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
337
+ )) }),
338
+ error && /* @__PURE__ */ jsxs("span", { className: cx("cdf-error-message", globalClasses.errorText, localClasses.errorText), children: [
250
339
  /* @__PURE__ */ jsxs(
251
340
  "svg",
252
341
  {
@@ -267,20 +356,58 @@ var RadioField = ({ name, schema, isRequired }) => {
267
356
  ] })
268
357
  ] });
269
358
  };
270
- var CheckboxField = ({ name, schema, isRequired }) => {
359
+ var CheckboxField = ({
360
+ name,
361
+ schema,
362
+ uiSchema,
363
+ isRequired
364
+ }) => {
365
+ const globalClasses = useClassNames();
366
+ const localClasses = (uiSchema == null ? void 0 : uiSchema["ui:classNames"]) || {};
271
367
  const {
272
368
  register,
273
369
  formState: { errors }
274
370
  } = useFormContext();
275
371
  const error = errors[name];
276
- return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
277
- /* @__PURE__ */ jsx("div", { className: "cdf-checkbox-group", children: /* @__PURE__ */ jsxs("label", { className: "cdf-checkbox-label", children: [
278
- /* @__PURE__ */ jsx("input", { type: "checkbox", ...register(name), className: "cdf-checkbox-input" }),
279
- schema.title || name,
280
- isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
281
- ] }) }),
372
+ return /* @__PURE__ */ jsxs("div", { className: cx("cdf-field-group", globalClasses.fieldGroup, localClasses.fieldGroup), children: [
373
+ /* @__PURE__ */ jsx(
374
+ "div",
375
+ {
376
+ className: cx(
377
+ "cdf-checkbox-group",
378
+ globalClasses.checkboxGroup,
379
+ localClasses.checkboxGroup
380
+ ),
381
+ children: /* @__PURE__ */ jsxs(
382
+ "label",
383
+ {
384
+ className: cx(
385
+ "cdf-checkbox-label",
386
+ globalClasses.checkboxLabel,
387
+ localClasses.checkboxLabel
388
+ ),
389
+ children: [
390
+ /* @__PURE__ */ jsx(
391
+ "input",
392
+ {
393
+ type: "checkbox",
394
+ ...register(name),
395
+ className: cx(
396
+ "cdf-checkbox-input",
397
+ globalClasses.checkboxInput,
398
+ localClasses.checkboxInput
399
+ )
400
+ }
401
+ ),
402
+ schema.title || name,
403
+ isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
404
+ ]
405
+ }
406
+ )
407
+ }
408
+ ),
282
409
  schema.description && /* @__PURE__ */ jsx("p", { style: { fontSize: "0.875rem", color: "var(--cdf-text-muted)", marginTop: "0.25rem" }, children: schema.description }),
283
- error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
410
+ error && /* @__PURE__ */ jsxs("span", { className: cx("cdf-error-message", globalClasses.errorText, localClasses.errorText), children: [
284
411
  /* @__PURE__ */ jsxs(
285
412
  "svg",
286
413
  {
@@ -304,8 +431,11 @@ var CheckboxField = ({ name, schema, isRequired }) => {
304
431
  var CheckboxGroupField = ({
305
432
  name,
306
433
  schema,
434
+ uiSchema,
307
435
  isRequired
308
436
  }) => {
437
+ const globalClasses = useClassNames();
438
+ const localClasses = (uiSchema == null ? void 0 : uiSchema["ui:classNames"]) || {};
309
439
  const {
310
440
  register,
311
441
  formState: { errors }
@@ -315,24 +445,49 @@ var CheckboxGroupField = ({
315
445
  if (schema.items && !Array.isArray(schema.items) && schema.items.enum) {
316
446
  options = schema.items.enum;
317
447
  }
318
- return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
319
- /* @__PURE__ */ jsxs("label", { className: "cdf-label", children: [
448
+ return /* @__PURE__ */ jsxs("div", { className: cx("cdf-field-group", globalClasses.fieldGroup, localClasses.fieldGroup), children: [
449
+ /* @__PURE__ */ jsxs("label", { className: cx("cdf-label", globalClasses.label, localClasses.label), children: [
320
450
  schema.title || name,
321
451
  isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
322
452
  ] }),
323
- /* @__PURE__ */ jsx("div", { className: "cdf-checkbox-group", children: options.map((option) => /* @__PURE__ */ jsxs("label", { className: "cdf-checkbox-label", children: [
324
- /* @__PURE__ */ jsx(
325
- "input",
326
- {
327
- type: "checkbox",
328
- value: option,
329
- ...register(name),
330
- className: "cdf-checkbox-input"
331
- }
332
- ),
333
- option
334
- ] }, option)) }),
335
- error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
453
+ /* @__PURE__ */ jsx(
454
+ "div",
455
+ {
456
+ className: cx(
457
+ "cdf-checkbox-group",
458
+ globalClasses.checkboxGroup,
459
+ localClasses.checkboxGroup
460
+ ),
461
+ children: options.map((option) => /* @__PURE__ */ jsxs(
462
+ "label",
463
+ {
464
+ className: cx(
465
+ "cdf-checkbox-label",
466
+ globalClasses.checkboxLabel,
467
+ localClasses.checkboxLabel
468
+ ),
469
+ children: [
470
+ /* @__PURE__ */ jsx(
471
+ "input",
472
+ {
473
+ type: "checkbox",
474
+ value: option,
475
+ ...register(name),
476
+ className: cx(
477
+ "cdf-checkbox-input",
478
+ globalClasses.checkboxInput,
479
+ localClasses.checkboxInput
480
+ )
481
+ }
482
+ ),
483
+ option
484
+ ]
485
+ },
486
+ option
487
+ ))
488
+ }
489
+ ),
490
+ error && /* @__PURE__ */ jsxs("span", { className: cx("cdf-error-message", globalClasses.errorText, localClasses.errorText), children: [
336
491
  /* @__PURE__ */ jsxs(
337
492
  "svg",
338
493
  {
@@ -353,7 +508,9 @@ var CheckboxGroupField = ({
353
508
  ] })
354
509
  ] });
355
510
  };
356
- var FileField = ({ name, schema, isRequired }) => {
511
+ var FileField = ({ name, schema, uiSchema, isRequired }) => {
512
+ const globalClasses = useClassNames();
513
+ const localClasses = (uiSchema == null ? void 0 : uiSchema["ui:classNames"]) || {};
357
514
  const {
358
515
  setValue,
359
516
  formState: { errors }
@@ -376,23 +533,36 @@ var FileField = ({ name, schema, isRequired }) => {
376
533
  };
377
534
  reader.readAsDataURL(file);
378
535
  };
379
- return /* @__PURE__ */ jsxs("div", { className: "cdf-field-group", children: [
380
- /* @__PURE__ */ jsxs("label", { className: "cdf-label", children: [
536
+ return /* @__PURE__ */ jsxs("div", { className: cx("cdf-field-group", globalClasses.fieldGroup, localClasses.fieldGroup), children: [
537
+ /* @__PURE__ */ jsxs("label", { className: cx("cdf-label", globalClasses.label, localClasses.label), children: [
381
538
  schema.title || name,
382
539
  isRequired && /* @__PURE__ */ jsx("span", { className: "cdf-required-mark", children: "*" })
383
540
  ] }),
384
- /* @__PURE__ */ jsxs("div", { className: `cdf-file-wrapper ${error ? "cdf-input--error" : ""}`, children: [
385
- /* @__PURE__ */ jsx("input", { type: "file", className: "cdf-file-input", onChange: handleFileChange }),
386
- /* @__PURE__ */ jsxs("div", { className: "cdf-file-text", children: [
387
- /* @__PURE__ */ jsx("span", { children: "Click to upload" }),
388
- " or drag and drop"
389
- ] }),
390
- fileName && /* @__PURE__ */ jsxs("div", { className: "cdf-file-preview", children: [
391
- "Selected: ",
392
- /* @__PURE__ */ jsx("strong", { children: fileName })
393
- ] })
394
- ] }),
395
- error && /* @__PURE__ */ jsxs("span", { className: "cdf-error-message", children: [
541
+ /* @__PURE__ */ jsxs(
542
+ "div",
543
+ {
544
+ className: cx(
545
+ "cdf-file-wrapper",
546
+ globalClasses.fileWrapper,
547
+ localClasses.fileWrapper,
548
+ error && "cdf-input--error",
549
+ error && globalClasses.inputError,
550
+ error && localClasses.inputError
551
+ ),
552
+ children: [
553
+ /* @__PURE__ */ jsx("input", { type: "file", className: "cdf-file-input", onChange: handleFileChange }),
554
+ /* @__PURE__ */ jsxs("div", { className: cx("cdf-file-text", globalClasses.fileText, localClasses.fileText), children: [
555
+ /* @__PURE__ */ jsx("span", { children: "Click to upload" }),
556
+ " or drag and drop"
557
+ ] }),
558
+ fileName && /* @__PURE__ */ jsxs("div", { className: "cdf-file-preview", children: [
559
+ "Selected: ",
560
+ /* @__PURE__ */ jsx("strong", { children: fileName })
561
+ ] })
562
+ ]
563
+ }
564
+ ),
565
+ error && /* @__PURE__ */ jsxs("span", { className: cx("cdf-error-message", globalClasses.errorText, localClasses.errorText), children: [
396
566
  /* @__PURE__ */ jsxs(
397
567
  "svg",
398
568
  {
@@ -423,31 +593,39 @@ var FieldRenderer = ({
423
593
  const widget = uiSchema == null ? void 0 : uiSchema["ui:widget"];
424
594
  const renderField = () => {
425
595
  if (schema.type === "array") {
426
- return /* @__PURE__ */ jsx(CheckboxGroupField, { name, schema, isRequired });
596
+ return /* @__PURE__ */ jsx(
597
+ CheckboxGroupField,
598
+ {
599
+ name,
600
+ schema,
601
+ uiSchema,
602
+ isRequired
603
+ }
604
+ );
427
605
  }
428
606
  if (schema.type === "boolean") {
429
- return /* @__PURE__ */ jsx(CheckboxField, { name, schema, isRequired });
607
+ return /* @__PURE__ */ jsx(CheckboxField, { name, schema, uiSchema, isRequired });
430
608
  }
431
609
  if (schema.enum) {
432
610
  if (widget === "radio") {
433
- return /* @__PURE__ */ jsx(RadioField, { name, schema, isRequired });
611
+ return /* @__PURE__ */ jsx(RadioField, { name, schema, uiSchema, isRequired });
434
612
  }
435
- return /* @__PURE__ */ jsx(SelectField, { name, schema, isRequired });
613
+ return /* @__PURE__ */ jsx(SelectField, { name, schema, uiSchema, isRequired });
436
614
  }
437
615
  if (schema.type === "string") {
438
616
  if (schema.format === "data-url") {
439
- return /* @__PURE__ */ jsx(FileField, { name, schema, isRequired });
617
+ return /* @__PURE__ */ jsx(FileField, { name, schema, uiSchema, isRequired });
440
618
  }
441
619
  if (schema.format === "password") {
442
- return /* @__PURE__ */ jsx(PasswordField, { name, schema, isRequired });
620
+ return /* @__PURE__ */ jsx(PasswordField, { name, schema, uiSchema, isRequired });
443
621
  }
444
622
  if (schema.format === "rich-text") {
445
- return /* @__PURE__ */ jsx(RichTextField, { name, schema, isRequired });
623
+ return /* @__PURE__ */ jsx(RichTextField, { name, schema, uiSchema, isRequired });
446
624
  }
447
- return /* @__PURE__ */ jsx(TextField, { name, schema, isRequired });
625
+ return /* @__PURE__ */ jsx(TextField, { name, schema, uiSchema, isRequired });
448
626
  }
449
627
  if (schema.type === "number" || schema.type === "integer") {
450
- return /* @__PURE__ */ jsx(NumberField, { name, schema, isRequired });
628
+ return /* @__PURE__ */ jsx(NumberField, { name, schema, uiSchema, isRequired });
451
629
  }
452
630
  return /* @__PURE__ */ jsx("div", { className: "cdf-field-group", children: /* @__PURE__ */ jsxs("p", { className: "cdf-error-message", children: [
453
631
  "Unsupported field type: ",
@@ -462,7 +640,8 @@ var SchemaForm = ({
462
640
  onSubmit,
463
641
  defaultValues,
464
642
  columns = 1,
465
- theme
643
+ theme,
644
+ classNames = {}
466
645
  }) => {
467
646
  const methods = useForm({
468
647
  resolver: ajvResolver(schema, {
@@ -486,10 +665,17 @@ var SchemaForm = ({
486
665
  "--cdf-surface": theme.surface,
487
666
  "--cdf-border": theme.border
488
667
  } : {};
489
- return /* @__PURE__ */ jsxs("div", { className: "cdf-form-container", style: themeStyles, children: [
490
- schema.title && /* @__PURE__ */ jsx("h2", { className: "cdf-form-title", children: schema.title }),
491
- schema.description && /* @__PURE__ */ jsx("p", { style: { color: "var(--cdf-text-muted)", marginBottom: "1.5rem" }, children: schema.description }),
492
- /* @__PURE__ */ jsx(FormProvider, { ...methods, children: /* @__PURE__ */ jsxs("form", { onSubmit: methods.handleSubmit(onSubmit), noValidate: true, children: [
668
+ return /* @__PURE__ */ jsx(ClassNamesProvider, { value: classNames, children: /* @__PURE__ */ jsxs("div", { className: cx("cdf-form-container", classNames.container), style: themeStyles, children: [
669
+ schema.title && /* @__PURE__ */ jsx("h2", { className: cx("cdf-form-title", classNames.title), children: schema.title }),
670
+ schema.description && /* @__PURE__ */ jsx(
671
+ "p",
672
+ {
673
+ className: classNames.description,
674
+ style: { color: "var(--cdf-text-muted)", marginBottom: "1.5rem" },
675
+ children: schema.description
676
+ }
677
+ ),
678
+ /* @__PURE__ */ jsx(FormProvider, { ...methods, children: /* @__PURE__ */ jsxs("form", { className: classNames.form, onSubmit: methods.handleSubmit(onSubmit), noValidate: true, children: [
493
679
  /* @__PURE__ */ jsx("div", { className: `cdf-form-grid-${columns}`, children: Object.entries(schema.properties).map(([key, propSchema]) => {
494
680
  var _a;
495
681
  return /* @__PURE__ */ jsx(
@@ -503,11 +689,1439 @@ var SchemaForm = ({
503
689
  key
504
690
  );
505
691
  }) }),
506
- /* @__PURE__ */ jsx("button", { type: "submit", className: "cdf-submit-btn", children: "Submit" })
692
+ /* @__PURE__ */ jsx("button", { type: "submit", className: cx("cdf-submit-btn", classNames.submitButton), children: "Submit" })
507
693
  ] }) })
508
- ] });
694
+ ] }) });
695
+ };
696
+
697
+ // src/builder/types.ts
698
+ var FIELD_TEMPLATES = {
699
+ text: {
700
+ type: "text",
701
+ schema: { type: "string", title: "New Text Field" }
702
+ },
703
+ number: {
704
+ type: "number",
705
+ schema: { type: "number", title: "New Number Field" }
706
+ },
707
+ email: {
708
+ type: "email",
709
+ schema: { type: "string", format: "email", title: "Email Address" }
710
+ },
711
+ password: {
712
+ type: "password",
713
+ schema: { type: "string", format: "password", title: "Password" }
714
+ },
715
+ "rich-text": {
716
+ type: "rich-text",
717
+ schema: { type: "string", format: "rich-text", title: "Rich Text" }
718
+ },
719
+ file: {
720
+ type: "file",
721
+ schema: { type: "string", format: "data-url", title: "File Upload" }
722
+ },
723
+ checkbox: {
724
+ type: "checkbox",
725
+ schema: { type: "boolean", title: "Checkbox" }
726
+ },
727
+ checkboxes: {
728
+ type: "checkboxes",
729
+ schema: {
730
+ type: "array",
731
+ title: "Multiple Checkboxes",
732
+ items: { type: "string", enum: ["Option 1", "Option 2"] }
733
+ }
734
+ },
735
+ select: {
736
+ type: "select",
737
+ schema: { type: "string", title: "Dropdown", enum: ["Option 1", "Option 2"] }
738
+ },
739
+ radio: {
740
+ type: "radio",
741
+ schema: { type: "string", title: "Radio Buttons", enum: ["Option 1", "Option 2"] },
742
+ uiSchema: { "ui:widget": "radio" }
743
+ }
744
+ };
745
+
746
+ // src/builder/useFormBuilder.ts
747
+ var useFormBuilder = (initialSchema, initialUiSchema, initialColumns, initialTheme) => {
748
+ const [fields, setFields] = useState(() => {
749
+ if (!initialSchema || !initialSchema.properties) return [];
750
+ return Object.entries(initialSchema.properties).map(([key, propSchema]) => {
751
+ var _a;
752
+ let type = "text";
753
+ if (propSchema.type === "string") {
754
+ if (propSchema.format === "email") type = "email";
755
+ else if (propSchema.format === "password") type = "password";
756
+ else if (propSchema.format === "data-url") type = "file";
757
+ else if (propSchema.format === "rich-text") type = "rich-text";
758
+ else if (propSchema.enum) type = "select";
759
+ } else if (propSchema.type === "number" || propSchema.type === "integer") {
760
+ type = "number";
761
+ } else if (propSchema.type === "boolean") {
762
+ type = "checkbox";
763
+ } else if (propSchema.type === "array") {
764
+ type = "checkboxes";
765
+ }
766
+ const uiSchema = initialUiSchema == null ? void 0 : initialUiSchema[key];
767
+ if (propSchema.enum && (uiSchema == null ? void 0 : uiSchema["ui:widget"]) === "radio") {
768
+ type = "radio";
769
+ }
770
+ return {
771
+ id: v4(),
772
+ key,
773
+ type,
774
+ schema: propSchema,
775
+ uiSchema,
776
+ isRequired: (_a = initialSchema.required) == null ? void 0 : _a.includes(key)
777
+ };
778
+ });
779
+ });
780
+ const [selectedFieldId, setSelectedFieldId] = useState(null);
781
+ const addField = useCallback((type, index) => {
782
+ const template = FIELD_TEMPLATES[type];
783
+ const newField = {
784
+ id: v4(),
785
+ key: `field_${Date.now()}`,
786
+ type,
787
+ // Deep clone template schemas
788
+ schema: JSON.parse(JSON.stringify(template.schema)),
789
+ uiSchema: template.uiSchema ? JSON.parse(JSON.stringify(template.uiSchema)) : void 0
790
+ };
791
+ setFields((prev) => {
792
+ if (typeof index === "number") {
793
+ const newFields = [...prev];
794
+ newFields.splice(index, 0, newField);
795
+ return newFields;
796
+ }
797
+ return [...prev, newField];
798
+ });
799
+ setSelectedFieldId(newField.id);
800
+ }, []);
801
+ const removeField = useCallback(
802
+ (id) => {
803
+ setFields((prev) => prev.filter((f) => f.id !== id));
804
+ if (selectedFieldId === id) setSelectedFieldId(null);
805
+ },
806
+ [selectedFieldId]
807
+ );
808
+ const updateField = useCallback((id, updates) => {
809
+ setFields((prev) => prev.map((f) => f.id === id ? { ...f, ...updates } : f));
810
+ }, []);
811
+ const reorderFields = useCallback((activeId, overId) => {
812
+ setFields((prev) => {
813
+ const oldIndex = prev.findIndex((f) => f.id === activeId);
814
+ const newIndex = prev.findIndex((f) => f.id === overId);
815
+ return arrayMove(prev, oldIndex, newIndex);
816
+ });
817
+ }, []);
818
+ const selectedField = useMemo(
819
+ () => fields.find((f) => f.id === selectedFieldId),
820
+ [fields, selectedFieldId]
821
+ );
822
+ const compileSchemas = useCallback(() => {
823
+ var _a;
824
+ const finalSchema = {
825
+ type: "object",
826
+ title: (initialSchema == null ? void 0 : initialSchema.title) || "Generated Form",
827
+ description: (initialSchema == null ? void 0 : initialSchema.description) || "",
828
+ properties: {},
829
+ required: []
830
+ };
831
+ const finalUiSchema = {};
832
+ fields.forEach((field) => {
833
+ if (finalSchema.properties) {
834
+ finalSchema.properties[field.key] = field.schema;
835
+ }
836
+ if (field.isRequired && finalSchema.required) {
837
+ finalSchema.required.push(field.key);
838
+ }
839
+ if (field.uiSchema) {
840
+ finalUiSchema[field.key] = field.uiSchema;
841
+ }
842
+ });
843
+ if (((_a = finalSchema.required) == null ? void 0 : _a.length) === 0) {
844
+ delete finalSchema.required;
845
+ }
846
+ return { schema: finalSchema, uiSchema: finalUiSchema };
847
+ }, [fields, initialSchema]);
848
+ const [formSettings, setFormSettings] = useState({
849
+ columns: initialColumns || 1,
850
+ theme: initialTheme || {}
851
+ });
852
+ const updateFormSettings = useCallback((updates) => {
853
+ setFormSettings((prev) => ({
854
+ ...prev,
855
+ ...updates,
856
+ theme: { ...prev.theme, ...updates.theme || {} }
857
+ }));
858
+ }, []);
859
+ return {
860
+ fields,
861
+ selectedFieldId,
862
+ setSelectedFieldId,
863
+ selectedField,
864
+ addField,
865
+ removeField,
866
+ updateField,
867
+ reorderFields,
868
+ compileSchemas,
869
+ formSettings,
870
+ updateFormSettings
871
+ };
872
+ };
873
+ var TOOLS = [
874
+ { type: "text", label: "Text Field", icon: /* @__PURE__ */ jsx(Type, { size: 18 }) },
875
+ { type: "number", label: "Number", icon: /* @__PURE__ */ jsx(Hash, { size: 18 }) },
876
+ { type: "email", label: "Email", icon: /* @__PURE__ */ jsx(Mail, { size: 18 }) },
877
+ { type: "password", label: "Password", icon: /* @__PURE__ */ jsx(Key, { size: 18 }) },
878
+ { type: "rich-text", label: "Rich Text", icon: /* @__PURE__ */ jsx(AlignLeft, { size: 18 }) },
879
+ { type: "select", label: "Dropdown", icon: /* @__PURE__ */ jsx(ChevronDown, { size: 18 }) },
880
+ { type: "radio", label: "Radio Group", icon: /* @__PURE__ */ jsx(CheckCircle2, { size: 18 }) },
881
+ { type: "checkbox", label: "Checkbox", icon: /* @__PURE__ */ jsx(CheckSquare, { size: 18 }) },
882
+ { type: "checkboxes", label: "Checkbox Group", icon: /* @__PURE__ */ jsx(List, { size: 18 }) },
883
+ { type: "file", label: "File Upload", icon: /* @__PURE__ */ jsx(FileUp, { size: 18 }) }
884
+ ];
885
+ var DraggableTool = ({
886
+ type,
887
+ label,
888
+ icon
889
+ }) => {
890
+ const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
891
+ id: `toolbox-${type}`,
892
+ data: {
893
+ type: "ToolboxItem",
894
+ fieldType: type
895
+ }
896
+ });
897
+ return /* @__PURE__ */ jsxs(
898
+ "div",
899
+ {
900
+ ref: setNodeRef,
901
+ ...listeners,
902
+ ...attributes,
903
+ style: {
904
+ display: "flex",
905
+ alignItems: "center",
906
+ gap: "0.75rem",
907
+ padding: "0.75rem",
908
+ backgroundColor: "white",
909
+ border: "1px solid #e5e7eb",
910
+ borderRadius: "0.5rem",
911
+ cursor: isDragging ? "grabbing" : "grab",
912
+ opacity: isDragging ? 0.5 : 1,
913
+ marginBottom: "0.5rem",
914
+ boxShadow: "0 1px 2px rgba(0,0,0,0.05)",
915
+ transition: "all 0.2s"
916
+ },
917
+ onMouseEnter: (e) => {
918
+ e.currentTarget.style.borderColor = "#6366f1";
919
+ e.currentTarget.style.boxShadow = "0 4px 6px rgba(99, 102, 241, 0.1)";
920
+ },
921
+ onMouseLeave: (e) => {
922
+ e.currentTarget.style.borderColor = "#e5e7eb";
923
+ e.currentTarget.style.boxShadow = "0 1px 2px rgba(0,0,0,0.05)";
924
+ },
925
+ children: [
926
+ /* @__PURE__ */ jsx("div", { style: { color: "#6b7280" }, children: icon }),
927
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: label })
928
+ ]
929
+ }
930
+ );
931
+ };
932
+ var Toolbox = () => {
933
+ return /* @__PURE__ */ jsxs(
934
+ "div",
935
+ {
936
+ style: {
937
+ padding: "1.5rem",
938
+ width: "280px",
939
+ borderRight: "1px solid #e5e7eb",
940
+ backgroundColor: "#f9fafb",
941
+ height: "100%",
942
+ overflowY: "auto"
943
+ },
944
+ children: [
945
+ /* @__PURE__ */ jsx("h3", { style: { fontSize: "1rem", fontWeight: 600, color: "#111827", marginBottom: "1rem" }, children: "Form Elements" }),
946
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "0.875rem", color: "#6b7280", marginBottom: "1.5rem" }, children: "Drag and drop fields onto the canvas to build your form." }),
947
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: TOOLS.map((tool) => /* @__PURE__ */ jsx(DraggableTool, { ...tool }, tool.type)) })
948
+ ]
949
+ }
950
+ );
951
+ };
952
+ var SortableField = ({
953
+ field,
954
+ isSelected,
955
+ onClick,
956
+ onRemove,
957
+ onDuplicate
958
+ }) => {
959
+ var _a, _b;
960
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
961
+ id: field.id,
962
+ data: {
963
+ type: "SortableField",
964
+ field
965
+ }
966
+ });
967
+ const style = {
968
+ transform: CSS.Transform.toString(transform),
969
+ transition,
970
+ opacity: isDragging ? 0.6 : 1,
971
+ position: "relative",
972
+ zIndex: isDragging ? 10 : 1,
973
+ padding: "2rem 1.5rem 1.5rem",
974
+ // Extra top padding for drag handle
975
+ backgroundColor: "white",
976
+ borderRadius: "0.75rem",
977
+ border: `2px solid ${isSelected ? "#6366f1" : "#e5e7eb"}`,
978
+ boxShadow: isSelected ? "0 4px 12px rgba(99, 102, 241, 0.15)" : "0 1px 3px rgba(0,0,0,0.05)",
979
+ marginBottom: "1rem",
980
+ cursor: "pointer",
981
+ gridColumn: `span ${((_a = field.uiSchema) == null ? void 0 : _a["ui:columnSpan"]) || 1} / span ${((_b = field.uiSchema) == null ? void 0 : _b["ui:columnSpan"]) || 1}`
982
+ };
983
+ const methods = useForm();
984
+ return /* @__PURE__ */ jsxs(
985
+ "div",
986
+ {
987
+ ref: setNodeRef,
988
+ style,
989
+ onClick: (e) => {
990
+ e.stopPropagation();
991
+ onClick();
992
+ },
993
+ children: [
994
+ /* @__PURE__ */ jsx(
995
+ "div",
996
+ {
997
+ ...attributes,
998
+ ...listeners,
999
+ style: {
1000
+ position: "absolute",
1001
+ top: "0",
1002
+ left: "50%",
1003
+ transform: "translateX(-50%)",
1004
+ width: "40px",
1005
+ height: "24px",
1006
+ backgroundColor: isSelected ? "#eef2ff" : "#f3f4f6",
1007
+ borderBottomLeftRadius: "8px",
1008
+ borderBottomRightRadius: "8px",
1009
+ display: "flex",
1010
+ alignItems: "center",
1011
+ justifyContent: "center",
1012
+ cursor: isDragging ? "grabbing" : "grab",
1013
+ color: isSelected ? "#6366f1" : "#9ca3af",
1014
+ zIndex: 2
1015
+ },
1016
+ onClick: (e) => e.stopPropagation(),
1017
+ children: /* @__PURE__ */ jsx(GripVertical, { size: 16 })
1018
+ }
1019
+ ),
1020
+ /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
1021
+ /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, zIndex: 1, cursor: "pointer" } }),
1022
+ /* @__PURE__ */ jsx("div", { style: { pointerEvents: "none" }, children: /* @__PURE__ */ jsx(FormProvider, { ...methods, children: /* @__PURE__ */ jsx("form", { children: /* @__PURE__ */ jsx(
1023
+ FieldRenderer,
1024
+ {
1025
+ name: field.key,
1026
+ schema: field.schema,
1027
+ uiSchema: field.uiSchema,
1028
+ isRequired: field.isRequired
1029
+ }
1030
+ ) }) }) })
1031
+ ] }),
1032
+ isSelected && /* @__PURE__ */ jsxs(
1033
+ "div",
1034
+ {
1035
+ style: {
1036
+ position: "absolute",
1037
+ top: "-12px",
1038
+ right: "1rem",
1039
+ display: "flex",
1040
+ gap: "0.25rem",
1041
+ backgroundColor: "#ffffff",
1042
+ border: "1px solid #e5e7eb",
1043
+ padding: "0.25rem",
1044
+ borderRadius: "0.5rem",
1045
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
1046
+ zIndex: 10
1047
+ },
1048
+ children: [
1049
+ /* @__PURE__ */ jsx(
1050
+ "button",
1051
+ {
1052
+ onClick: (e) => {
1053
+ e.stopPropagation();
1054
+ onDuplicate();
1055
+ },
1056
+ style: {
1057
+ color: "#4f46e5",
1058
+ backgroundColor: "#eef2ff",
1059
+ border: "none",
1060
+ cursor: "pointer",
1061
+ padding: "0.375rem",
1062
+ borderRadius: "0.375rem",
1063
+ display: "flex",
1064
+ alignItems: "center",
1065
+ justifyContent: "center"
1066
+ },
1067
+ title: "Duplicate Field",
1068
+ children: /* @__PURE__ */ jsx(Copy, { size: 14 })
1069
+ }
1070
+ ),
1071
+ /* @__PURE__ */ jsx(
1072
+ "button",
1073
+ {
1074
+ onClick: (e) => {
1075
+ e.stopPropagation();
1076
+ onRemove();
1077
+ },
1078
+ style: {
1079
+ color: "#ef4444",
1080
+ backgroundColor: "#fef2f2",
1081
+ border: "none",
1082
+ cursor: "pointer",
1083
+ padding: "0.375rem",
1084
+ borderRadius: "0.375rem",
1085
+ display: "flex",
1086
+ alignItems: "center",
1087
+ justifyContent: "center"
1088
+ },
1089
+ title: "Remove Field",
1090
+ children: /* @__PURE__ */ jsx(Trash2, { size: 14 })
1091
+ }
1092
+ )
1093
+ ]
1094
+ }
1095
+ )
1096
+ ]
1097
+ }
1098
+ );
1099
+ };
1100
+ var Canvas = ({
1101
+ fields,
1102
+ selectedFieldId,
1103
+ onSelectField,
1104
+ onRemoveField,
1105
+ onDuplicateField
1106
+ }) => {
1107
+ const { setNodeRef, isOver } = useDroppable({
1108
+ id: "canvas-droppable",
1109
+ data: {
1110
+ type: "Canvas"
1111
+ }
1112
+ });
1113
+ return /* @__PURE__ */ jsx(
1114
+ "div",
1115
+ {
1116
+ style: {
1117
+ flex: 1,
1118
+ padding: "2rem",
1119
+ backgroundColor: "#f3f4f6",
1120
+ overflowY: "auto",
1121
+ display: "flex",
1122
+ flexDirection: "column",
1123
+ alignItems: "center"
1124
+ },
1125
+ onClick: () => onSelectField(""),
1126
+ children: /* @__PURE__ */ jsx(
1127
+ "div",
1128
+ {
1129
+ ref: setNodeRef,
1130
+ style: {
1131
+ width: "100%",
1132
+ maxWidth: "800px",
1133
+ minHeight: "400px",
1134
+ backgroundColor: fields.length === 0 ? "transparent" : "white",
1135
+ border: fields.length === 0 ? "2px dashed #d1d5db" : "1px solid #e5e7eb",
1136
+ borderRadius: "0.75rem",
1137
+ padding: fields.length === 0 ? "0" : "2rem",
1138
+ display: "flex",
1139
+ flexDirection: "column",
1140
+ boxShadow: fields.length === 0 ? "none" : "0 10px 15px -3px rgba(0, 0, 0, 0.1)",
1141
+ transition: "all 0.2s ease",
1142
+ ...isOver && fields.length === 0 ? { backgroundColor: "#eef2ff", borderColor: "#6366f1" } : {}
1143
+ },
1144
+ children: fields.length === 0 ? /* @__PURE__ */ jsxs("div", { style: { margin: "auto", textAlign: "center", color: "#6b7280" }, children: [
1145
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "1.125rem", fontWeight: 500, marginBottom: "0.5rem" }, children: "Your form is empty" }),
1146
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "0.875rem" }, children: "Drag and drop a field from the left panel to get started." })
1147
+ ] }) : /* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: "1rem" }, children: /* @__PURE__ */ jsx(SortableContext, { items: fields.map((f) => f.id), strategy: verticalListSortingStrategy, children: fields.map((field) => /* @__PURE__ */ jsx(
1148
+ SortableField,
1149
+ {
1150
+ field,
1151
+ isSelected: selectedFieldId === field.id,
1152
+ onClick: () => onSelectField(field.id),
1153
+ onRemove: () => onRemoveField(field.id),
1154
+ onDuplicate: () => onDuplicateField(field)
1155
+ },
1156
+ field.id
1157
+ )) }) })
1158
+ }
1159
+ )
1160
+ }
1161
+ );
1162
+ };
1163
+ var PropertiesPanel = ({
1164
+ field,
1165
+ formSettings,
1166
+ onUpdate,
1167
+ onUpdateSettings
1168
+ }) => {
1169
+ var _a, _b, _c, _d, _e, _f, _g;
1170
+ const [activeTab, setActiveTab] = useState("general");
1171
+ if (!field) {
1172
+ return /* @__PURE__ */ jsxs(
1173
+ "div",
1174
+ {
1175
+ style: {
1176
+ width: "320px",
1177
+ borderLeft: "1px solid #e5e7eb",
1178
+ backgroundColor: "white",
1179
+ display: "flex",
1180
+ flexDirection: "column",
1181
+ height: "100%",
1182
+ overflowY: "auto"
1183
+ },
1184
+ children: [
1185
+ /* @__PURE__ */ jsxs(
1186
+ "div",
1187
+ {
1188
+ style: {
1189
+ padding: "1.5rem",
1190
+ borderBottom: "1px solid #e5e7eb",
1191
+ backgroundColor: "#f9fafb"
1192
+ },
1193
+ children: [
1194
+ /* @__PURE__ */ jsx("h3", { style: { fontSize: "1.125rem", fontWeight: 600, color: "#111827", margin: 0 }, children: "Global Form Settings" }),
1195
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "0.875rem", color: "#6b7280", margin: "0.25rem 0 0" }, children: "Click a field to edit its properties, or configure global form settings here." })
1196
+ ]
1197
+ }
1198
+ ),
1199
+ /* @__PURE__ */ jsxs("div", { style: { padding: "1.5rem", display: "flex", flexDirection: "column", gap: "1.5rem" }, children: [
1200
+ /* @__PURE__ */ jsxs("div", { children: [
1201
+ /* @__PURE__ */ jsxs(
1202
+ "h4",
1203
+ {
1204
+ style: {
1205
+ fontSize: "0.875rem",
1206
+ fontWeight: 600,
1207
+ color: "#374151",
1208
+ marginBottom: "0.75rem",
1209
+ display: "flex",
1210
+ alignItems: "center",
1211
+ gap: "0.375rem"
1212
+ },
1213
+ children: [
1214
+ /* @__PURE__ */ jsx(LayoutTemplate, { size: 16 }),
1215
+ " Layout Options"
1216
+ ]
1217
+ }
1218
+ ),
1219
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1220
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: "Global Columns" }),
1221
+ /* @__PURE__ */ jsxs(
1222
+ "select",
1223
+ {
1224
+ value: formSettings.columns,
1225
+ onChange: (e) => onUpdateSettings({ columns: Number(e.target.value) }),
1226
+ style: {
1227
+ width: "100%",
1228
+ padding: "0.5rem",
1229
+ border: "1px solid #d1d5db",
1230
+ borderRadius: "0.375rem",
1231
+ fontSize: "0.875rem"
1232
+ },
1233
+ children: [
1234
+ /* @__PURE__ */ jsx("option", { value: 1, children: "1 Column" }),
1235
+ /* @__PURE__ */ jsx("option", { value: 2, children: "2 Columns" }),
1236
+ /* @__PURE__ */ jsx("option", { value: 3, children: "3 Columns" }),
1237
+ /* @__PURE__ */ jsx("option", { value: 4, children: "4 Columns" })
1238
+ ]
1239
+ }
1240
+ )
1241
+ ] })
1242
+ ] }),
1243
+ /* @__PURE__ */ jsxs("div", { children: [
1244
+ /* @__PURE__ */ jsxs(
1245
+ "h4",
1246
+ {
1247
+ style: {
1248
+ fontSize: "0.875rem",
1249
+ fontWeight: 600,
1250
+ color: "#374151",
1251
+ marginBottom: "0.75rem",
1252
+ display: "flex",
1253
+ alignItems: "center",
1254
+ gap: "0.375rem"
1255
+ },
1256
+ children: [
1257
+ /* @__PURE__ */ jsx(Palette, { size: 16 }),
1258
+ " Theme Colors"
1259
+ ]
1260
+ }
1261
+ ),
1262
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
1263
+ /* @__PURE__ */ jsxs(
1264
+ "div",
1265
+ {
1266
+ style: {
1267
+ display: "flex",
1268
+ alignItems: "center",
1269
+ justifyContent: "space-between",
1270
+ gap: "0.5rem"
1271
+ },
1272
+ children: [
1273
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#4b5563" }, children: "Primary Color" }),
1274
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1275
+ /* @__PURE__ */ jsx(
1276
+ "input",
1277
+ {
1278
+ type: "color",
1279
+ value: formSettings.theme.primary || "#6366f1",
1280
+ onChange: (e) => onUpdateSettings({
1281
+ theme: { ...formSettings.theme, primary: e.target.value }
1282
+ }),
1283
+ style: {
1284
+ width: "28px",
1285
+ height: "28px",
1286
+ padding: "0",
1287
+ border: "none",
1288
+ borderRadius: "4px",
1289
+ cursor: "pointer"
1290
+ }
1291
+ }
1292
+ ),
1293
+ /* @__PURE__ */ jsx(
1294
+ "input",
1295
+ {
1296
+ type: "text",
1297
+ value: formSettings.theme.primary || "",
1298
+ placeholder: "#6366f1",
1299
+ onChange: (e) => onUpdateSettings({
1300
+ theme: { ...formSettings.theme, primary: e.target.value }
1301
+ }),
1302
+ style: {
1303
+ width: "80px",
1304
+ padding: "0.25rem 0.5rem",
1305
+ border: "1px solid #d1d5db",
1306
+ borderRadius: "0.25rem",
1307
+ fontSize: "0.75rem",
1308
+ fontFamily: "monospace"
1309
+ }
1310
+ }
1311
+ )
1312
+ ] })
1313
+ ]
1314
+ }
1315
+ ),
1316
+ /* @__PURE__ */ jsxs(
1317
+ "div",
1318
+ {
1319
+ style: {
1320
+ display: "flex",
1321
+ alignItems: "center",
1322
+ justifyContent: "space-between",
1323
+ gap: "0.5rem"
1324
+ },
1325
+ children: [
1326
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#4b5563" }, children: "Background Color" }),
1327
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1328
+ /* @__PURE__ */ jsx(
1329
+ "input",
1330
+ {
1331
+ type: "color",
1332
+ value: formSettings.theme.background || "#ffffff",
1333
+ onChange: (e) => onUpdateSettings({
1334
+ theme: { ...formSettings.theme, background: e.target.value }
1335
+ }),
1336
+ style: {
1337
+ width: "28px",
1338
+ height: "28px",
1339
+ padding: "0",
1340
+ border: "none",
1341
+ borderRadius: "4px",
1342
+ cursor: "pointer"
1343
+ }
1344
+ }
1345
+ ),
1346
+ /* @__PURE__ */ jsx(
1347
+ "input",
1348
+ {
1349
+ type: "text",
1350
+ value: formSettings.theme.background || "",
1351
+ placeholder: "#ffffff",
1352
+ onChange: (e) => onUpdateSettings({
1353
+ theme: { ...formSettings.theme, background: e.target.value }
1354
+ }),
1355
+ style: {
1356
+ width: "80px",
1357
+ padding: "0.25rem 0.5rem",
1358
+ border: "1px solid #d1d5db",
1359
+ borderRadius: "0.25rem",
1360
+ fontSize: "0.75rem",
1361
+ fontFamily: "monospace"
1362
+ }
1363
+ }
1364
+ )
1365
+ ] })
1366
+ ]
1367
+ }
1368
+ )
1369
+ ] })
1370
+ ] })
1371
+ ] })
1372
+ ]
1373
+ }
1374
+ );
1375
+ }
1376
+ const handleSchemaChange = (key, value) => {
1377
+ onUpdate(field.id, {
1378
+ schema: { ...field.schema, [key]: value }
1379
+ });
1380
+ };
1381
+ const handleUiSchemaChange = (key, value) => {
1382
+ onUpdate(field.id, {
1383
+ uiSchema: { ...field.uiSchema || {}, [key]: value }
1384
+ });
1385
+ };
1386
+ const handleClassNamesChange = (element, value) => {
1387
+ var _a2;
1388
+ const existingUiClassNames = ((_a2 = field.uiSchema) == null ? void 0 : _a2["ui:classNames"]) || {};
1389
+ handleUiSchemaChange("ui:classNames", {
1390
+ ...existingUiClassNames,
1391
+ [element]: value
1392
+ });
1393
+ };
1394
+ return /* @__PURE__ */ jsxs(
1395
+ "div",
1396
+ {
1397
+ style: {
1398
+ width: "320px",
1399
+ borderLeft: "1px solid #e5e7eb",
1400
+ backgroundColor: "white",
1401
+ display: "flex",
1402
+ flexDirection: "column",
1403
+ height: "100%",
1404
+ overflowY: "auto"
1405
+ },
1406
+ children: [
1407
+ /* @__PURE__ */ jsxs("div", { style: { padding: "1.5rem 1.5rem 0", borderBottom: "1px solid #e5e7eb" }, children: [
1408
+ /* @__PURE__ */ jsx(
1409
+ "h3",
1410
+ {
1411
+ style: { fontSize: "1.125rem", fontWeight: 600, color: "#111827", marginBottom: "1rem" },
1412
+ children: "Field Settings"
1413
+ }
1414
+ ),
1415
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", borderBottom: "1px solid #e5e7eb" }, children: [
1416
+ /* @__PURE__ */ jsxs(
1417
+ "button",
1418
+ {
1419
+ onClick: () => setActiveTab("general"),
1420
+ style: {
1421
+ flex: 1,
1422
+ padding: "0.75rem 0",
1423
+ fontSize: "0.875rem",
1424
+ fontWeight: 500,
1425
+ backgroundColor: "transparent",
1426
+ border: "none",
1427
+ borderBottom: `2px solid ${activeTab === "general" ? "#6366f1" : "transparent"}`,
1428
+ color: activeTab === "general" ? "#6366f1" : "#6b7280",
1429
+ cursor: "pointer",
1430
+ display: "flex",
1431
+ alignItems: "center",
1432
+ justifyContent: "center",
1433
+ gap: "0.25rem"
1434
+ },
1435
+ children: [
1436
+ /* @__PURE__ */ jsx(Settings, { size: 14 }),
1437
+ " General"
1438
+ ]
1439
+ }
1440
+ ),
1441
+ /* @__PURE__ */ jsxs(
1442
+ "button",
1443
+ {
1444
+ onClick: () => setActiveTab("validation"),
1445
+ style: {
1446
+ flex: 1,
1447
+ padding: "0.75rem 0",
1448
+ fontSize: "0.875rem",
1449
+ fontWeight: 500,
1450
+ backgroundColor: "transparent",
1451
+ border: "none",
1452
+ borderBottom: `2px solid ${activeTab === "validation" ? "#6366f1" : "transparent"}`,
1453
+ color: activeTab === "validation" ? "#6366f1" : "#6b7280",
1454
+ cursor: "pointer",
1455
+ display: "flex",
1456
+ alignItems: "center",
1457
+ justifyContent: "center",
1458
+ gap: "0.25rem"
1459
+ },
1460
+ children: [
1461
+ /* @__PURE__ */ jsx(CheckCircle2, { size: 14 }),
1462
+ " Validation"
1463
+ ]
1464
+ }
1465
+ ),
1466
+ /* @__PURE__ */ jsxs(
1467
+ "button",
1468
+ {
1469
+ onClick: () => setActiveTab("design"),
1470
+ style: {
1471
+ flex: 1,
1472
+ padding: "0.75rem 0",
1473
+ fontSize: "0.875rem",
1474
+ fontWeight: 500,
1475
+ backgroundColor: "transparent",
1476
+ border: "none",
1477
+ borderBottom: `2px solid ${activeTab === "design" ? "#6366f1" : "transparent"}`,
1478
+ color: activeTab === "design" ? "#6366f1" : "#6b7280",
1479
+ cursor: "pointer",
1480
+ display: "flex",
1481
+ alignItems: "center",
1482
+ justifyContent: "center",
1483
+ gap: "0.25rem"
1484
+ },
1485
+ children: [
1486
+ /* @__PURE__ */ jsx(Paintbrush, { size: 14 }),
1487
+ " Design"
1488
+ ]
1489
+ }
1490
+ )
1491
+ ] })
1492
+ ] }),
1493
+ /* @__PURE__ */ jsxs("div", { style: { padding: "1.5rem", display: "flex", flexDirection: "column", gap: "1.25rem" }, children: [
1494
+ activeTab === "general" && /* @__PURE__ */ jsxs(Fragment, { children: [
1495
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1496
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Property Key" }),
1497
+ /* @__PURE__ */ jsx(
1498
+ "input",
1499
+ {
1500
+ type: "text",
1501
+ value: field.key,
1502
+ onChange: (e) => onUpdate(field.id, { key: e.target.value.replace(/[^a-zA-Z0-9_]/g, "") }),
1503
+ style: {
1504
+ width: "100%",
1505
+ padding: "0.5rem",
1506
+ border: "1px solid #d1d5db",
1507
+ borderRadius: "0.375rem",
1508
+ fontSize: "0.875rem"
1509
+ },
1510
+ placeholder: "e.g. firstName"
1511
+ }
1512
+ ),
1513
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.75rem", color: "#9ca3af" }, children: "The key used in the final JSON output." })
1514
+ ] }),
1515
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1516
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Label / Title" }),
1517
+ /* @__PURE__ */ jsx(
1518
+ "input",
1519
+ {
1520
+ type: "text",
1521
+ value: field.schema.title || "",
1522
+ onChange: (e) => handleSchemaChange("title", e.target.value),
1523
+ style: {
1524
+ width: "100%",
1525
+ padding: "0.5rem",
1526
+ border: "1px solid #d1d5db",
1527
+ borderRadius: "0.375rem",
1528
+ fontSize: "0.875rem"
1529
+ }
1530
+ }
1531
+ )
1532
+ ] }),
1533
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1534
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Description" }),
1535
+ /* @__PURE__ */ jsx(
1536
+ "textarea",
1537
+ {
1538
+ value: field.schema.description || "",
1539
+ onChange: (e) => handleSchemaChange("description", e.target.value),
1540
+ style: {
1541
+ width: "100%",
1542
+ padding: "0.5rem",
1543
+ border: "1px solid #d1d5db",
1544
+ borderRadius: "0.375rem",
1545
+ fontSize: "0.875rem",
1546
+ minHeight: "80px"
1547
+ }
1548
+ }
1549
+ )
1550
+ ] }),
1551
+ (field.type === "select" || field.type === "radio" || field.type === "checkboxes") && /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1552
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Options (Comma separated)" }),
1553
+ /* @__PURE__ */ jsx(
1554
+ "input",
1555
+ {
1556
+ type: "text",
1557
+ value: field.type === "checkboxes" ? field.schema.items && !Array.isArray(field.schema.items) ? (_a = field.schema.items.enum) == null ? void 0 : _a.join(", ") : "" : ((_b = field.schema.enum) == null ? void 0 : _b.join(", ")) || "",
1558
+ onChange: (e) => {
1559
+ const valArray = e.target.value.split(",").map((s) => s.trim()).filter(Boolean);
1560
+ if (field.type === "checkboxes") {
1561
+ handleSchemaChange("items", {
1562
+ ...field.schema.items || {},
1563
+ enum: valArray
1564
+ });
1565
+ } else {
1566
+ handleSchemaChange("enum", valArray);
1567
+ }
1568
+ },
1569
+ style: {
1570
+ width: "100%",
1571
+ padding: "0.5rem",
1572
+ border: "1px solid #d1d5db",
1573
+ borderRadius: "0.375rem",
1574
+ fontSize: "0.875rem"
1575
+ }
1576
+ }
1577
+ )
1578
+ ] })
1579
+ ] }),
1580
+ activeTab === "validation" && /* @__PURE__ */ jsxs(Fragment, { children: [
1581
+ /* @__PURE__ */ jsxs(
1582
+ "label",
1583
+ {
1584
+ style: {
1585
+ display: "flex",
1586
+ alignItems: "center",
1587
+ gap: "0.5rem",
1588
+ fontSize: "0.875rem",
1589
+ fontWeight: 500,
1590
+ color: "#374151",
1591
+ cursor: "pointer"
1592
+ },
1593
+ children: [
1594
+ /* @__PURE__ */ jsx(
1595
+ "input",
1596
+ {
1597
+ type: "checkbox",
1598
+ checked: field.isRequired || false,
1599
+ onChange: (e) => onUpdate(field.id, { isRequired: e.target.checked })
1600
+ }
1601
+ ),
1602
+ "Required Field"
1603
+ ]
1604
+ }
1605
+ ),
1606
+ (field.type === "text" || field.type === "email" || field.type === "password") && /* @__PURE__ */ jsxs(Fragment, { children: [
1607
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1608
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Min Length" }),
1609
+ /* @__PURE__ */ jsx(
1610
+ "input",
1611
+ {
1612
+ type: "number",
1613
+ value: field.schema.minLength || "",
1614
+ onChange: (e) => handleSchemaChange(
1615
+ "minLength",
1616
+ e.target.value ? Number(e.target.value) : void 0
1617
+ ),
1618
+ style: {
1619
+ width: "100%",
1620
+ padding: "0.5rem",
1621
+ border: "1px solid #d1d5db",
1622
+ borderRadius: "0.375rem",
1623
+ fontSize: "0.875rem"
1624
+ }
1625
+ }
1626
+ )
1627
+ ] }),
1628
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1629
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Max Length" }),
1630
+ /* @__PURE__ */ jsx(
1631
+ "input",
1632
+ {
1633
+ type: "number",
1634
+ value: field.schema.maxLength || "",
1635
+ onChange: (e) => handleSchemaChange(
1636
+ "maxLength",
1637
+ e.target.value ? Number(e.target.value) : void 0
1638
+ ),
1639
+ style: {
1640
+ width: "100%",
1641
+ padding: "0.5rem",
1642
+ border: "1px solid #d1d5db",
1643
+ borderRadius: "0.375rem",
1644
+ fontSize: "0.875rem"
1645
+ }
1646
+ }
1647
+ )
1648
+ ] }),
1649
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1650
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Regex Pattern" }),
1651
+ /* @__PURE__ */ jsx(
1652
+ "input",
1653
+ {
1654
+ type: "text",
1655
+ value: field.schema.pattern || "",
1656
+ onChange: (e) => handleSchemaChange("pattern", e.target.value || void 0),
1657
+ style: {
1658
+ width: "100%",
1659
+ padding: "0.5rem",
1660
+ border: "1px solid #d1d5db",
1661
+ borderRadius: "0.375rem",
1662
+ fontSize: "0.875rem"
1663
+ }
1664
+ }
1665
+ )
1666
+ ] })
1667
+ ] }),
1668
+ field.type === "number" && /* @__PURE__ */ jsxs(Fragment, { children: [
1669
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1670
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Minimum Value" }),
1671
+ /* @__PURE__ */ jsx(
1672
+ "input",
1673
+ {
1674
+ type: "number",
1675
+ value: field.schema.minimum || "",
1676
+ onChange: (e) => handleSchemaChange(
1677
+ "minimum",
1678
+ e.target.value ? Number(e.target.value) : void 0
1679
+ ),
1680
+ style: {
1681
+ width: "100%",
1682
+ padding: "0.5rem",
1683
+ border: "1px solid #d1d5db",
1684
+ borderRadius: "0.375rem",
1685
+ fontSize: "0.875rem"
1686
+ }
1687
+ }
1688
+ )
1689
+ ] }),
1690
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1691
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Maximum Value" }),
1692
+ /* @__PURE__ */ jsx(
1693
+ "input",
1694
+ {
1695
+ type: "number",
1696
+ value: field.schema.maximum || "",
1697
+ onChange: (e) => handleSchemaChange(
1698
+ "maximum",
1699
+ e.target.value ? Number(e.target.value) : void 0
1700
+ ),
1701
+ style: {
1702
+ width: "100%",
1703
+ padding: "0.5rem",
1704
+ border: "1px solid #d1d5db",
1705
+ borderRadius: "0.375rem",
1706
+ fontSize: "0.875rem"
1707
+ }
1708
+ }
1709
+ )
1710
+ ] })
1711
+ ] })
1712
+ ] }),
1713
+ activeTab === "design" && /* @__PURE__ */ jsxs(Fragment, { children: [
1714
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
1715
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.875rem", fontWeight: 500, color: "#374151" }, children: "Column Span" }),
1716
+ /* @__PURE__ */ jsxs(
1717
+ "select",
1718
+ {
1719
+ value: ((_c = field.uiSchema) == null ? void 0 : _c["ui:columnSpan"]) || 1,
1720
+ onChange: (e) => handleUiSchemaChange("ui:columnSpan", Number(e.target.value)),
1721
+ style: {
1722
+ width: "100%",
1723
+ padding: "0.5rem",
1724
+ border: "1px solid #d1d5db",
1725
+ borderRadius: "0.375rem",
1726
+ fontSize: "0.875rem"
1727
+ },
1728
+ children: [
1729
+ /* @__PURE__ */ jsx("option", { value: 1, children: "1 Column" }),
1730
+ /* @__PURE__ */ jsx("option", { value: 2, children: "2 Columns" }),
1731
+ /* @__PURE__ */ jsx("option", { value: 3, children: "3 Columns" }),
1732
+ /* @__PURE__ */ jsx("option", { value: 4, children: "4 Columns" })
1733
+ ]
1734
+ }
1735
+ )
1736
+ ] }),
1737
+ /* @__PURE__ */ jsxs("div", { style: { marginTop: "1rem", borderTop: "1px solid #e5e7eb", paddingTop: "1rem" }, children: [
1738
+ /* @__PURE__ */ jsx(
1739
+ "h4",
1740
+ {
1741
+ style: {
1742
+ fontSize: "0.875rem",
1743
+ fontWeight: 600,
1744
+ color: "#111827",
1745
+ marginBottom: "0.5rem"
1746
+ },
1747
+ children: "Tailwind Classes (ui:classNames)"
1748
+ }
1749
+ ),
1750
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
1751
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
1752
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.75rem", color: "#6b7280" }, children: "Input" }),
1753
+ /* @__PURE__ */ jsx(
1754
+ "input",
1755
+ {
1756
+ type: "text",
1757
+ value: ((_e = (_d = field.uiSchema) == null ? void 0 : _d["ui:classNames"]) == null ? void 0 : _e.input) || "",
1758
+ onChange: (e) => handleClassNamesChange("input", e.target.value),
1759
+ style: {
1760
+ width: "100%",
1761
+ padding: "0.4rem",
1762
+ border: "1px solid #d1d5db",
1763
+ borderRadius: "0.25rem",
1764
+ fontSize: "0.75rem",
1765
+ fontFamily: "monospace"
1766
+ },
1767
+ placeholder: "e.g. bg-gray-50 border-blue-500"
1768
+ }
1769
+ )
1770
+ ] }),
1771
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
1772
+ /* @__PURE__ */ jsx("label", { style: { fontSize: "0.75rem", color: "#6b7280" }, children: "Label" }),
1773
+ /* @__PURE__ */ jsx(
1774
+ "input",
1775
+ {
1776
+ type: "text",
1777
+ value: ((_g = (_f = field.uiSchema) == null ? void 0 : _f["ui:classNames"]) == null ? void 0 : _g.label) || "",
1778
+ onChange: (e) => handleClassNamesChange("label", e.target.value),
1779
+ style: {
1780
+ width: "100%",
1781
+ padding: "0.4rem",
1782
+ border: "1px solid #d1d5db",
1783
+ borderRadius: "0.25rem",
1784
+ fontSize: "0.75rem",
1785
+ fontFamily: "monospace"
1786
+ },
1787
+ placeholder: "e.g. text-blue-600 font-bold"
1788
+ }
1789
+ )
1790
+ ] })
1791
+ ] })
1792
+ ] })
1793
+ ] })
1794
+ ] })
1795
+ ]
1796
+ }
1797
+ );
1798
+ };
1799
+ var FormBuilder = ({
1800
+ initialSchema,
1801
+ initialUiSchema,
1802
+ initialColumns,
1803
+ initialTheme,
1804
+ onSave
1805
+ }) => {
1806
+ const {
1807
+ fields,
1808
+ selectedFieldId,
1809
+ setSelectedFieldId,
1810
+ selectedField,
1811
+ addField,
1812
+ removeField,
1813
+ updateField,
1814
+ reorderFields,
1815
+ compileSchemas,
1816
+ formSettings,
1817
+ updateFormSettings
1818
+ } = useFormBuilder(initialSchema, initialUiSchema, initialColumns, initialTheme);
1819
+ const [activeDragType, setActiveDragType] = useState(null);
1820
+ const [isPreviewMode, setIsPreviewMode] = useState(false);
1821
+ const sensors = useSensors(
1822
+ useSensor(PointerSensor),
1823
+ useSensor(KeyboardSensor, {
1824
+ coordinateGetter: sortableKeyboardCoordinates
1825
+ })
1826
+ );
1827
+ const handleDragStart = (event) => {
1828
+ var _a;
1829
+ const { active } = event;
1830
+ if (((_a = active.data.current) == null ? void 0 : _a.type) === "ToolboxItem") {
1831
+ setActiveDragType(active.data.current.fieldType);
1832
+ }
1833
+ };
1834
+ const handleDragEnd = (event) => {
1835
+ var _a, _b;
1836
+ const { active, over } = event;
1837
+ setActiveDragType(null);
1838
+ if (!over) return;
1839
+ if (((_a = active.data.current) == null ? void 0 : _a.type) === "ToolboxItem") {
1840
+ if (over.id === "canvas-droppable" || fields.find((f) => f.id === over.id)) {
1841
+ const overIndex = fields.findIndex((f) => f.id === over.id);
1842
+ addField(
1843
+ active.data.current.fieldType,
1844
+ overIndex >= 0 ? overIndex : void 0
1845
+ );
1846
+ }
1847
+ return;
1848
+ }
1849
+ if (((_b = active.data.current) == null ? void 0 : _b.type) === "SortableField" && active.id !== over.id) {
1850
+ reorderFields(active.id, over.id);
1851
+ }
1852
+ };
1853
+ const handleSave = () => {
1854
+ if (onSave) {
1855
+ const { schema, uiSchema } = compileSchemas();
1856
+ onSave(schema, uiSchema, formSettings);
1857
+ }
1858
+ };
1859
+ return /* @__PURE__ */ jsxs(
1860
+ "div",
1861
+ {
1862
+ style: {
1863
+ display: "flex",
1864
+ flexDirection: "column",
1865
+ height: "100vh",
1866
+ width: "100vw",
1867
+ fontFamily: "system-ui, sans-serif"
1868
+ },
1869
+ children: [
1870
+ /* @__PURE__ */ jsxs(
1871
+ "div",
1872
+ {
1873
+ style: {
1874
+ height: "60px",
1875
+ borderBottom: "1px solid #e5e7eb",
1876
+ backgroundColor: "white",
1877
+ display: "flex",
1878
+ alignItems: "center",
1879
+ justifyContent: "space-between",
1880
+ padding: "0 1.5rem",
1881
+ zIndex: 20
1882
+ },
1883
+ children: [
1884
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1885
+ /* @__PURE__ */ jsx(
1886
+ "div",
1887
+ {
1888
+ style: {
1889
+ width: "32px",
1890
+ height: "32px",
1891
+ backgroundColor: "#6366f1",
1892
+ borderRadius: "0.5rem",
1893
+ display: "flex",
1894
+ alignItems: "center",
1895
+ justifyContent: "center",
1896
+ color: "white"
1897
+ },
1898
+ children: /* @__PURE__ */ jsx(Code2, { size: 20 })
1899
+ }
1900
+ ),
1901
+ /* @__PURE__ */ jsx("h1", { style: { fontSize: "1.25rem", fontWeight: 700, color: "#111827", margin: 0 }, children: "Visual Form Builder" })
1902
+ ] }),
1903
+ /* @__PURE__ */ jsxs(
1904
+ "div",
1905
+ {
1906
+ style: {
1907
+ display: "flex",
1908
+ backgroundColor: "#f3f4f6",
1909
+ padding: "0.25rem",
1910
+ borderRadius: "0.5rem"
1911
+ },
1912
+ children: [
1913
+ /* @__PURE__ */ jsxs(
1914
+ "button",
1915
+ {
1916
+ onClick: () => setIsPreviewMode(false),
1917
+ style: {
1918
+ display: "flex",
1919
+ alignItems: "center",
1920
+ gap: "0.375rem",
1921
+ padding: "0.375rem 0.75rem",
1922
+ fontSize: "0.875rem",
1923
+ fontWeight: 500,
1924
+ border: "none",
1925
+ borderRadius: "0.375rem",
1926
+ cursor: "pointer",
1927
+ transition: "all 0.2s",
1928
+ backgroundColor: !isPreviewMode ? "white" : "transparent",
1929
+ color: !isPreviewMode ? "#111827" : "#6b7280",
1930
+ boxShadow: !isPreviewMode ? "0 1px 3px rgba(0,0,0,0.1)" : "none"
1931
+ },
1932
+ children: [
1933
+ /* @__PURE__ */ jsx(LayoutTemplate, { size: 16 }),
1934
+ " Builder"
1935
+ ]
1936
+ }
1937
+ ),
1938
+ /* @__PURE__ */ jsxs(
1939
+ "button",
1940
+ {
1941
+ onClick: () => setIsPreviewMode(true),
1942
+ style: {
1943
+ display: "flex",
1944
+ alignItems: "center",
1945
+ gap: "0.375rem",
1946
+ padding: "0.375rem 0.75rem",
1947
+ fontSize: "0.875rem",
1948
+ fontWeight: 500,
1949
+ border: "none",
1950
+ borderRadius: "0.375rem",
1951
+ cursor: "pointer",
1952
+ transition: "all 0.2s",
1953
+ backgroundColor: isPreviewMode ? "white" : "transparent",
1954
+ color: isPreviewMode ? "#111827" : "#6b7280",
1955
+ boxShadow: isPreviewMode ? "0 1px 3px rgba(0,0,0,0.1)" : "none"
1956
+ },
1957
+ children: [
1958
+ /* @__PURE__ */ jsx(Eye, { size: 16 }),
1959
+ " Preview"
1960
+ ]
1961
+ }
1962
+ )
1963
+ ]
1964
+ }
1965
+ ),
1966
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
1967
+ "button",
1968
+ {
1969
+ onClick: handleSave,
1970
+ style: {
1971
+ display: "flex",
1972
+ alignItems: "center",
1973
+ gap: "0.5rem",
1974
+ backgroundColor: "#6366f1",
1975
+ color: "white",
1976
+ border: "none",
1977
+ padding: "0.5rem 1rem",
1978
+ borderRadius: "0.375rem",
1979
+ fontWeight: 600,
1980
+ cursor: "pointer",
1981
+ transition: "background-color 0.2s"
1982
+ },
1983
+ onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "#4f46e5",
1984
+ onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "#6366f1",
1985
+ children: [
1986
+ /* @__PURE__ */ jsx(Save, { size: 16 }),
1987
+ " Save Form"
1988
+ ]
1989
+ }
1990
+ ) })
1991
+ ]
1992
+ }
1993
+ ),
1994
+ /* @__PURE__ */ jsx(
1995
+ "div",
1996
+ {
1997
+ style: {
1998
+ display: "flex",
1999
+ flex: 1,
2000
+ overflow: "hidden",
2001
+ backgroundColor: "#f3f4f6",
2002
+ minHeight: 0
2003
+ },
2004
+ children: isPreviewMode ? /* @__PURE__ */ jsx(
2005
+ "div",
2006
+ {
2007
+ style: {
2008
+ flex: 1,
2009
+ padding: "3rem",
2010
+ overflowY: "auto",
2011
+ display: "flex",
2012
+ justifyContent: "center"
2013
+ },
2014
+ children: /* @__PURE__ */ jsxs(
2015
+ "div",
2016
+ {
2017
+ style: {
2018
+ width: "100%",
2019
+ maxWidth: "800px",
2020
+ backgroundColor: "white",
2021
+ padding: "2rem",
2022
+ borderRadius: "1rem",
2023
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)"
2024
+ },
2025
+ children: [
2026
+ /* @__PURE__ */ jsx(
2027
+ "div",
2028
+ {
2029
+ style: {
2030
+ marginBottom: "2rem",
2031
+ paddingBottom: "1rem",
2032
+ borderBottom: "1px solid #e5e7eb",
2033
+ display: "flex",
2034
+ justifyContent: "space-between",
2035
+ alignItems: "center"
2036
+ },
2037
+ children: /* @__PURE__ */ jsx(
2038
+ "span",
2039
+ {
2040
+ style: {
2041
+ fontSize: "0.875rem",
2042
+ fontWeight: 600,
2043
+ color: "#6366f1",
2044
+ textTransform: "uppercase",
2045
+ letterSpacing: "0.05em"
2046
+ },
2047
+ children: "Live Preview"
2048
+ }
2049
+ )
2050
+ }
2051
+ ),
2052
+ /* @__PURE__ */ jsx(
2053
+ SchemaForm,
2054
+ {
2055
+ schema: compileSchemas().schema,
2056
+ uiSchema: compileSchemas().uiSchema,
2057
+ columns: formSettings.columns,
2058
+ theme: formSettings.theme,
2059
+ onSubmit: (data) => alert("Preview Form Submitted!\n\n" + JSON.stringify(data, null, 2))
2060
+ }
2061
+ )
2062
+ ]
2063
+ }
2064
+ )
2065
+ }
2066
+ ) : /* @__PURE__ */ jsxs(
2067
+ DndContext,
2068
+ {
2069
+ sensors,
2070
+ collisionDetection: closestCenter,
2071
+ onDragStart: handleDragStart,
2072
+ onDragEnd: handleDragEnd,
2073
+ children: [
2074
+ /* @__PURE__ */ jsx(Toolbox, {}),
2075
+ /* @__PURE__ */ jsx(
2076
+ Canvas,
2077
+ {
2078
+ fields,
2079
+ selectedFieldId,
2080
+ onSelectField: setSelectedFieldId,
2081
+ onRemoveField: removeField,
2082
+ onDuplicateField: (f) => {
2083
+ const idx = fields.findIndex((field) => field.id === f.id);
2084
+ addField(f.type, idx + 1);
2085
+ }
2086
+ }
2087
+ ),
2088
+ /* @__PURE__ */ jsx(
2089
+ PropertiesPanel,
2090
+ {
2091
+ field: selectedField || null,
2092
+ formSettings,
2093
+ onUpdate: updateField,
2094
+ onUpdateSettings: updateFormSettings
2095
+ }
2096
+ ),
2097
+ /* @__PURE__ */ jsx(DragOverlay, { children: activeDragType ? /* @__PURE__ */ jsxs(
2098
+ "div",
2099
+ {
2100
+ style: {
2101
+ padding: "0.75rem",
2102
+ backgroundColor: "#6366f1",
2103
+ color: "white",
2104
+ borderRadius: "0.5rem",
2105
+ opacity: 0.8,
2106
+ fontWeight: 500
2107
+ },
2108
+ children: [
2109
+ "Dropping ",
2110
+ activeDragType,
2111
+ "..."
2112
+ ]
2113
+ }
2114
+ ) : null })
2115
+ ]
2116
+ }
2117
+ )
2118
+ }
2119
+ )
2120
+ ]
2121
+ }
2122
+ );
509
2123
  };
510
2124
 
511
- export { FieldRenderer, SchemaForm };
2125
+ export { FieldRenderer, FormBuilder, SchemaForm };
512
2126
  //# sourceMappingURL=index.mjs.map
513
2127
  //# sourceMappingURL=index.mjs.map