@squaredr/fieldcraft-pro 1.7.0 → 1.8.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.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var react = require('react');
3
+ var React = require('react');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var core = require('@dnd-kit/core');
6
6
  var lucideReact = require('lucide-react');
@@ -8,9 +8,31 @@ var fieldcraftReact = require('@squaredr/fieldcraft-react');
8
8
  var fieldcraftCore = require('@squaredr/fieldcraft-core');
9
9
  var clsx = require('clsx');
10
10
  var tailwindMerge = require('tailwind-merge');
11
- var react$1 = require('@xyflow/react');
11
+ var SelectPrimitive = require('@radix-ui/react-select');
12
+ var react = require('@xyflow/react');
12
13
  require('@xyflow/react/dist/style.css');
13
14
 
15
+ function _interopNamespace(e) {
16
+ if (e && e.__esModule) return e;
17
+ var n = Object.create(null);
18
+ if (e) {
19
+ Object.keys(e).forEach(function (k) {
20
+ if (k !== 'default') {
21
+ var d = Object.getOwnPropertyDescriptor(e, k);
22
+ Object.defineProperty(n, k, d.get ? d : {
23
+ enumerable: true,
24
+ get: function () { return e[k]; }
25
+ });
26
+ }
27
+ });
28
+ }
29
+ n.default = e;
30
+ return Object.freeze(n);
31
+ }
32
+
33
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
34
+ var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
35
+
14
36
  // ../license/dist/index.mjs
15
37
  var DEV_HOSTNAMES = /* @__PURE__ */ new Set([
16
38
  "localhost",
@@ -85,9 +107,9 @@ function isProductionEnvironment() {
85
107
  }
86
108
  typeof process !== "undefined" && process.env?.NEXT_PUBLIC_FCPRO_PING_URL || "https://fieldcraft.dev/api/license/ping";
87
109
  var defaultContext = { status: "validating" };
88
- var LicenseCtx = react.createContext(defaultContext);
110
+ var LicenseCtx = React.createContext(defaultContext);
89
111
  function useLicense() {
90
- return react.useContext(LicenseCtx);
112
+ return React.useContext(LicenseCtx);
91
113
  }
92
114
  function UnlicensedOverlay({ featureName, reason, children }) {
93
115
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", minHeight: "200px" }, children: [
@@ -312,38 +334,41 @@ function requireLicense(Component3, featureName) {
312
334
  }
313
335
  var MAX_HISTORY = 50;
314
336
  function useUndoRedo(currentSchema, setSchema) {
315
- const historyRef = react.useRef([currentSchema]);
316
- const [currentIndex, setCurrentIndex] = react.useState(0);
337
+ const historyRef = React.useRef([currentSchema]);
338
+ const [currentIndex, setCurrentIndex] = React.useState(0);
339
+ const currentIndexRef = React.useRef(currentIndex);
340
+ currentIndexRef.current = currentIndex;
317
341
  const canUndo = currentIndex > 0;
318
342
  const canRedo = currentIndex < historyRef.current.length - 1;
319
- const push = react.useCallback(
343
+ const push = React.useCallback(
320
344
  (schema) => {
321
- historyRef.current = historyRef.current.slice(0, currentIndex + 1);
345
+ const idx = currentIndexRef.current;
346
+ historyRef.current = historyRef.current.slice(0, idx + 1);
322
347
  historyRef.current.push(schema);
323
348
  if (historyRef.current.length > MAX_HISTORY) {
324
349
  historyRef.current.shift();
325
350
  setCurrentIndex(historyRef.current.length - 1);
326
351
  } else {
327
- setCurrentIndex((prev) => prev + 1);
352
+ setCurrentIndex(idx + 1);
328
353
  }
329
354
  },
330
- [currentIndex]
355
+ []
331
356
  );
332
- const undo = react.useCallback(() => {
357
+ const undo = React.useCallback(() => {
333
358
  if (currentIndex > 0) {
334
359
  const newIndex = currentIndex - 1;
335
360
  setCurrentIndex(newIndex);
336
361
  setSchema(historyRef.current[newIndex]);
337
362
  }
338
363
  }, [currentIndex, setSchema]);
339
- const redo = react.useCallback(() => {
364
+ const redo = React.useCallback(() => {
340
365
  if (currentIndex < historyRef.current.length - 1) {
341
366
  const newIndex = currentIndex + 1;
342
367
  setCurrentIndex(newIndex);
343
368
  setSchema(historyRef.current[newIndex]);
344
369
  }
345
370
  }, [currentIndex, setSchema]);
346
- const clear = react.useCallback(() => {
371
+ const clear = React.useCallback(() => {
347
372
  historyRef.current = [currentSchema];
348
373
  setCurrentIndex(0);
349
374
  }, [currentSchema]);
@@ -572,16 +597,16 @@ function findSection(schema, sectionId) {
572
597
 
573
598
  // src/form-builder/hooks/use-builder-state.ts
574
599
  function useBuilderState(initialSchema) {
575
- const [schema, setSchema] = react.useState(initialSchema);
576
- const [selectedItem, setSelectedItem] = react.useState(null);
577
- const [isDirty, setIsDirty] = react.useState(false);
578
- const schemaRef = react.useRef(schema);
600
+ const [schema, setSchema] = React.useState(initialSchema);
601
+ const [selectedItem, setSelectedItem] = React.useState(null);
602
+ const [isDirty, setIsDirty] = React.useState(false);
603
+ const schemaRef = React.useRef(schema);
579
604
  schemaRef.current = schema;
580
605
  const undoRedo = useUndoRedo(schema, (newSchema) => {
581
606
  setSchema(newSchema);
582
607
  setIsDirty(true);
583
608
  });
584
- const updateSchema = react.useCallback(
609
+ const updateSchema = React.useCallback(
585
610
  (newSchema) => {
586
611
  setSchema(newSchema);
587
612
  undoRedo.push(newSchema);
@@ -589,20 +614,20 @@ function useBuilderState(initialSchema) {
589
614
  },
590
615
  [undoRedo]
591
616
  );
592
- const applyMutation = react.useCallback(
617
+ const applyMutation = React.useCallback(
593
618
  (mutate) => {
594
619
  const result = mutate(schemaRef.current);
595
620
  updateSchema(result);
596
621
  },
597
622
  [updateSchema]
598
623
  );
599
- const addSection2 = react.useCallback(
624
+ const addSection2 = React.useCallback(
600
625
  (section, index) => {
601
626
  applyMutation((s) => addSection(s, section, index));
602
627
  },
603
628
  [applyMutation]
604
629
  );
605
- const removeSection2 = react.useCallback(
630
+ const removeSection2 = React.useCallback(
606
631
  (sectionId) => {
607
632
  applyMutation((s) => removeSection(s, sectionId));
608
633
  setSelectedItem((prev) => {
@@ -612,31 +637,31 @@ function useBuilderState(initialSchema) {
612
637
  },
613
638
  [applyMutation]
614
639
  );
615
- const updateSection2 = react.useCallback(
640
+ const updateSection2 = React.useCallback(
616
641
  (sectionId, updates) => {
617
642
  applyMutation((s) => updateSection(s, sectionId, updates));
618
643
  },
619
644
  [applyMutation]
620
645
  );
621
- const moveSection2 = react.useCallback(
646
+ const moveSection2 = React.useCallback(
622
647
  (sectionId, newIndex) => {
623
648
  applyMutation((s) => moveSection(s, sectionId, newIndex));
624
649
  },
625
650
  [applyMutation]
626
651
  );
627
- const duplicateSection2 = react.useCallback(
652
+ const duplicateSection2 = React.useCallback(
628
653
  (sectionId) => {
629
654
  applyMutation((s) => duplicateSection(s, sectionId));
630
655
  },
631
656
  [applyMutation]
632
657
  );
633
- const addQuestion2 = react.useCallback(
658
+ const addQuestion2 = React.useCallback(
634
659
  (sectionId, question, index) => {
635
660
  applyMutation((s) => addQuestion(s, sectionId, question, index));
636
661
  },
637
662
  [applyMutation]
638
663
  );
639
- const removeQuestion2 = react.useCallback(
664
+ const removeQuestion2 = React.useCallback(
640
665
  (sectionId, questionId) => {
641
666
  applyMutation((s) => removeQuestion(s, sectionId, questionId));
642
667
  setSelectedItem((prev) => {
@@ -648,34 +673,34 @@ function useBuilderState(initialSchema) {
648
673
  },
649
674
  [applyMutation]
650
675
  );
651
- const updateQuestion2 = react.useCallback(
676
+ const updateQuestion2 = React.useCallback(
652
677
  (sectionId, questionId, updates) => {
653
678
  applyMutation((s) => updateQuestion(s, sectionId, questionId, updates));
654
679
  },
655
680
  [applyMutation]
656
681
  );
657
- const moveQuestion2 = react.useCallback(
682
+ const moveQuestion2 = React.useCallback(
658
683
  (sectionId, questionId, targetSectionId, newIndex) => {
659
684
  applyMutation((s) => moveQuestion(s, sectionId, questionId, targetSectionId, newIndex));
660
685
  },
661
686
  [applyMutation]
662
687
  );
663
- const duplicateQuestion2 = react.useCallback(
688
+ const duplicateQuestion2 = React.useCallback(
664
689
  (sectionId, questionId) => {
665
690
  applyMutation((s) => duplicateQuestion(s, sectionId, questionId));
666
691
  },
667
692
  [applyMutation]
668
693
  );
669
- const selectQuestion = react.useCallback((sectionId, questionId) => {
694
+ const selectQuestion = React.useCallback((sectionId, questionId) => {
670
695
  setSelectedItem({ type: "question", sectionId, questionId });
671
696
  }, []);
672
- const selectSection = react.useCallback((sectionId) => {
697
+ const selectSection = React.useCallback((sectionId) => {
673
698
  setSelectedItem({ type: "section", sectionId });
674
699
  }, []);
675
- const clearSelection = react.useCallback(() => {
700
+ const clearSelection = React.useCallback(() => {
676
701
  setSelectedItem(null);
677
702
  }, []);
678
- const resetSchema = react.useCallback(
703
+ const resetSchema = React.useCallback(
679
704
  (newSchema) => {
680
705
  setSchema(newSchema);
681
706
  undoRedo.clear();
@@ -684,7 +709,7 @@ function useBuilderState(initialSchema) {
684
709
  },
685
710
  [undoRedo]
686
711
  );
687
- const markClean = react.useCallback(() => {
712
+ const markClean = React.useCallback(() => {
688
713
  setIsDirty(false);
689
714
  }, []);
690
715
  return {
@@ -945,7 +970,7 @@ var QUESTION_TYPE_INFO = {
945
970
  category: "advanced",
946
971
  icon: "ListPlus",
947
972
  description: "Repeatable group of fields",
948
- defaultConfig: { type: "repeater", fields: [], minItems: 1, maxItems: 10 }
973
+ defaultConfig: { type: "repeater", fields: [], minEntries: 1, maxEntries: 10 }
949
974
  },
950
975
  likert: {
951
976
  type: "likert",
@@ -956,13 +981,7 @@ var QUESTION_TYPE_INFO = {
956
981
  requiresOptions: true,
957
982
  defaultConfig: {
958
983
  type: "likert",
959
- scale: [
960
- { label: "Strongly Disagree", value: "1" },
961
- { label: "Disagree", value: "2" },
962
- { label: "Neutral", value: "3" },
963
- { label: "Agree", value: "4" },
964
- { label: "Strongly Agree", value: "5" }
965
- ]
984
+ labels: ["Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"]
966
985
  }
967
986
  },
968
987
  scoring: {
@@ -1015,7 +1034,7 @@ var QUESTION_TYPE_INFO = {
1015
1034
  category: "advanced",
1016
1035
  icon: "CreditCard",
1017
1036
  description: "Collect payment via Stripe",
1018
- defaultConfig: { type: "payment", provider: "stripe", publicKey: "", currency: "USD" }
1037
+ defaultConfig: { type: "payment", provider: "stripe", publicKey: "", currency: "USD", serverUrl: "" }
1019
1038
  },
1020
1039
  // ── Structural ──
1021
1040
  section_header: {
@@ -1162,7 +1181,7 @@ var DEFAULT_PALETTE = [
1162
1181
 
1163
1182
  // src/form-builder/hooks/use-drag-drop.ts
1164
1183
  function useDragDrop(builderState) {
1165
- const [activeDragItem, setActiveDragItem] = react.useState(null);
1184
+ const [activeDragItem, setActiveDragItem] = React.useState(null);
1166
1185
  const sensors = core.useSensors(
1167
1186
  core.useSensor(core.MouseSensor, {
1168
1187
  activationConstraint: {
@@ -1212,11 +1231,11 @@ function useDragDrop(builderState) {
1212
1231
  }
1213
1232
  return null;
1214
1233
  };
1215
- const handleDragStart = react.useCallback((event) => {
1234
+ const handleDragStart = React.useCallback((event) => {
1216
1235
  const item = parseDragItem(event.active);
1217
1236
  setActiveDragItem(item);
1218
1237
  }, []);
1219
- const handleDragCancel = react.useCallback(() => {
1238
+ const handleDragCancel = React.useCallback(() => {
1220
1239
  setActiveDragItem(null);
1221
1240
  }, []);
1222
1241
  const handleDragEnd = (event) => {
@@ -1386,9 +1405,9 @@ function PaletteItem({ questionType, typeInfo }) {
1386
1405
  );
1387
1406
  }
1388
1407
  function QuestionPalette({ questionTypes, palette }) {
1389
- const [collapsed, setCollapsed] = react.useState({});
1390
- const [search, setSearch] = react.useState("");
1391
- const mergedPalette = react.useMemo(
1408
+ const [collapsed, setCollapsed] = React.useState({});
1409
+ const [search, setSearch] = React.useState("");
1410
+ const mergedPalette = React.useMemo(
1392
1411
  () => palette ? [...DEFAULT_PALETTE, ...palette] : DEFAULT_PALETTE,
1393
1412
  [palette]
1394
1413
  );
@@ -1469,13 +1488,13 @@ function QuestionBlock({
1469
1488
  }) {
1470
1489
  const typeInfo = QUESTION_TYPE_INFO[question.type];
1471
1490
  const IconComponent = typeInfo ? getIcon(typeInfo.icon) : null;
1472
- const [isEditing, setIsEditing] = react.useState(false);
1473
- const [editValue, setEditValue] = react.useState(question.label);
1474
- const inputRef = react.useRef(null);
1475
- react.useEffect(() => {
1491
+ const [isEditing, setIsEditing] = React.useState(false);
1492
+ const [editValue, setEditValue] = React.useState(question.label);
1493
+ const inputRef = React.useRef(null);
1494
+ React.useEffect(() => {
1476
1495
  if (!isEditing) setEditValue(question.label);
1477
1496
  }, [question.label, isEditing]);
1478
- react.useEffect(() => {
1497
+ React.useEffect(() => {
1479
1498
  if (isEditing && inputRef.current) {
1480
1499
  inputRef.current.focus();
1481
1500
  inputRef.current.select();
@@ -1632,7 +1651,7 @@ function ConfirmDialog({ open, title, message, onConfirm, onCancel }) {
1632
1651
  );
1633
1652
  }
1634
1653
  function SectionBlock({ section, builderState }) {
1635
- const [confirmDelete, setConfirmDelete] = react.useState(false);
1654
+ const [confirmDelete, setConfirmDelete] = React.useState(false);
1636
1655
  const { setNodeRef } = core.useDroppable({
1637
1656
  id: `section-end-${section.id}`,
1638
1657
  data: { type: "section", sectionId: section.id, index: section.questions.length }
@@ -1813,30 +1832,71 @@ function FormCanvas({ builderState }) {
1813
1832
  ] })
1814
1833
  ] }) });
1815
1834
  }
1816
- var NativeSelect = react.forwardRef(
1817
- ({ className, wrapperClassName, children, ...props }, ref) => {
1818
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", wrapperClassName), children: [
1835
+ var Select = SelectPrimitive__namespace.Root;
1836
+ var SelectTrigger = React__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
1837
+ SelectPrimitive__namespace.Trigger,
1838
+ {
1839
+ ref,
1840
+ className: cn(
1841
+ "flex h-9 w-full items-center justify-between rounded-md border border-input bg-card px-3 py-1 text-sm shadow-xs transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
1842
+ className
1843
+ ),
1844
+ ...props,
1845
+ children: [
1846
+ children,
1847
+ /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Icon, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4 text-muted-foreground" }) })
1848
+ ]
1849
+ }
1850
+ ));
1851
+ SelectTrigger.displayName = "SelectTrigger";
1852
+ var SelectContent = React__namespace.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
1853
+ SelectPrimitive__namespace.Content,
1854
+ {
1855
+ ref,
1856
+ className: cn(
1857
+ "relative z-50 max-h-64 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
1858
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
1859
+ className
1860
+ ),
1861
+ position,
1862
+ ...props,
1863
+ children: [
1864
+ /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ScrollUpButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "size-4" }) }),
1819
1865
  /* @__PURE__ */ jsxRuntime.jsx(
1820
- "select",
1866
+ SelectPrimitive__namespace.Viewport,
1821
1867
  {
1822
- ref,
1823
1868
  className: cn(
1824
- "flex h-9 w-full appearance-none rounded-md border border-input bg-card px-3 py-1 pr-8 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring text-foreground cursor-pointer",
1825
- className
1869
+ "p-1",
1870
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
1826
1871
  ),
1827
- ...props,
1828
1872
  children
1829
1873
  }
1830
1874
  ),
1831
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "pointer-events-none absolute right-2.5 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" })
1832
- ] });
1875
+ /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ScrollDownButton, { className: "flex cursor-default items-center justify-center py-1", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4" }) })
1876
+ ]
1833
1877
  }
1834
- );
1835
- NativeSelect.displayName = "NativeSelect";
1878
+ ) }));
1879
+ SelectContent.displayName = "SelectContent";
1880
+ var SelectItem = React__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
1881
+ SelectPrimitive__namespace.Item,
1882
+ {
1883
+ ref,
1884
+ className: cn(
1885
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
1886
+ className
1887
+ ),
1888
+ ...props,
1889
+ children: [
1890
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-4" }) }) }),
1891
+ /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemText, { children })
1892
+ ]
1893
+ }
1894
+ ));
1895
+ SelectItem.displayName = "SelectItem";
1836
1896
  function useConfigUpdater(question, onUpdate) {
1837
- return (field, value) => {
1897
+ return (updates) => {
1838
1898
  const current = question.config ?? {};
1839
- onUpdate({ config: { ...current, type: question.type, [field]: value } });
1899
+ onUpdate({ config: { ...current, type: question.type, ...updates } });
1840
1900
  };
1841
1901
  }
1842
1902
  function QuestionConfigEditor({ question, onUpdate }) {
@@ -1846,226 +1906,274 @@ function QuestionConfigEditor({ question, onUpdate }) {
1846
1906
  // ── Text ──
1847
1907
  case "short_text":
1848
1908
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Text Settings", children: [
1849
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Length", value: config.maxLength, placeholder: "255", onChange: (v) => updateConfig("maxLength", v) }),
1850
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Input Type", value: config.inputType ?? "text", options: [{ label: "Text", value: "text" }, { label: "Password", value: "password" }], onChange: (v) => updateConfig("inputType", v) }),
1851
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Prefix", value: config.prefix, placeholder: "e.g. $", onChange: (v) => updateConfig("prefix", v) }),
1852
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Suffix", value: config.suffix, placeholder: "e.g. USD", onChange: (v) => updateConfig("suffix", v) })
1909
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Length", value: config.maxLength, placeholder: "255", onChange: (v) => updateConfig({ maxLength: v }) }),
1910
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Input Type", value: config.inputType ?? "text", options: [{ label: "Text", value: "text" }, { label: "Password", value: "password" }], onChange: (v) => updateConfig({ inputType: v }) }),
1911
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Prefix", value: config.prefix, placeholder: "e.g. $", onChange: (v) => updateConfig({ prefix: v }) }),
1912
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Suffix", value: config.suffix, placeholder: "e.g. USD", onChange: (v) => updateConfig({ suffix: v }) })
1853
1913
  ] });
1854
1914
  case "long_text":
1855
1915
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Text Settings", children: [
1856
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Length", value: config.maxLength, placeholder: "No limit", onChange: (v) => updateConfig("maxLength", v) }),
1857
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Rows", value: config.rows, placeholder: "4", onChange: (v) => updateConfig("rows", v) }),
1858
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Character Count", checked: !!config.showCharCount, onChange: (v) => updateConfig("showCharCount", v) })
1916
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Length", value: config.maxLength, placeholder: "No limit", onChange: (v) => updateConfig({ maxLength: v }) }),
1917
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Rows", value: config.rows, placeholder: "4", onChange: (v) => updateConfig({ rows: v }) }),
1918
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Character Count", checked: !!config.showCharCount, onChange: (v) => updateConfig({ showCharCount: v }) })
1859
1919
  ] });
1860
1920
  case "legal_name":
1861
1921
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Name Fields", children: [
1862
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Middle Name", checked: !!config.showMiddleName, onChange: (v) => updateConfig("showMiddleName", v) }),
1863
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Suffix", checked: !!config.showSuffix, onChange: (v) => updateConfig("showSuffix", v) })
1922
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Middle Name", checked: !!config.showMiddleName, onChange: (v) => updateConfig({ showMiddleName: v }) }),
1923
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Suffix", checked: !!config.showSuffix, onChange: (v) => updateConfig({ showSuffix: v }) })
1864
1924
  ] });
1865
1925
  // ── Numeric ──
1866
1926
  case "number":
1867
1927
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Number Settings", children: [
1868
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Min", value: config.min, onChange: (v) => updateConfig("min", v) }),
1869
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max", value: config.max, onChange: (v) => updateConfig("max", v) }),
1870
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig("step", v) }),
1871
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Decimal Places", value: config.decimalPlaces, placeholder: "0", onChange: (v) => updateConfig("decimalPlaces", v) }),
1872
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Prefix", value: config.prefix, placeholder: "e.g. $", onChange: (v) => updateConfig("prefix", v) }),
1873
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Suffix", value: config.suffix, placeholder: "e.g. kg", onChange: (v) => updateConfig("suffix", v) })
1928
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Min", value: config.min, onChange: (v) => updateConfig({ min: v }) }),
1929
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max", value: config.max, onChange: (v) => updateConfig({ max: v }) }),
1930
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig({ step: v }) }),
1931
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Decimal Places", value: config.decimalPlaces, placeholder: "0", onChange: (v) => updateConfig({ decimalPlaces: v }) }),
1932
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Prefix", value: config.prefix, placeholder: "e.g. $", onChange: (v) => updateConfig({ prefix: v }) }),
1933
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Suffix", value: config.suffix, placeholder: "e.g. kg", onChange: (v) => updateConfig({ suffix: v }) })
1874
1934
  ] });
1875
1935
  case "slider":
1876
1936
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Slider Settings", children: [
1877
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Min", value: config.min, placeholder: "0", onChange: (v) => updateConfig("min", v) }),
1878
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max", value: config.max, placeholder: "100", onChange: (v) => updateConfig("max", v) }),
1879
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig("step", v) }),
1880
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Value", checked: !!config.showValue, onChange: (v) => updateConfig("showValue", v) }),
1881
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Min Label", value: config.minLabel, onChange: (v) => updateConfig("minLabel", v) }),
1882
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Max Label", value: config.maxLabel, onChange: (v) => updateConfig("maxLabel", v) })
1937
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Min", value: config.min, placeholder: "0", onChange: (v) => updateConfig({ min: v }) }),
1938
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max", value: config.max, placeholder: "100", onChange: (v) => updateConfig({ max: v }) }),
1939
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig({ step: v }) }),
1940
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Value", checked: !!config.showValue, onChange: (v) => updateConfig({ showValue: v }) }),
1941
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Min Label", value: config.minLabel, onChange: (v) => updateConfig({ minLabel: v }) }),
1942
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Max Label", value: config.maxLabel, onChange: (v) => updateConfig({ maxLabel: v }) })
1883
1943
  ] });
1884
1944
  case "rating":
1885
1945
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Rating Settings", children: [
1886
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Stars", value: config.max, placeholder: "5", onChange: (v) => updateConfig("max", v) }),
1887
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Icon", value: config.icon ?? "star", options: [{ label: "Star", value: "star" }, { label: "Heart", value: "heart" }, { label: "Circle", value: "circle" }], onChange: (v) => updateConfig("icon", v) }),
1888
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Labels", checked: !!config.showLabels, onChange: (v) => updateConfig("showLabels", v) })
1946
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Stars", value: config.max, placeholder: "5", onChange: (v) => updateConfig({ max: v }) }),
1947
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Icon", value: config.icon ?? "star", options: [{ label: "Star", value: "star" }, { label: "Heart", value: "heart" }, { label: "Circle", value: "circle" }], onChange: (v) => updateConfig({ icon: v }) }),
1948
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Labels", checked: !!config.showLabels, onChange: (v) => updateConfig({ showLabels: v }) })
1889
1949
  ] });
1890
1950
  case "nps":
1891
1951
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "NPS Settings", children: [
1892
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Low Label", value: config.lowLabel ?? "Not likely", onChange: (v) => updateConfig("lowLabel", v) }),
1893
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "High Label", value: config.highLabel ?? "Very likely", onChange: (v) => updateConfig("highLabel", v) })
1952
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Low Label", value: config.lowLabel ?? "Not likely", onChange: (v) => updateConfig({ lowLabel: v }) }),
1953
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "High Label", value: config.highLabel ?? "Very likely", onChange: (v) => updateConfig({ highLabel: v }) })
1894
1954
  ] });
1895
1955
  case "opinion_scale":
1896
1956
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Scale Settings", children: [
1897
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Min", value: config.min, placeholder: "1", onChange: (v) => updateConfig("min", v) }),
1898
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max", value: config.max, placeholder: "5", onChange: (v) => updateConfig("max", v) }),
1899
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig("step", v) }),
1900
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Min Label", value: config.minLabel, onChange: (v) => updateConfig("minLabel", v) }),
1901
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Max Label", value: config.maxLabel, onChange: (v) => updateConfig("maxLabel", v) })
1957
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Min", value: config.min, placeholder: "1", onChange: (v) => updateConfig({ min: v }) }),
1958
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max", value: config.max, placeholder: "5", onChange: (v) => updateConfig({ max: v }) }),
1959
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Step", value: config.step, placeholder: "1", onChange: (v) => updateConfig({ step: v }) }),
1960
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Min Label", value: config.minLabel, onChange: (v) => updateConfig({ minLabel: v }) }),
1961
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Max Label", value: config.maxLabel, onChange: (v) => updateConfig({ maxLabel: v }) })
1902
1962
  ] });
1903
1963
  case "likert":
1904
- return /* @__PURE__ */ jsxRuntime.jsx(ConfigSection, { title: "Likert Settings", children: /* @__PURE__ */ jsxRuntime.jsx(LikertLabelsEditor, { labels: config.labels ?? ["Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"], onChange: (v) => updateConfig("labels", v) }) });
1964
+ return /* @__PURE__ */ jsxRuntime.jsx(ConfigSection, { title: "Likert Settings", children: /* @__PURE__ */ jsxRuntime.jsx(LikertLabelsEditor, { labels: config.labels ?? ["Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"], onChange: (v) => updateConfig({ labels: v }) }) });
1905
1965
  // ── Selection ──
1906
1966
  case "single_select":
1907
1967
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Select Settings", children: [
1908
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Layout", value: config.layout ?? "vertical", options: [{ label: "Vertical", value: "vertical" }, { label: "Horizontal", value: "horizontal" }, { label: "Grid", value: "grid" }], onChange: (v) => updateConfig("layout", v) }),
1909
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => updateConfig("allowOther", v) }),
1910
- !!config.allowOther && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Other Label", value: config.otherLabel ?? "Other", onChange: (v) => updateConfig("otherLabel", v) })
1968
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Layout", value: config.layout ?? "vertical", options: [{ label: "Vertical", value: "vertical" }, { label: "Horizontal", value: "horizontal" }, { label: "Grid", value: "grid" }], onChange: (v) => updateConfig({ layout: v }) }),
1969
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => v ? updateConfig({ allowOther: true }) : updateConfig({ allowOther: false, otherLabel: void 0 }) }),
1970
+ !!config.allowOther && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Other Label", value: config.otherLabel ?? "Other", onChange: (v) => updateConfig({ otherLabel: v }) })
1911
1971
  ] });
1912
1972
  case "multi_select":
1913
1973
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Multi-Select Settings", children: [
1914
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Layout", value: config.layout ?? "vertical", options: [{ label: "Vertical", value: "vertical" }, { label: "Horizontal", value: "horizontal" }, { label: "Grid", value: "grid" }], onChange: (v) => updateConfig("layout", v) }),
1915
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Min Selections", value: config.minSelections, onChange: (v) => updateConfig("minSelections", v) }),
1916
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Selections", value: config.maxSelections, onChange: (v) => updateConfig("maxSelections", v) }),
1917
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => updateConfig("allowOther", v) }),
1918
- !!config.allowOther && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Other Label", value: config.otherLabel ?? "Other", onChange: (v) => updateConfig("otherLabel", v) })
1974
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Layout", value: config.layout ?? "vertical", options: [{ label: "Vertical", value: "vertical" }, { label: "Horizontal", value: "horizontal" }, { label: "Grid", value: "grid" }], onChange: (v) => updateConfig({ layout: v }) }),
1975
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Min Selections", value: config.minSelections, onChange: (v) => updateConfig({ minSelections: v }) }),
1976
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Selections", value: config.maxSelections, onChange: (v) => updateConfig({ maxSelections: v }) }),
1977
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => v ? updateConfig({ allowOther: true }) : updateConfig({ allowOther: false, otherLabel: void 0 }) }),
1978
+ !!config.allowOther && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Other Label", value: config.otherLabel ?? "Other", onChange: (v) => updateConfig({ otherLabel: v }) })
1919
1979
  ] });
1920
1980
  case "dropdown":
1921
1981
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Dropdown Settings", children: [
1922
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Searchable", checked: !!config.searchable, onChange: (v) => updateConfig("searchable", v) }),
1923
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => updateConfig("allowOther", v) }),
1924
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Multiple", checked: !!config.multiple, onChange: (v) => updateConfig("multiple", v) })
1982
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Searchable", checked: !!config.searchable, onChange: (v) => updateConfig({ searchable: v }) }),
1983
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Allow Other", checked: !!config.allowOther, onChange: (v) => updateConfig({ allowOther: v }) }),
1984
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Multiple", checked: !!config.multiple, onChange: (v) => updateConfig({ multiple: v }) })
1925
1985
  ] });
1926
1986
  case "boolean":
1927
1987
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Yes/No Settings", children: [
1928
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Style", value: config.style ?? "toggle", options: [{ label: "Toggle", value: "toggle" }, { label: "Radio", value: "radio" }, { label: "Checkbox", value: "checkbox" }], onChange: (v) => updateConfig("style", v) }),
1929
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "True Label", value: config.trueLabel ?? "Yes", onChange: (v) => updateConfig("trueLabel", v) }),
1930
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "False Label", value: config.falseLabel ?? "No", onChange: (v) => updateConfig("falseLabel", v) })
1988
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Style", value: config.style ?? "toggle", options: [{ label: "Toggle", value: "toggle" }, { label: "Radio", value: "radio" }, { label: "Checkbox", value: "checkbox" }], onChange: (v) => updateConfig({ style: v }) }),
1989
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "True Label", value: config.trueLabel ?? "Yes", onChange: (v) => updateConfig({ trueLabel: v }) }),
1990
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "False Label", value: config.falseLabel ?? "No", onChange: (v) => updateConfig({ falseLabel: v }) })
1931
1991
  ] });
1932
1992
  case "country_select":
1933
1993
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Country Settings", children: [
1934
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Flags", checked: config.showFlags !== false, onChange: (v) => updateConfig("showFlags", v) }),
1935
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Priority Countries", value: config.priorityCountries?.join(", "), placeholder: "e.g. US, GB, CA", onChange: (v) => updateConfig("priorityCountries", v ? v.split(",").map((s) => s.trim()).filter(Boolean) : void 0) }),
1936
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Exclude Countries", value: config.excludeCountries?.join(", "), placeholder: "e.g. XX, YY", onChange: (v) => updateConfig("excludeCountries", v ? v.split(",").map((s) => s.trim()).filter(Boolean) : void 0) })
1994
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Flags", checked: config.showFlags !== false, onChange: (v) => updateConfig({ showFlags: v }) }),
1995
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Priority Countries", value: config.priorityCountries?.join(", "), placeholder: "e.g. US, GB, CA", onChange: (v) => updateConfig({ priorityCountries: v ? v.split(",").map((s) => s.trim()).filter(Boolean) : void 0 }) }),
1996
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Exclude Countries", value: config.excludeCountries?.join(", "), placeholder: "e.g. XX, YY", onChange: (v) => updateConfig({ excludeCountries: v ? v.split(",").map((s) => s.trim()).filter(Boolean) : void 0 }) })
1937
1997
  ] });
1938
1998
  // ── Date/Time ──
1939
1999
  case "date":
1940
2000
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Date Settings", children: [
1941
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Min Date", value: config.minDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig("minDate", v) }),
1942
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Max Date", value: config.maxDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig("maxDate", v) }),
1943
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Disable Past Dates", checked: !!config.disablePast, onChange: (v) => updateConfig("disablePast", v) }),
1944
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Disable Future Dates", checked: !!config.disableFuture, onChange: (v) => updateConfig("disableFuture", v) }),
1945
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Format", value: config.format, placeholder: "e.g. MM/DD/YYYY", onChange: (v) => updateConfig("format", v) })
2001
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Min Date", value: config.minDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig({ minDate: v }) }),
2002
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Max Date", value: config.maxDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig({ maxDate: v }) }),
2003
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Disable Past Dates", checked: !!config.disablePast, onChange: (v) => updateConfig({ disablePast: v }) }),
2004
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Disable Future Dates", checked: !!config.disableFuture, onChange: (v) => updateConfig({ disableFuture: v }) }),
2005
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Format", value: config.format, placeholder: "e.g. MM/DD/YYYY", onChange: (v) => updateConfig({ format: v }) })
1946
2006
  ] });
1947
2007
  case "time":
1948
2008
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Time Settings", children: [
1949
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Format", value: config.format ?? "12h", options: [{ label: "12 Hour", value: "12h" }, { label: "24 Hour", value: "24h" }], onChange: (v) => updateConfig("format", v) }),
1950
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Minute Step", value: config.minuteStep, placeholder: "1", onChange: (v) => updateConfig("minuteStep", v) })
2009
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Format", value: config.format ?? "12h", options: [{ label: "12 Hour", value: "12h" }, { label: "24 Hour", value: "24h" }], onChange: (v) => updateConfig({ format: v }) }),
2010
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Minute Step", value: config.minuteStep, placeholder: "1", onChange: (v) => updateConfig({ minuteStep: v }) })
1951
2011
  ] });
1952
2012
  case "date_range":
1953
2013
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Date Range Settings", children: [
1954
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Min Date", value: config.minDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig("minDate", v) }),
1955
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Max Date", value: config.maxDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig("maxDate", v) }),
1956
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Range (days)", value: config.maxRangeDays, onChange: (v) => updateConfig("maxRangeDays", v) })
2014
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Min Date", value: config.minDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig({ minDate: v }) }),
2015
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Max Date", value: config.maxDate, placeholder: "YYYY-MM-DD", onChange: (v) => updateConfig({ maxDate: v }) }),
2016
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Range (days)", value: config.maxRangeDays, onChange: (v) => updateConfig({ maxRangeDays: v }) })
1957
2017
  ] });
1958
- case "appointment":
2018
+ case "appointment": {
2019
+ const appointmentMode = typeof config.embedUrl === "string" ? "embed" : typeof config.slotsUrl === "string" ? "url" : "static";
1959
2020
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Appointment Settings", children: [
1960
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Duration (min)", value: config.duration ?? 30, onChange: (v) => updateConfig("duration", v) }),
1961
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Timezone", value: config.timezone, placeholder: "e.g. America/New_York", onChange: (v) => updateConfig("timezone", v) }),
1962
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Slots URL", value: config.slotsUrl, placeholder: "API endpoint for available slots", onChange: (v) => updateConfig("slotsUrl", v) })
2021
+ /* @__PURE__ */ jsxRuntime.jsx(
2022
+ SelectField,
2023
+ {
2024
+ label: "Mode",
2025
+ value: appointmentMode,
2026
+ options: [
2027
+ { label: "Static Slots", value: "static" },
2028
+ { label: "API Endpoint", value: "url" },
2029
+ { label: "Embed (Calendly / Cal.com)", value: "embed" }
2030
+ ],
2031
+ onChange: (v) => {
2032
+ if (v === "static") {
2033
+ updateConfig({ slotsUrl: void 0, embedUrl: void 0, embedProvider: void 0 });
2034
+ } else if (v === "url") {
2035
+ updateConfig({ slotsUrl: "", embedUrl: void 0, embedProvider: void 0, slots: void 0 });
2036
+ } else if (v === "embed") {
2037
+ updateConfig({ embedUrl: "", slotsUrl: void 0, slots: void 0 });
2038
+ }
2039
+ }
2040
+ }
2041
+ ),
2042
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Duration (min)", value: config.duration ?? 30, onChange: (v) => updateConfig({ duration: v }) }),
2043
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Timezone", value: config.timezone, placeholder: "e.g. America/New_York", onChange: (v) => updateConfig({ timezone: v }) }),
2044
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Timezone Field", value: config.timezoneField, placeholder: "Field ID for dynamic timezone", onChange: (v) => updateConfig({ timezoneField: v }) }),
2045
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Date Format", value: config.dateFormat, placeholder: "Locale-aware (default)", onChange: (v) => updateConfig({ dateFormat: v }) }),
2046
+ appointmentMode === "url" && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Slots URL", value: config.slotsUrl, placeholder: "https://api.example.com/slots", onChange: (v) => updateConfig({ slotsUrl: v }) }),
2047
+ appointmentMode === "embed" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2048
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Embed URL", value: config.embedUrl, placeholder: "https://calendly.com/your-name/30min", onChange: (v) => updateConfig({ embedUrl: v }) }),
2049
+ /* @__PURE__ */ jsxRuntime.jsx(
2050
+ SelectField,
2051
+ {
2052
+ label: "Embed Provider",
2053
+ value: config.embedProvider ?? "custom",
2054
+ options: [
2055
+ { label: "Calendly", value: "calendly" },
2056
+ { label: "Cal.com", value: "cal_com" },
2057
+ { label: "Custom", value: "custom" }
2058
+ ],
2059
+ onChange: (v) => updateConfig({ embedProvider: v })
2060
+ }
2061
+ )
2062
+ ] }),
2063
+ appointmentMode === "static" && /* @__PURE__ */ jsxRuntime.jsx(
2064
+ AppointmentSlotsEditor,
2065
+ {
2066
+ slots: config.slots ?? [],
2067
+ onChange: (v) => updateConfig({ slots: v })
2068
+ }
2069
+ )
1963
2070
  ] });
2071
+ }
1964
2072
  // ── Media ──
1965
2073
  case "file_upload":
1966
2074
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Upload Settings", children: [
1967
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Files", value: config.maxFiles ?? 1, onChange: (v) => updateConfig("maxFiles", v) }),
1968
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Size (MB)", value: config.maxSizeMb ?? 10, onChange: (v) => updateConfig("maxSizeMb", v) }),
1969
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Accepted Types", value: config.accept?.join(", "), placeholder: "e.g. .pdf, .jpg, .png", onChange: (v) => updateConfig("accept", v ? v.split(",").map((s) => s.trim()) : void 0) }),
1970
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Upload URL", value: config.uploadUrl, placeholder: "Server upload endpoint", onChange: (v) => updateConfig("uploadUrl", v) })
2075
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Files", value: config.maxFiles ?? 1, onChange: (v) => updateConfig({ maxFiles: v }) }),
2076
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Size (MB)", value: config.maxSizeMb ?? 10, onChange: (v) => updateConfig({ maxSizeMb: v }) }),
2077
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Accepted Types", value: config.accept?.join(", "), placeholder: "e.g. .pdf, .jpg, .png", onChange: (v) => updateConfig({ accept: v ? v.split(",").map((s) => s.trim()) : void 0 }) }),
2078
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Upload URL", value: config.uploadUrl, placeholder: "Server upload endpoint", onChange: (v) => updateConfig({ uploadUrl: v }) })
1971
2079
  ] });
1972
2080
  case "signature":
1973
2081
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Signature Settings", children: [
1974
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Pen Color", value: config.penColor, placeholder: "#000000", onChange: (v) => updateConfig("penColor", v) }),
1975
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Background", value: config.backgroundColor, placeholder: "#ffffff", onChange: (v) => updateConfig("backgroundColor", v) }),
1976
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Width (px)", value: config.width, onChange: (v) => updateConfig("width", v) }),
1977
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Height (px)", value: config.height, onChange: (v) => updateConfig("height", v) })
2082
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Pen Color", value: config.penColor, placeholder: "#000000", onChange: (v) => updateConfig({ penColor: v }) }),
2083
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Background", value: config.backgroundColor, placeholder: "#ffffff", onChange: (v) => updateConfig({ backgroundColor: v }) }),
2084
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Width (px)", value: config.width, onChange: (v) => updateConfig({ width: v }) }),
2085
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Height (px)", value: config.height, onChange: (v) => updateConfig({ height: v }) })
1978
2086
  ] });
1979
2087
  case "image_capture":
1980
2088
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Camera Settings", children: [
1981
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Camera", value: config.camera ?? "any", options: [{ label: "Any", value: "any" }, { label: "Front", value: "front" }, { label: "Back", value: "back" }], onChange: (v) => updateConfig("camera", v) }),
1982
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Size (MB)", value: config.maxSizeMb, onChange: (v) => updateConfig("maxSizeMb", v) }),
1983
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Allow Gallery", checked: config.allowGallery !== false, onChange: (v) => updateConfig("allowGallery", v) })
2089
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Camera", value: config.camera ?? "any", options: [{ label: "Any", value: "any" }, { label: "Front", value: "front" }, { label: "Back", value: "back" }], onChange: (v) => updateConfig({ camera: v }) }),
2090
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Size (MB)", value: config.maxSizeMb, onChange: (v) => updateConfig({ maxSizeMb: v }) }),
2091
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Allow Gallery", checked: config.allowGallery !== false, onChange: (v) => updateConfig({ allowGallery: v }) })
1984
2092
  ] });
1985
2093
  // ── Content & Visual ──
1986
2094
  case "welcome-screen":
1987
2095
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Welcome Screen", children: [
1988
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Heading", value: config.heading ?? "Welcome", onChange: (v) => updateConfig("heading", v) }),
1989
- /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Description", value: config.description, onChange: (v) => updateConfig("description", v) }),
1990
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Button Text", value: config.buttonText ?? "Start", onChange: (v) => updateConfig("buttonText", v) }),
1991
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Image URL", value: config.imageUrl, placeholder: "https://...", onChange: (v) => updateConfig("imageUrl", v) }),
1992
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Alignment", value: config.alignment ?? "center", options: [{ label: "Left", value: "left" }, { label: "Center", value: "center" }, { label: "Right", value: "right" }], onChange: (v) => updateConfig("alignment", v) })
2096
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Heading", value: config.heading ?? "Welcome", onChange: (v) => updateConfig({ heading: v }) }),
2097
+ /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Description", value: config.description, onChange: (v) => updateConfig({ description: v }) }),
2098
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Button Text", value: config.buttonText ?? "Start", onChange: (v) => updateConfig({ buttonText: v }) }),
2099
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Image URL", value: config.imageUrl, placeholder: "https://...", onChange: (v) => updateConfig({ imageUrl: v }) }),
2100
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Alignment", value: config.alignment ?? "center", options: [{ label: "Left", value: "left" }, { label: "Center", value: "center" }, { label: "Right", value: "right" }], onChange: (v) => updateConfig({ alignment: v }) })
1993
2101
  ] });
1994
2102
  case "thank-you-screen":
1995
2103
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Thank You Screen", children: [
1996
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Heading", value: config.heading ?? "Thank You!", onChange: (v) => updateConfig("heading", v) }),
1997
- /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Description", value: config.description ?? "", onChange: (v) => updateConfig("description", v) }),
1998
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Image URL", value: config.imageUrl, placeholder: "https://...", onChange: (v) => updateConfig("imageUrl", v) }),
1999
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Redirect URL", value: config.redirectUrl, placeholder: "https://...", onChange: (v) => updateConfig("redirectUrl", v) }),
2000
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Redirect Delay (s)", value: config.redirectDelay, placeholder: "0", onChange: (v) => updateConfig("redirectDelay", v) }),
2001
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Response Summary", checked: !!config.showSummary, onChange: (v) => updateConfig("showSummary", v) })
2104
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Heading", value: config.heading ?? "Thank You!", onChange: (v) => updateConfig({ heading: v }) }),
2105
+ /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Description", value: config.description ?? "", onChange: (v) => updateConfig({ description: v }) }),
2106
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Image URL", value: config.imageUrl, placeholder: "https://...", onChange: (v) => updateConfig({ imageUrl: v }) }),
2107
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Redirect URL", value: config.redirectUrl, placeholder: "https://...", onChange: (v) => updateConfig({ redirectUrl: v }) }),
2108
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Redirect Delay (s)", value: config.redirectDelay, placeholder: "0", onChange: (v) => updateConfig({ redirectDelay: v }) }),
2109
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Response Summary", checked: !!config.showSummary, onChange: (v) => updateConfig({ showSummary: v }) })
2002
2110
  ] });
2003
2111
  case "rich-text":
2004
2112
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Rich Text", children: [
2005
- /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Content", value: config.content ?? "", rows: 6, onChange: (v) => updateConfig("content", v) }),
2006
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Format", value: config.format ?? "html", options: [{ label: "HTML", value: "html" }, { label: "Markdown", value: "markdown" }], onChange: (v) => updateConfig("format", v) })
2113
+ /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Content", value: config.content ?? "", rows: 6, onChange: (v) => updateConfig({ content: v }) }),
2114
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Format", value: config.format ?? "html", options: [{ label: "HTML", value: "html" }, { label: "Markdown", value: "markdown" }], onChange: (v) => updateConfig({ format: v }) })
2007
2115
  ] });
2008
2116
  case "image":
2009
2117
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Image Settings", children: [
2010
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Source URL", value: config.src ?? "", placeholder: "https://...", onChange: (v) => updateConfig("src", v) }),
2011
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Alt Text", value: config.alt ?? "", onChange: (v) => updateConfig("alt", v) }),
2012
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Caption", value: config.caption, onChange: (v) => updateConfig("caption", v) }),
2013
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Alignment", value: config.alignment ?? "center", options: [{ label: "Left", value: "left" }, { label: "Center", value: "center" }, { label: "Right", value: "right" }], onChange: (v) => updateConfig("alignment", v) }),
2014
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Width", value: config.width, placeholder: "e.g. 100% or 300px", onChange: (v) => updateConfig("width", v) }),
2015
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Link URL", value: config.link, placeholder: "Click opens this URL", onChange: (v) => updateConfig("link", v) })
2118
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Source URL", value: config.src ?? "", placeholder: "https://...", onChange: (v) => updateConfig({ src: v }) }),
2119
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Alt Text", value: config.alt ?? "", onChange: (v) => updateConfig({ alt: v }) }),
2120
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Caption", value: config.caption, onChange: (v) => updateConfig({ caption: v }) }),
2121
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Alignment", value: config.alignment ?? "center", options: [{ label: "Left", value: "left" }, { label: "Center", value: "center" }, { label: "Right", value: "right" }], onChange: (v) => updateConfig({ alignment: v }) }),
2122
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Width", value: config.width, placeholder: "e.g. 100% or 300px", onChange: (v) => updateConfig({ width: v }) }),
2123
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Link URL", value: config.link, placeholder: "Click opens this URL", onChange: (v) => updateConfig({ link: v }) })
2016
2124
  ] });
2017
2125
  case "video":
2018
2126
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Video Settings", children: [
2019
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Source URL", value: config.src ?? "", placeholder: "YouTube/Vimeo URL", onChange: (v) => updateConfig("src", v) }),
2020
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Provider", value: config.provider ?? "youtube", options: [{ label: "YouTube", value: "youtube" }, { label: "Vimeo", value: "vimeo" }, { label: "Direct URL", value: "url" }], onChange: (v) => updateConfig("provider", v) }),
2021
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Autoplay", checked: !!config.autoplay, onChange: (v) => updateConfig("autoplay", v) }),
2022
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Muted", checked: !!config.muted, onChange: (v) => updateConfig("muted", v) }),
2023
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Width", value: config.width, placeholder: "e.g. 100% or 640px", onChange: (v) => updateConfig("width", v) }),
2024
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Height", value: config.height, placeholder: "e.g. 360px", onChange: (v) => updateConfig("height", v) })
2127
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Source URL", value: config.src ?? "", placeholder: "YouTube/Vimeo URL", onChange: (v) => updateConfig({ src: v }) }),
2128
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Provider", value: config.provider ?? "youtube", options: [{ label: "YouTube", value: "youtube" }, { label: "Vimeo", value: "vimeo" }, { label: "Direct URL", value: "url" }], onChange: (v) => updateConfig({ provider: v }) }),
2129
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Autoplay", checked: !!config.autoplay, onChange: (v) => updateConfig({ autoplay: v }) }),
2130
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Muted", checked: !!config.muted, onChange: (v) => updateConfig({ muted: v }) }),
2131
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Width", value: config.width, placeholder: "e.g. 100% or 640px", onChange: (v) => updateConfig({ width: v }) }),
2132
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Height", value: config.height, placeholder: "e.g. 360px", onChange: (v) => updateConfig({ height: v }) })
2025
2133
  ] });
2026
2134
  case "divider":
2027
2135
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Divider Settings", children: [
2028
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Style", value: config.style ?? "solid", options: [{ label: "Solid", value: "solid" }, { label: "Dashed", value: "dashed" }, { label: "Dotted", value: "dotted" }], onChange: (v) => updateConfig("style", v) }),
2029
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Color", value: config.color, placeholder: "#e5e7eb", onChange: (v) => updateConfig("color", v) }),
2030
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Thickness (px)", value: config.thickness, placeholder: "1", onChange: (v) => updateConfig("thickness", v) }),
2031
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Spacing (px)", value: config.spacing, placeholder: "16", onChange: (v) => updateConfig("spacing", v) })
2136
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Style", value: config.style ?? "solid", options: [{ label: "Solid", value: "solid" }, { label: "Dashed", value: "dashed" }, { label: "Dotted", value: "dotted" }], onChange: (v) => updateConfig({ style: v }) }),
2137
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Color", value: config.color, placeholder: "#e5e7eb", onChange: (v) => updateConfig({ color: v }) }),
2138
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Thickness (px)", value: config.thickness, placeholder: "1", onChange: (v) => updateConfig({ thickness: v }) }),
2139
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Spacing (px)", value: config.spacing, placeholder: "16", onChange: (v) => updateConfig({ spacing: v }) })
2032
2140
  ] });
2033
2141
  case "spacer":
2034
- return /* @__PURE__ */ jsxRuntime.jsx(ConfigSection, { title: "Spacer Settings", children: /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Height (px)", value: config.height ?? 32, onChange: (v) => updateConfig("height", v) }) });
2142
+ return /* @__PURE__ */ jsxRuntime.jsx(ConfigSection, { title: "Spacer Settings", children: /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Height (px)", value: config.height ?? 32, onChange: (v) => updateConfig({ height: v }) }) });
2035
2143
  // ── Structural ──
2036
2144
  case "section_header":
2037
2145
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Header Settings", children: [
2038
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Level", value: config.level ?? "h3", options: [{ label: "H2", value: "h2" }, { label: "H3", value: "h3" }, { label: "H4", value: "h4" }], onChange: (v) => updateConfig("level", v) }),
2039
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Divider", checked: !!config.showDivider, onChange: (v) => updateConfig("showDivider", v) })
2146
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Level", value: config.level ?? "h3", options: [{ label: "H2", value: "h2" }, { label: "H3", value: "h3" }, { label: "H4", value: "h4" }], onChange: (v) => updateConfig({ level: v }) }),
2147
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Divider", checked: !!config.showDivider, onChange: (v) => updateConfig({ showDivider: v }) })
2040
2148
  ] });
2041
2149
  case "info_block":
2042
2150
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Info Block", children: [
2043
- /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Content", value: config.content ?? "", rows: 4, onChange: (v) => updateConfig("content", v) }),
2044
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Variant", value: config.variant ?? "info", options: [{ label: "Info", value: "info" }, { label: "Warning", value: "warning" }, { label: "Success", value: "success" }, { label: "Error", value: "error" }], onChange: (v) => updateConfig("variant", v) })
2151
+ /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Content", value: config.content ?? "", rows: 4, onChange: (v) => updateConfig({ content: v }) }),
2152
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Variant", value: config.variant ?? "info", options: [{ label: "Info", value: "info" }, { label: "Warning", value: "warning" }, { label: "Success", value: "success" }, { label: "Error", value: "error" }], onChange: (v) => updateConfig({ variant: v }) })
2045
2153
  ] });
2046
2154
  case "page_break":
2047
- return /* @__PURE__ */ jsxRuntime.jsx(ConfigSection, { title: "Page Break", children: /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Label", value: config.label, placeholder: "Next page label", onChange: (v) => updateConfig("label", v) }) });
2155
+ return /* @__PURE__ */ jsxRuntime.jsx(ConfigSection, { title: "Page Break", children: /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Label", value: config.label, placeholder: "Next page label", onChange: (v) => updateConfig({ label: v }) }) });
2048
2156
  case "consent":
2049
2157
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Consent Settings", children: [
2050
- /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Consent Text", value: config.text ?? "", rows: 4, onChange: (v) => updateConfig("text", v) }),
2051
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Checkbox Label", value: config.checkboxLabel ?? "I agree", onChange: (v) => updateConfig("checkboxLabel", v) }),
2052
- /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Expandable Text", value: config.expandableText, rows: 3, placeholder: "Additional text shown on expand", onChange: (v) => updateConfig("expandableText", v) })
2158
+ /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Consent Text", value: config.text ?? "", rows: 4, onChange: (v) => updateConfig({ text: v }) }),
2159
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Checkbox Label", value: config.checkboxLabel ?? "I agree", onChange: (v) => updateConfig({ checkboxLabel: v }) }),
2160
+ /* @__PURE__ */ jsxRuntime.jsx(TextareaField, { label: "Expandable Text", value: config.expandableText, rows: 3, placeholder: "Additional text shown on expand", onChange: (v) => updateConfig({ expandableText: v }) })
2053
2161
  ] });
2054
2162
  // ── Advanced ──
2055
2163
  case "matrix":
2056
2164
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Matrix Settings", children: [
2057
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Input Type", value: config.inputType ?? "radio", options: [{ label: "Radio", value: "radio" }, { label: "Checkbox", value: "checkbox" }, { label: "Text", value: "text" }, { label: "Number", value: "number" }], onChange: (v) => updateConfig("inputType", v) }),
2058
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Required", value: config.required ?? "none", options: [{ label: "All rows", value: "all" }, { label: "Any row", value: "any" }, { label: "None", value: "none" }], onChange: (v) => updateConfig("required", v) }),
2059
- /* @__PURE__ */ jsxRuntime.jsx(MatrixItemsEditor, { label: "Rows", items: config.rows ?? [], onChange: (v) => updateConfig("rows", v) }),
2060
- /* @__PURE__ */ jsxRuntime.jsx(MatrixItemsEditor, { label: "Columns", items: config.columns ?? [], onChange: (v) => updateConfig("columns", v) })
2165
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Input Type", value: config.inputType ?? "radio", options: [{ label: "Radio", value: "radio" }, { label: "Checkbox", value: "checkbox" }, { label: "Text", value: "text" }, { label: "Number", value: "number" }], onChange: (v) => updateConfig({ inputType: v }) }),
2166
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Required", value: config.required ?? "none", options: [{ label: "All rows", value: "all" }, { label: "Any row", value: "any" }, { label: "None", value: "none" }], onChange: (v) => updateConfig({ required: v }) }),
2167
+ /* @__PURE__ */ jsxRuntime.jsx(MatrixItemsEditor, { label: "Rows", items: config.rows ?? [], onChange: (v) => updateConfig({ rows: v }) }),
2168
+ /* @__PURE__ */ jsxRuntime.jsx(MatrixItemsEditor, { label: "Columns", items: config.columns ?? [], onChange: (v) => updateConfig({ columns: v }) })
2061
2169
  ] });
2062
2170
  case "repeater":
2063
2171
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Repeater Settings", children: [
2064
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Min Entries", value: config.minEntries, placeholder: "1", onChange: (v) => updateConfig("minEntries", v) }),
2065
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Entries", value: config.maxEntries, onChange: (v) => updateConfig("maxEntries", v) }),
2066
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Default Entries", value: config.defaultEntries, placeholder: "1", onChange: (v) => updateConfig("defaultEntries", v) }),
2067
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Add Button Label", value: config.addLabel, placeholder: "Add Entry", onChange: (v) => updateConfig("addLabel", v) }),
2068
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Remove Button Label", value: config.removeLabel, placeholder: "Remove", onChange: (v) => updateConfig("removeLabel", v) }),
2172
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Min Entries", value: config.minEntries, placeholder: "1", onChange: (v) => updateConfig({ minEntries: v }) }),
2173
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Max Entries", value: config.maxEntries, onChange: (v) => updateConfig({ maxEntries: v }) }),
2174
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Default Entries", value: config.defaultEntries, placeholder: "1", onChange: (v) => updateConfig({ defaultEntries: v }) }),
2175
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Add Button Label", value: config.addLabel, placeholder: "Add Entry", onChange: (v) => updateConfig({ addLabel: v }) }),
2176
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Remove Button Label", value: config.removeLabel, placeholder: "Remove", onChange: (v) => updateConfig({ removeLabel: v }) }),
2069
2177
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-[11px] text-muted-foreground leading-relaxed", children: "Sub-fields for each repeater entry are configured by nesting questions inside the repeater in the schema JSON." })
2070
2178
  ] });
2071
2179
  case "address": {
@@ -2079,9 +2187,9 @@ function QuestionConfigEditor({ question, onUpdate }) {
2079
2187
  ];
2080
2188
  const activeFields = config.fields ?? ["street", "city", "state", "zip", "country"];
2081
2189
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Address Settings", children: [
2082
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Provider", value: config.provider ?? "none", options: [{ label: "None", value: "none" }, { label: "Google", value: "google" }, { label: "Mapbox", value: "mapbox" }], onChange: (v) => updateConfig("provider", v) }),
2083
- config.provider !== "none" && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "API Key", value: config.apiKey, placeholder: "Provider API key", onChange: (v) => updateConfig("apiKey", v) }),
2084
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Default Country", value: config.defaultCountry, placeholder: "e.g. US", onChange: (v) => updateConfig("defaultCountry", v) }),
2190
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Provider", value: config.provider ?? "none", options: [{ label: "None", value: "none" }, { label: "Google", value: "google" }, { label: "Mapbox", value: "mapbox" }], onChange: (v) => updateConfig({ provider: v }) }),
2191
+ config.provider !== "none" && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "API Key", value: config.apiKey, placeholder: "Provider API key", onChange: (v) => updateConfig({ apiKey: v }) }),
2192
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Default Country", value: config.defaultCountry, placeholder: "e.g. US", onChange: (v) => updateConfig({ defaultCountry: v }) }),
2085
2193
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2086
2194
  /* @__PURE__ */ jsxRuntime.jsx(fieldcraftReact.Label, { className: "text-xs text-muted-foreground mb-2 block", children: "Fields" }),
2087
2195
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5", children: ADDRESS_FIELDS.map((f) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -2091,7 +2199,7 @@ function QuestionConfigEditor({ question, onUpdate }) {
2091
2199
  checked: activeFields.includes(f.value),
2092
2200
  onChange: (checked) => {
2093
2201
  const next = checked ? [...activeFields, f.value] : activeFields.filter((v) => v !== f.value);
2094
- updateConfig("fields", next.length > 0 ? next : void 0);
2202
+ updateConfig({ fields: next.length > 0 ? next : void 0 });
2095
2203
  }
2096
2204
  },
2097
2205
  f.value
@@ -2101,41 +2209,47 @@ function QuestionConfigEditor({ question, onUpdate }) {
2101
2209
  }
2102
2210
  case "payment":
2103
2211
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Payment Settings", children: [
2104
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Provider", value: config.provider ?? "stripe", options: [{ label: "Stripe", value: "stripe" }, { label: "PayPal", value: "paypal" }], onChange: (v) => updateConfig("provider", v) }),
2105
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Public Key", value: config.publicKey ?? "", placeholder: "Provider public/client key", onChange: (v) => updateConfig("publicKey", v) }),
2106
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Amount", value: config.amount, onChange: (v) => updateConfig("amount", v) }),
2107
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Amount Field", value: config.amountField, placeholder: "Field ID for dynamic amount", onChange: (v) => updateConfig("amountField", v) }),
2108
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Currency", value: config.currency, placeholder: "USD", onChange: (v) => updateConfig("currency", v) }),
2109
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Description", value: config.description, onChange: (v) => updateConfig("description", v) })
2212
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Provider", value: config.provider ?? "stripe", options: [{ label: "Stripe", value: "stripe" }, { label: "PayPal", value: "paypal" }], onChange: (v) => updateConfig({ provider: v }) }),
2213
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Public Key", value: config.publicKey ?? "", placeholder: "Provider public/client key", onChange: (v) => updateConfig({ publicKey: v }) }),
2214
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Server URL", value: config.serverUrl ?? "", placeholder: "https://api.example.com/create-intent", onChange: (v) => updateConfig({ serverUrl: v || void 0 }) }),
2215
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Client Secret Path", value: config.responseMapping?.clientSecretPath ?? "", placeholder: "clientSecret", onChange: (v) => updateConfig({ responseMapping: v ? { clientSecretPath: v } : void 0 }) }),
2216
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Amount", value: config.amount, onChange: (v) => updateConfig({ amount: v }) }),
2217
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Amount Field", value: config.amountField, placeholder: "Field ID for dynamic amount", onChange: (v) => updateConfig({ amountField: v }) }),
2218
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Currency", value: config.currency, placeholder: "USD", onChange: (v) => updateConfig({ currency: v }) }),
2219
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Description", value: config.description, onChange: (v) => updateConfig({ description: v }) })
2110
2220
  ] });
2111
2221
  case "calculated":
2112
2222
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Calculated Field", children: [
2113
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Expression", value: config.expression ?? "", placeholder: "e.g. {q1} + {q2}", onChange: (v) => updateConfig("expression", v) }),
2114
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Format", value: config.format ?? "number", options: [{ label: "Number", value: "number" }, { label: "Currency", value: "currency" }, { label: "Percentage", value: "percentage" }], onChange: (v) => updateConfig("format", v) }),
2115
- /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Decimal Places", value: config.decimalPlaces, placeholder: "2", onChange: (v) => updateConfig("decimalPlaces", v) }),
2116
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Prefix", value: config.prefix, onChange: (v) => updateConfig("prefix", v) }),
2117
- /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Suffix", value: config.suffix, onChange: (v) => updateConfig("suffix", v) }),
2118
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Visible to User", checked: config.visible !== false, onChange: (v) => updateConfig("visible", v) })
2223
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Expression", value: config.expression ?? "", placeholder: "e.g. {q1} + {q2}", onChange: (v) => updateConfig({ expression: v }) }),
2224
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Format", value: config.format ?? "number", options: [{ label: "Number", value: "number" }, { label: "Currency", value: "currency" }, { label: "Percentage", value: "percentage" }], onChange: (v) => updateConfig({ format: v }) }),
2225
+ /* @__PURE__ */ jsxRuntime.jsx(NumberField, { label: "Decimal Places", value: config.decimalPlaces, placeholder: "2", onChange: (v) => updateConfig({ decimalPlaces: v }) }),
2226
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Prefix", value: config.prefix, onChange: (v) => updateConfig({ prefix: v }) }),
2227
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Suffix", value: config.suffix, onChange: (v) => updateConfig({ suffix: v }) }),
2228
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Visible to User", checked: config.visible !== false, onChange: (v) => updateConfig({ visible: v }) })
2119
2229
  ] });
2120
2230
  case "hidden":
2121
2231
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Hidden Field", children: [
2122
- /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Source", value: config.source ?? "static", options: [{ label: "Static Value", value: "static" }, { label: "URL Parameter", value: "url_param" }, { label: "Cookie", value: "cookie" }, { label: "Referrer", value: "referrer" }], onChange: (v) => updateConfig("source", v) }),
2123
- config.source === "static" && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Default Value", value: config.defaultValue, onChange: (v) => updateConfig("defaultValue", v) }),
2124
- config.source === "url_param" && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Parameter Name", value: config.paramName, placeholder: "e.g. utm_source", onChange: (v) => updateConfig("paramName", v) }),
2125
- config.source === "cookie" && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Cookie Name", value: config.cookieName, onChange: (v) => updateConfig("cookieName", v) })
2232
+ /* @__PURE__ */ jsxRuntime.jsx(SelectField, { label: "Source", value: config.source ?? "static", options: [{ label: "Static Value", value: "static" }, { label: "URL Parameter", value: "url_param" }, { label: "Cookie", value: "cookie" }, { label: "Referrer", value: "referrer" }], onChange: (v) => updateConfig({ source: v }) }),
2233
+ config.source === "static" && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Default Value", value: config.defaultValue, onChange: (v) => updateConfig({ defaultValue: v }) }),
2234
+ config.source === "url_param" && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Parameter Name", value: config.paramName, placeholder: "e.g. utm_source", onChange: (v) => updateConfig({ paramName: v }) }),
2235
+ config.source === "cookie" && /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Cookie Name", value: config.cookieName, onChange: (v) => updateConfig({ cookieName: v }) })
2126
2236
  ] });
2127
2237
  case "scoring":
2128
2238
  return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "Scoring Settings", children: [
2129
- /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Score", checked: !!config.showScore, onChange: (v) => updateConfig("showScore", v) }),
2130
- /* @__PURE__ */ jsxRuntime.jsx(ScoringOptionsEditor, { options: config.options ?? [], onChange: (v) => updateConfig("options", v) }),
2131
- /* @__PURE__ */ jsxRuntime.jsx(ScoreRangesEditor, { ranges: config.scoreRanges ?? [], onChange: (v) => updateConfig("scoreRanges", v) })
2239
+ /* @__PURE__ */ jsxRuntime.jsx(ToggleField, { label: "Show Score", checked: !!config.showScore, onChange: (v) => updateConfig({ showScore: v }) }),
2240
+ /* @__PURE__ */ jsxRuntime.jsx(ScoringOptionsEditor, { options: config.options ?? [], onChange: (v) => updateConfig({ options: v }) }),
2241
+ /* @__PURE__ */ jsxRuntime.jsx(ScoreRangesEditor, { ranges: config.scoreRanges ?? [], onChange: (v) => updateConfig({ scoreRanges: v }) })
2132
2242
  ] });
2133
2243
  case "ranking":
2134
- return /* @__PURE__ */ jsxRuntime.jsx(ConfigSection, { title: "Ranking Settings", children: /* @__PURE__ */ jsxRuntime.jsx(MatrixItemsEditor, { label: "Items", items: config.items ?? [], onChange: (v) => updateConfig("items", v) }) });
2244
+ return /* @__PURE__ */ jsxRuntime.jsx(ConfigSection, { title: "Ranking Settings", children: /* @__PURE__ */ jsxRuntime.jsx(MatrixItemsEditor, { label: "Items", items: config.items ?? [], onChange: (v) => updateConfig({ items: v }) }) });
2245
+ case "phone_international":
2246
+ return /* @__PURE__ */ jsxRuntime.jsxs(ConfigSection, { title: "International Phone Settings", children: [
2247
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Default Country", value: config.defaultCountry ?? "US", placeholder: "e.g. US", onChange: (v) => updateConfig({ defaultCountry: v }) }),
2248
+ /* @__PURE__ */ jsxRuntime.jsx(TextField, { label: "Priority Countries", value: config.priorityCountries?.join(", "), placeholder: "e.g. US, GB, CA", onChange: (v) => updateConfig({ priorityCountries: v ? v.split(",").map((s) => s.trim()).filter(Boolean) : void 0 }) })
2249
+ ] });
2135
2250
  // Types with no additional config
2136
2251
  case "email":
2137
2252
  case "phone":
2138
- case "phone_international":
2139
2253
  case "url":
2140
2254
  return null;
2141
2255
  default:
@@ -2227,7 +2341,10 @@ function SelectField({
2227
2341
  }) {
2228
2342
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2229
2343
  /* @__PURE__ */ jsxRuntime.jsx(fieldcraftReact.Label, { className: "text-xs text-muted-foreground mb-1", children: label }),
2230
- /* @__PURE__ */ jsxRuntime.jsx(NativeSelect, { value, onChange: (e) => onChange(e.target.value), children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value)) })
2344
+ /* @__PURE__ */ jsxRuntime.jsxs(Select, { value, onValueChange: onChange, children: [
2345
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: options.find((o) => o.value === value)?.label ?? value }) }),
2346
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
2347
+ ] })
2231
2348
  ] });
2232
2349
  }
2233
2350
  function LikertLabelsEditor({
@@ -2373,6 +2490,59 @@ function ScoringOptionsEditor({
2373
2490
  ] }, index)) })
2374
2491
  ] });
2375
2492
  }
2493
+ function AppointmentSlotsEditor({
2494
+ slots,
2495
+ onChange
2496
+ }) {
2497
+ const handleDateChange = (index, date) => {
2498
+ const updated = slots.map((s, i) => i === index ? { ...s, date } : s);
2499
+ onChange(updated);
2500
+ };
2501
+ const handleTimesChange = (index, timesStr) => {
2502
+ const times = timesStr.split(",").map((t) => t.trim()).filter(Boolean);
2503
+ const updated = slots.map((s, i) => i === index ? { ...s, times } : s);
2504
+ onChange(updated);
2505
+ };
2506
+ const handleAdd = () => {
2507
+ const tomorrow = /* @__PURE__ */ new Date();
2508
+ tomorrow.setDate(tomorrow.getDate() + 1);
2509
+ const dateStr = tomorrow.toISOString().split("T")[0];
2510
+ onChange([...slots, { date: dateStr, times: ["09:00", "10:00", "11:00", "14:00", "15:00"] }]);
2511
+ };
2512
+ const handleRemove = (index) => {
2513
+ onChange(slots.filter((_, i) => i !== index));
2514
+ };
2515
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2516
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
2517
+ /* @__PURE__ */ jsxRuntime.jsx(fieldcraftReact.Label, { className: "text-xs text-muted-foreground", children: "Slots" }),
2518
+ /* @__PURE__ */ jsxRuntime.jsx(fieldcraftReact.Button, { type: "button", variant: "link", size: "xs", onClick: handleAdd, className: "px-0", children: "+ Add Date" })
2519
+ ] }),
2520
+ slots.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-muted-foreground", children: "No slots configured. Add a date to get started." }),
2521
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: slots.map((slot, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 rounded-md border border-border space-y-1.5 group", children: [
2522
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
2523
+ /* @__PURE__ */ jsxRuntime.jsx(
2524
+ fieldcraftReact.Input,
2525
+ {
2526
+ type: "date",
2527
+ value: slot.date,
2528
+ onChange: (e) => handleDateChange(index, e.target.value),
2529
+ className: "h-7 text-xs flex-1"
2530
+ }
2531
+ ),
2532
+ /* @__PURE__ */ jsxRuntime.jsx(fieldcraftReact.Button, { type: "button", variant: "ghost", size: "icon-xs", onClick: () => handleRemove(index), className: "text-destructive opacity-0 group-hover:opacity-100 transition-opacity", children: "x" })
2533
+ ] }),
2534
+ /* @__PURE__ */ jsxRuntime.jsx(
2535
+ fieldcraftReact.Input,
2536
+ {
2537
+ value: slot.times.join(", "),
2538
+ onChange: (e) => handleTimesChange(index, e.target.value),
2539
+ className: "h-7 text-xs",
2540
+ placeholder: "09:00, 10:00, 14:00, 15:00"
2541
+ }
2542
+ )
2543
+ ] }, index)) })
2544
+ ] });
2545
+ }
2376
2546
  function ScoreRangesEditor({
2377
2547
  ranges,
2378
2548
  onChange
@@ -2405,6 +2575,26 @@ function ScoreRangesEditor({
2405
2575
  ] }, index)) })
2406
2576
  ] });
2407
2577
  }
2578
+ var NativeSelect = React.forwardRef(
2579
+ ({ className, wrapperClassName, children, ...props }, ref) => {
2580
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", wrapperClassName), children: [
2581
+ /* @__PURE__ */ jsxRuntime.jsx(
2582
+ "select",
2583
+ {
2584
+ ref,
2585
+ className: cn(
2586
+ "flex h-9 w-full appearance-none rounded-md border border-input bg-card px-3 py-1 pr-8 text-sm shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring text-foreground cursor-pointer",
2587
+ className
2588
+ ),
2589
+ ...props,
2590
+ children
2591
+ }
2592
+ ),
2593
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "pointer-events-none absolute right-2.5 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" })
2594
+ ] });
2595
+ }
2596
+ );
2597
+ NativeSelect.displayName = "NativeSelect";
2408
2598
  var RULE_TYPES = [
2409
2599
  { value: "minLength", label: "Min Length", description: "Minimum character count" },
2410
2600
  { value: "maxLength", label: "Max Length", description: "Maximum character count" },
@@ -2809,7 +2999,7 @@ function FormSettingsPanel({ schema, onUpdate }) {
2809
2999
  ];
2810
3000
  const displayMode = settings.displayMode ?? "stepped";
2811
3001
  const effectiveDisplayMode = hasConditions && displayMode === "classic" ? "stepped" : displayMode;
2812
- react.useEffect(() => {
3002
+ React.useEffect(() => {
2813
3003
  if (effectiveDisplayMode !== displayMode) {
2814
3004
  onUpdate({ ...schema, settings: { ...settings, displayMode: effectiveDisplayMode } });
2815
3005
  }
@@ -2966,7 +3156,7 @@ function SettingsSelect({
2966
3156
  }
2967
3157
  function PropertiesPanel({ builderState }) {
2968
3158
  const { schema, selectedItem } = builderState;
2969
- const [showSettings, setShowSettings] = react.useState(false);
3159
+ const [showSettings, setShowSettings] = React.useState(false);
2970
3160
  if (showSettings) {
2971
3161
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-80 h-full border-l border-border bg-card flex flex-col", children: [
2972
3162
  /* @__PURE__ */ jsxRuntime.jsx(PanelHeader, { title: "Form Settings", onClose: () => setShowSettings(false) }),
@@ -3041,11 +3231,11 @@ function SectionProperties({ section, onUpdate, onClose, onOpenSettings }) {
3041
3231
  ] });
3042
3232
  }
3043
3233
  function QuestionProperties({ question, sectionId, builderState, onClose, onOpenSettings }) {
3044
- const [activeTab, setActiveTab] = react.useState("basic");
3234
+ const [activeTab, setActiveTab] = React.useState("basic");
3045
3235
  const typeInfo = QUESTION_TYPE_INFO[question.type];
3046
3236
  const IconComponent = typeInfo ? getIcon(typeInfo.icon) : null;
3047
3237
  const hasOptions = typeInfo?.requiresOptions || question.options && question.options.length > 0;
3048
- const updateQuestion2 = react.useCallback(
3238
+ const updateQuestion2 = React.useCallback(
3049
3239
  (updates) => {
3050
3240
  builderState.updateQuestion(sectionId, question.id, updates);
3051
3241
  },
@@ -3220,7 +3410,7 @@ function FieldGroup({ label, children }) {
3220
3410
  children
3221
3411
  ] });
3222
3412
  }
3223
- var PreviewErrorBoundary = class extends react.Component {
3413
+ var PreviewErrorBoundary = class extends React.Component {
3224
3414
  state = { error: null };
3225
3415
  static getDerivedStateFromError(error) {
3226
3416
  return { error };
@@ -3281,15 +3471,15 @@ function errorsToMarkers(errors) {
3281
3471
  source: "FieldCraft Schema Validator"
3282
3472
  }));
3283
3473
  }
3284
- var Editor = react.lazy(() => import('@monaco-editor/react').then((m) => ({ default: m.default })));
3474
+ var Editor = React.lazy(() => import('@monaco-editor/react').then((m) => ({ default: m.default })));
3285
3475
  function MonacoWrapper({ value, onChange, errors }) {
3286
- const editorRef = react.useRef(null);
3287
- const monacoRef = react.useRef(null);
3476
+ const editorRef = React.useRef(null);
3477
+ const monacoRef = React.useRef(null);
3288
3478
  const handleMount = (editor, monaco) => {
3289
3479
  editorRef.current = editor;
3290
3480
  monacoRef.current = monaco;
3291
3481
  };
3292
- react.useEffect(() => {
3482
+ React.useEffect(() => {
3293
3483
  const editor = editorRef.current;
3294
3484
  const monaco = monacoRef.current;
3295
3485
  if (!editor || !monaco) return;
@@ -3321,14 +3511,14 @@ function MonacoWrapper({ value, onChange, errors }) {
3321
3511
  );
3322
3512
  }
3323
3513
  function JsonEditorPanel({ value, onChange, errors, onValidate }) {
3324
- const handleChange = react.useCallback(
3514
+ const handleChange = React.useCallback(
3325
3515
  (newValue) => {
3326
3516
  onChange(newValue);
3327
3517
  onValidate(newValue);
3328
3518
  },
3329
3519
  [onChange, onValidate]
3330
3520
  );
3331
- const handleFormat = react.useCallback(() => {
3521
+ const handleFormat = React.useCallback(() => {
3332
3522
  try {
3333
3523
  const formatted = JSON.stringify(JSON.parse(value), null, 2);
3334
3524
  onChange(formatted);
@@ -3361,7 +3551,7 @@ function JsonEditorPanel({ value, onChange, errors, onValidate }) {
3361
3551
  )
3362
3552
  ] }),
3363
3553
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
3364
- react.Suspense,
3554
+ React.Suspense,
3365
3555
  {
3366
3556
  fallback: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center h-full text-sm text-muted-foreground", children: "Loading editor..." }),
3367
3557
  children: /* @__PURE__ */ jsxRuntime.jsx(MonacoWrapper, { value, onChange: handleChange, errors })
@@ -3560,7 +3750,7 @@ function SectionNodeInner({ data }) {
3560
3750
  const d = data;
3561
3751
  const color = SECTION_COLORS[d.colorIndex % SECTION_COLORS.length];
3562
3752
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fc-flow-section-group", style: { borderColor: color }, children: [
3563
- /* @__PURE__ */ jsxRuntime.jsx(react$1.Handle, { type: "target", position: react$1.Position.Left, className: "fc-flow-handle fc-flow-handle--section" }),
3753
+ /* @__PURE__ */ jsxRuntime.jsx(react.Handle, { type: "target", position: react.Position.Left, className: "fc-flow-handle fc-flow-handle--section" }),
3564
3754
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fc-flow-section-group__header", style: { background: color }, children: [
3565
3755
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "fc-flow-section-group__label", children: d.label.length > 30 ? d.label.slice(0, 30) + "\u2026" : d.label }),
3566
3756
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "fc-flow-section-group__meta", children: [
@@ -3571,10 +3761,10 @@ function SectionNodeInner({ data }) {
3571
3761
  d.hasExitLogic && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "fc-flow-section-group__badge fc-flow-section-group__badge--jump", title: "Has onExit jump", children: "\u2934" })
3572
3762
  ] })
3573
3763
  ] }),
3574
- /* @__PURE__ */ jsxRuntime.jsx(react$1.Handle, { type: "source", position: react$1.Position.Right, className: "fc-flow-handle fc-flow-handle--section" })
3764
+ /* @__PURE__ */ jsxRuntime.jsx(react.Handle, { type: "source", position: react.Position.Right, className: "fc-flow-handle fc-flow-handle--section" })
3575
3765
  ] });
3576
3766
  }
3577
- var SectionNode = react.memo(SectionNodeInner);
3767
+ var SectionNode = React.memo(SectionNodeInner);
3578
3768
  function FieldNodeInner({ data }) {
3579
3769
  const d = data;
3580
3770
  const color = SECTION_COLORS[d.colorIndex % SECTION_COLORS.length];
@@ -3587,18 +3777,18 @@ function FieldNodeInner({ data }) {
3587
3777
  borderWidth: d.hasCondition ? 2 : 1
3588
3778
  },
3589
3779
  children: [
3590
- /* @__PURE__ */ jsxRuntime.jsx(react$1.Handle, { type: "target", position: react$1.Position.Left, className: "fc-flow-handle" }),
3780
+ /* @__PURE__ */ jsxRuntime.jsx(react.Handle, { type: "target", position: react.Position.Left, className: "fc-flow-handle" }),
3591
3781
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fc-flow-field__content", children: [
3592
3782
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "fc-flow-field__label", children: d.label.length > 26 ? d.label.slice(0, 26) + "\u2026" : d.label }),
3593
3783
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "fc-flow-field__type", children: d.fieldType })
3594
3784
  ] }),
3595
3785
  d.hasCondition && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fc-flow-badge", style: { background: color }, title: "Has showIf condition", children: "?" }),
3596
- /* @__PURE__ */ jsxRuntime.jsx(react$1.Handle, { type: "source", position: react$1.Position.Right, className: "fc-flow-handle" })
3786
+ /* @__PURE__ */ jsxRuntime.jsx(react.Handle, { type: "source", position: react.Position.Right, className: "fc-flow-handle" })
3597
3787
  ]
3598
3788
  }
3599
3789
  );
3600
3790
  }
3601
- var FieldNode = react.memo(FieldNodeInner);
3791
+ var FieldNode = React.memo(FieldNodeInner);
3602
3792
  var logicFlowNodeTypes = {
3603
3793
  sectionNode: SectionNode,
3604
3794
  fieldNode: FieldNode
@@ -3616,7 +3806,7 @@ function ConditionEdgeInner({
3616
3806
  data,
3617
3807
  markerEnd
3618
3808
  }) {
3619
- const [edgePath, labelX, labelY] = react$1.getBezierPath({
3809
+ const [edgePath, labelX, labelY] = react.getBezierPath({
3620
3810
  sourceX,
3621
3811
  sourceY,
3622
3812
  sourcePosition,
@@ -3627,7 +3817,7 @@ function ConditionEdgeInner({
3627
3817
  const isJump = data?.edgeType === "onExit";
3628
3818
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3629
3819
  /* @__PURE__ */ jsxRuntime.jsx(
3630
- react$1.BaseEdge,
3820
+ react.BaseEdge,
3631
3821
  {
3632
3822
  id,
3633
3823
  path: edgePath,
@@ -3640,7 +3830,7 @@ function ConditionEdgeInner({
3640
3830
  }
3641
3831
  }
3642
3832
  ),
3643
- label && /* @__PURE__ */ jsxRuntime.jsx(react$1.EdgeLabelRenderer, { children: /* @__PURE__ */ jsxRuntime.jsx(
3833
+ label && /* @__PURE__ */ jsxRuntime.jsx(react.EdgeLabelRenderer, { children: /* @__PURE__ */ jsxRuntime.jsx(
3644
3834
  "div",
3645
3835
  {
3646
3836
  className: "fc-flow-edge-label",
@@ -3653,7 +3843,7 @@ function ConditionEdgeInner({
3653
3843
  ) })
3654
3844
  ] });
3655
3845
  }
3656
- var ConditionEdge = react.memo(ConditionEdgeInner);
3846
+ var ConditionEdge = React.memo(ConditionEdgeInner);
3657
3847
  function PipelineEdgeInner({
3658
3848
  id,
3659
3849
  sourceX,
@@ -3664,7 +3854,7 @@ function PipelineEdgeInner({
3664
3854
  targetPosition,
3665
3855
  markerEnd
3666
3856
  }) {
3667
- const [edgePath] = react$1.getBezierPath({
3857
+ const [edgePath] = react.getBezierPath({
3668
3858
  sourceX,
3669
3859
  sourceY,
3670
3860
  sourcePosition,
@@ -3673,7 +3863,7 @@ function PipelineEdgeInner({
3673
3863
  targetPosition
3674
3864
  });
3675
3865
  return /* @__PURE__ */ jsxRuntime.jsx(
3676
- react$1.BaseEdge,
3866
+ react.BaseEdge,
3677
3867
  {
3678
3868
  id,
3679
3869
  path: edgePath,
@@ -3686,7 +3876,7 @@ function PipelineEdgeInner({
3686
3876
  }
3687
3877
  );
3688
3878
  }
3689
- var PipelineEdge = react.memo(PipelineEdgeInner);
3879
+ var PipelineEdge = React.memo(PipelineEdgeInner);
3690
3880
  var logicFlowEdgeTypes = {
3691
3881
  conditionEdge: ConditionEdge,
3692
3882
  pipelineEdge: PipelineEdge
@@ -3724,30 +3914,30 @@ function removeConditionForSource(showIf, sourceFieldId) {
3724
3914
  }
3725
3915
  var defaultEdgeOptions = {
3726
3916
  markerEnd: {
3727
- type: react$1.MarkerType.ArrowClosed,
3917
+ type: react.MarkerType.ArrowClosed,
3728
3918
  width: 16,
3729
3919
  height: 12
3730
3920
  }
3731
3921
  };
3732
3922
  function LogicFlowEditor({ schema, onChange }) {
3733
3923
  const noSections = schema.sections.length === 0;
3734
- const flowGraph = react.useMemo(() => buildReactFlowGraph(schema), [schema]);
3735
- const [nodes, setNodes, onNodesChange] = react$1.useNodesState(flowGraph.nodes);
3736
- const [edges, setEdges, onEdgesChange] = react$1.useEdgesState(flowGraph.edges);
3737
- const [selectedFieldId, setSelectedFieldId] = react.useState(null);
3924
+ const flowGraph = React.useMemo(() => buildReactFlowGraph(schema), [schema]);
3925
+ const [nodes, setNodes, onNodesChange] = react.useNodesState(flowGraph.nodes);
3926
+ const [edges, setEdges, onEdgesChange] = react.useEdgesState(flowGraph.edges);
3927
+ const [selectedFieldId, setSelectedFieldId] = React.useState(null);
3738
3928
  const selectedQuestion = selectedFieldId ? findQuestion2(schema, selectedFieldId) : void 0;
3739
- react.useEffect(() => {
3929
+ React.useEffect(() => {
3740
3930
  setNodes(flowGraph.nodes);
3741
3931
  setEdges(flowGraph.edges);
3742
3932
  }, [flowGraph, setNodes, setEdges]);
3743
- const sectionIds = react.useMemo(() => {
3933
+ const sectionIds = React.useMemo(() => {
3744
3934
  const ids = [];
3745
3935
  for (const section of schema.sections) {
3746
3936
  ids.push(section.id);
3747
3937
  }
3748
3938
  return ids;
3749
3939
  }, [schema]);
3750
- const onNodeClick = react.useCallback(
3940
+ const onNodeClick = React.useCallback(
3751
3941
  (_event, node) => {
3752
3942
  if (node.type === "fieldNode") {
3753
3943
  setSelectedFieldId(node.id);
@@ -3755,7 +3945,7 @@ function LogicFlowEditor({ schema, onChange }) {
3755
3945
  },
3756
3946
  []
3757
3947
  );
3758
- const onConnect = react.useCallback(
3948
+ const onConnect = React.useCallback(
3759
3949
  (connection) => {
3760
3950
  if (!connection.source || !connection.target) return;
3761
3951
  const targetQuestion = findQuestion2(schema, connection.target);
@@ -3782,7 +3972,7 @@ function LogicFlowEditor({ schema, onChange }) {
3782
3972
  },
3783
3973
  [schema, onChange]
3784
3974
  );
3785
- const onEdgesDelete = react.useCallback(
3975
+ const onEdgesDelete = React.useCallback(
3786
3976
  (deletedEdges) => {
3787
3977
  let updatedSchema = schema;
3788
3978
  for (const edge of deletedEdges) {
@@ -3807,7 +3997,7 @@ function LogicFlowEditor({ schema, onChange }) {
3807
3997
  },
3808
3998
  [schema, onChange]
3809
3999
  );
3810
- const handleConditionUpdate = react.useCallback(
4000
+ const handleConditionUpdate = React.useCallback(
3811
4001
  (updates) => {
3812
4002
  if (!selectedFieldId) return;
3813
4003
  const updatedSchema = updateQuestionInSchema(schema, selectedFieldId, updates);
@@ -3821,18 +4011,18 @@ function LogicFlowEditor({ schema, onChange }) {
3821
4011
  const jumpCount = flowGraph.edges.filter(
3822
4012
  (e) => e.data?.edgeType === "onExit"
3823
4013
  ).length;
3824
- const totalFields = react.useMemo(
4014
+ const totalFields = React.useMemo(
3825
4015
  () => schema.sections.reduce((sum, s) => sum + s.questions.length, 0),
3826
4016
  [schema]
3827
4017
  );
3828
- const conditionalFields = react.useMemo(
4018
+ const conditionalFields = React.useMemo(
3829
4019
  () => schema.sections.reduce(
3830
4020
  (sum, s) => sum + s.questions.filter((q) => !!q.showIf).length,
3831
4021
  0
3832
4022
  ),
3833
4023
  [schema]
3834
4024
  );
3835
- return /* @__PURE__ */ jsxRuntime.jsx(react$1.ReactFlowProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
4025
+ return /* @__PURE__ */ jsxRuntime.jsx(react.ReactFlowProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
3836
4026
  LogicFlowInner,
3837
4027
  {
3838
4028
  noSections,
@@ -3876,7 +4066,7 @@ function LogicFlowInner({
3876
4066
  totalFields,
3877
4067
  conditionalFields
3878
4068
  }) {
3879
- const { zoomIn, zoomOut, fitView } = react$1.useReactFlow();
4069
+ const { zoomIn, zoomOut, fitView } = react.useReactFlow();
3880
4070
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col bg-background min-h-0", children: [
3881
4071
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 h-9 flex items-center justify-between px-4 border-b border-border bg-card/50", children: [
3882
4072
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
@@ -3904,7 +4094,7 @@ function LogicFlowInner({
3904
4094
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs max-w-xs mx-auto", children: "Switch to Design mode and add sections with fields. Then come back here to visualize and edit branching logic." })
3905
4095
  ] }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex min-h-0", children: [
3906
4096
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntime.jsxs(
3907
- react$1.ReactFlow,
4097
+ react.ReactFlow,
3908
4098
  {
3909
4099
  nodes,
3910
4100
  edges,
@@ -3921,9 +4111,9 @@ function LogicFlowInner({
3921
4111
  deleteKeyCode: ["Backspace", "Delete"],
3922
4112
  proOptions: { hideAttribution: true },
3923
4113
  children: [
3924
- /* @__PURE__ */ jsxRuntime.jsx(react$1.Background, { gap: 20, size: 1 }),
4114
+ /* @__PURE__ */ jsxRuntime.jsx(react.Background, { gap: 20, size: 1 }),
3925
4115
  /* @__PURE__ */ jsxRuntime.jsx(
3926
- react$1.MiniMap,
4116
+ react.MiniMap,
3927
4117
  {
3928
4118
  nodeColor: (node) => {
3929
4119
  const d = node.data;
@@ -3987,15 +4177,15 @@ function LogicFlowInner({
3987
4177
  ] });
3988
4178
  }
3989
4179
  function TemplateGallery({ templates, onSelect, onClose }) {
3990
- const [search, setSearch] = react.useState("");
3991
- const [activeCategory, setActiveCategory] = react.useState("all");
3992
- const [confirmTemplate, setConfirmTemplate] = react.useState(null);
3993
- const categories = react.useMemo(() => {
4180
+ const [search, setSearch] = React.useState("");
4181
+ const [activeCategory, setActiveCategory] = React.useState("all");
4182
+ const [confirmTemplate, setConfirmTemplate] = React.useState(null);
4183
+ const categories = React.useMemo(() => {
3994
4184
  const cats = /* @__PURE__ */ new Set();
3995
4185
  for (const t of templates) cats.add(t.meta.category);
3996
4186
  return ["all", ...Array.from(cats)];
3997
4187
  }, [templates]);
3998
- const filtered = react.useMemo(() => {
4188
+ const filtered = React.useMemo(() => {
3999
4189
  return templates.filter((t) => {
4000
4190
  const matchesCategory = activeCategory === "all" || t.meta.category === activeCategory;
4001
4191
  const matchesSearch = !search || t.meta.name.toLowerCase().includes(search.toLowerCase()) || t.meta.description.toLowerCase().includes(search.toLowerCase()) || t.meta.tags?.some((tag) => tag.toLowerCase().includes(search.toLowerCase()));
@@ -4091,9 +4281,9 @@ function TemplateGallery({ templates, onSelect, onClose }) {
4091
4281
  ] }) });
4092
4282
  }
4093
4283
  function useDebouncedValidation(delayMs = 500) {
4094
- const [errors, setErrors] = react.useState([]);
4095
- const timerRef = react.useRef(null);
4096
- const validate = react.useCallback(
4284
+ const [errors, setErrors] = React.useState([]);
4285
+ const timerRef = React.useRef(null);
4286
+ const validate = React.useCallback(
4097
4287
  (text) => {
4098
4288
  if (timerRef.current) {
4099
4289
  clearTimeout(timerRef.current);
@@ -4142,9 +4332,9 @@ function useDebouncedValidation(delayMs = 500) {
4142
4332
  );
4143
4333
  return { errors, validate };
4144
4334
  }
4145
- var ThemeCtx = react.createContext({});
4335
+ var ThemeCtx = React.createContext({});
4146
4336
  function useBuilderTheme() {
4147
- return react.useContext(ThemeCtx);
4337
+ return React.useContext(ThemeCtx);
4148
4338
  }
4149
4339
  function themeToCssVars(theme) {
4150
4340
  const vars = {};
@@ -4180,10 +4370,10 @@ function themeToCssVars(theme) {
4180
4370
  }
4181
4371
  function FormBuilderThemeProvider({ theme, children }) {
4182
4372
  const resolved = theme ?? {};
4183
- const cssVars = react.useMemo(() => themeToCssVars(resolved), [resolved]);
4373
+ const cssVars = React.useMemo(() => themeToCssVars(resolved), [resolved]);
4184
4374
  return /* @__PURE__ */ jsxRuntime.jsx(ThemeCtx.Provider, { value: resolved, children: /* @__PURE__ */ jsxRuntime.jsx("div", { "data-fcb-root": "", style: cssVars, className: "w-full h-full", children }) });
4185
4375
  }
4186
- var FormBuilderErrorBoundary = class extends react.Component {
4376
+ var FormBuilderErrorBoundary = class extends React.Component {
4187
4377
  constructor(props) {
4188
4378
  super(props);
4189
4379
  this.state = { hasError: false, error: null };
@@ -4215,30 +4405,30 @@ var FormBuilderErrorBoundary = class extends react.Component {
4215
4405
  };
4216
4406
  function FormBuilderCore(props) {
4217
4407
  const { initialSchema = DEFAULT_SCHEMA, onChange, onSave, height = "100vh", theme, className, toolbarExtra, questionTypes, palette, preview, templates, schemaUrl } = props;
4218
- const [viewMode, setViewMode] = react.useState("design");
4219
- const [jsonText, setJsonText] = react.useState("");
4220
- const [jsonSwitchError, setJsonSwitchError] = react.useState(null);
4221
- const [showTemplateGallery, setShowTemplateGallery] = react.useState(false);
4222
- const [saveValidationErrors, setSaveValidationErrors] = react.useState(null);
4223
- const [schemaUrlLoading, setSchemaUrlLoading] = react.useState(!!schemaUrl);
4224
- const [schemaUrlError, setSchemaUrlError] = react.useState(null);
4408
+ const [viewMode, setViewMode] = React.useState("design");
4409
+ const [jsonText, setJsonText] = React.useState("");
4410
+ const [jsonSwitchError, setJsonSwitchError] = React.useState(null);
4411
+ const [showTemplateGallery, setShowTemplateGallery] = React.useState(false);
4412
+ const [saveValidationErrors, setSaveValidationErrors] = React.useState(null);
4413
+ const [schemaUrlLoading, setSchemaUrlLoading] = React.useState(!!schemaUrl);
4414
+ const [schemaUrlError, setSchemaUrlError] = React.useState(null);
4225
4415
  const { errors: jsonErrors, validate: validateJson } = useDebouncedValidation(400);
4226
4416
  const mergedQuestionTypes = questionTypes ? { ...QUESTION_TYPE_INFO, ...questionTypes } : QUESTION_TYPE_INFO;
4227
4417
  const builderState = useBuilderState(initialSchema);
4228
4418
  const dragDrop = useDragDrop(builderState);
4229
- const fileInputRef = react.useRef(null);
4230
- const [mobilePanel, setMobilePanel] = react.useState("none");
4231
- react.useEffect(() => {
4419
+ const fileInputRef = React.useRef(null);
4420
+ const [mobilePanel, setMobilePanel] = React.useState("none");
4421
+ React.useEffect(() => {
4232
4422
  if (builderState.selectedItem && window.innerWidth < 768) {
4233
4423
  setMobilePanel("properties");
4234
4424
  }
4235
4425
  }, [builderState.selectedItem]);
4236
- react.useEffect(() => {
4426
+ React.useEffect(() => {
4237
4427
  if (!dragDrop.activeDragItem && mobilePanel === "palette") {
4238
4428
  setMobilePanel("none");
4239
4429
  }
4240
4430
  }, [dragDrop.activeDragItem]);
4241
- react.useEffect(() => {
4431
+ React.useEffect(() => {
4242
4432
  if (!schemaUrl) return;
4243
4433
  let cancelled = false;
4244
4434
  setSchemaUrlLoading(true);
@@ -4268,12 +4458,12 @@ function FormBuilderCore(props) {
4268
4458
  cancelled = true;
4269
4459
  };
4270
4460
  }, [schemaUrl]);
4271
- react.useEffect(() => {
4461
+ React.useEffect(() => {
4272
4462
  if (onChange && builderState.isDirty) {
4273
4463
  onChange(builderState.schema);
4274
4464
  }
4275
4465
  }, [builderState.schema, builderState.isDirty, onChange]);
4276
- const handleSave = react.useCallback(() => {
4466
+ const handleSave = React.useCallback(() => {
4277
4467
  if (!onSave) return;
4278
4468
  try {
4279
4469
  fieldcraftCore.validateSchema(builderState.schema);
@@ -4288,7 +4478,7 @@ function FormBuilderCore(props) {
4288
4478
  }
4289
4479
  }
4290
4480
  }, [onSave, builderState]);
4291
- const handleExport = react.useCallback(() => {
4481
+ const handleExport = React.useCallback(() => {
4292
4482
  const json = JSON.stringify(builderState.schema, null, 2);
4293
4483
  const blob = new Blob([json], { type: "application/json" });
4294
4484
  const url = URL.createObjectURL(blob);
@@ -4298,10 +4488,10 @@ function FormBuilderCore(props) {
4298
4488
  a.click();
4299
4489
  URL.revokeObjectURL(url);
4300
4490
  }, [builderState.schema]);
4301
- const handleImport = react.useCallback(() => {
4491
+ const handleImport = React.useCallback(() => {
4302
4492
  fileInputRef.current?.click();
4303
4493
  }, []);
4304
- const handleFileChange = react.useCallback(
4494
+ const handleFileChange = React.useCallback(
4305
4495
  (e) => {
4306
4496
  const file = e.target.files?.[0];
4307
4497
  if (!file) return;
@@ -4328,7 +4518,7 @@ ${details}`);
4328
4518
  },
4329
4519
  [builderState]
4330
4520
  );
4331
- const handleViewModeChange = react.useCallback(
4521
+ const handleViewModeChange = React.useCallback(
4332
4522
  (newMode) => {
4333
4523
  setJsonSwitchError(null);
4334
4524
  if (viewMode === "json" && newMode !== "json") {
@@ -4354,7 +4544,7 @@ ${details}`);
4354
4544
  },
4355
4545
  [viewMode, jsonText, builderState]
4356
4546
  );
4357
- const handleKeyDown = react.useCallback(
4547
+ const handleKeyDown = React.useCallback(
4358
4548
  (e) => {
4359
4549
  const mod = e.metaKey || e.ctrlKey;
4360
4550
  const tag = e.target.tagName;