@rachelallyson/hero-hook-form 2.7.0 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
6
6
  });
7
7
 
8
8
  // src/components/Form.tsx
9
- import React18 from "react";
9
+ import React20 from "react";
10
10
  import { Button as Button3 } from "@heroui/react";
11
11
 
12
12
  // src/hooks/useFormHelper.ts
@@ -24,7 +24,9 @@ function useFormHelper({
24
24
  isSubmitting: false,
25
25
  isSuccess: false
26
26
  });
27
- const form = methods ?? useForm({ defaultValues });
27
+ const form = methods ?? useForm({
28
+ ...defaultValues && { defaultValues }
29
+ });
28
30
  const handleSubmit = async () => {
29
31
  setSubmissionState((prev) => ({
30
32
  ...prev,
@@ -64,6 +66,7 @@ function useFormHelper({
64
66
  };
65
67
  return {
66
68
  error: submissionState.error,
69
+ // useForm returns UseFormReturn<T, any, T> which is structurally compatible with UseFormReturn<T>
67
70
  form,
68
71
  handleSubmit,
69
72
  isSubmitted: submissionState.isSubmitted,
@@ -74,8 +77,14 @@ function useFormHelper({
74
77
  };
75
78
  }
76
79
 
80
+ // src/types.ts
81
+ function pathToString(path) {
82
+ if (path === void 0) return "";
83
+ return path;
84
+ }
85
+
77
86
  // src/components/FormField.tsx
78
- import React17 from "react";
87
+ import React19 from "react";
79
88
  import { get, useWatch as useWatch3 } from "react-hook-form";
80
89
 
81
90
  // src/fields/AutocompleteField.tsx
@@ -129,6 +138,7 @@ function AutocompleteField(props) {
129
138
  isDisabled,
130
139
  isInvalid: Boolean(fieldState.error),
131
140
  label,
141
+ name,
132
142
  placeholder,
133
143
  selectedKey: allowsCustomValue ? void 0 : hasSelectedValue ? String(selectedKey) : void 0,
134
144
  inputValue: shouldShowInputValue ? field2.value ?? "" : void 0,
@@ -171,81 +181,93 @@ function HeroHookFormProvider(props) {
171
181
  const value = useMemo(() => props.defaults ?? {}, [props.defaults]);
172
182
  return /* @__PURE__ */ React2.createElement(DefaultsContext.Provider, { value }, props.children);
173
183
  }
184
+ function extractInputCommon(common) {
185
+ const result = {};
186
+ if (common.color !== void 0) {
187
+ const color = common.color;
188
+ result.color = color;
189
+ }
190
+ if (common.size !== void 0) {
191
+ const size = common.size;
192
+ result.size = size;
193
+ }
194
+ if (common.variant !== void 0) {
195
+ const variant = common.variant;
196
+ result.variant = variant;
197
+ }
198
+ if (common.radius !== void 0) {
199
+ const radius = common.radius;
200
+ result.radius = radius;
201
+ }
202
+ if (common.labelPlacement !== void 0) {
203
+ const labelPlacement = common.labelPlacement;
204
+ result.labelPlacement = labelPlacement;
205
+ }
206
+ return result;
207
+ }
208
+ function extractTextareaCommon(common) {
209
+ const result = {};
210
+ if (common.color !== void 0) {
211
+ const color = common.color;
212
+ result.color = color;
213
+ }
214
+ if (common.size !== void 0) {
215
+ const size = common.size;
216
+ result.size = size;
217
+ }
218
+ if (common.variant !== void 0) {
219
+ const variant = common.variant;
220
+ result.variant = variant;
221
+ }
222
+ if (common.radius !== void 0) {
223
+ const radius = common.radius;
224
+ result.radius = radius;
225
+ }
226
+ if (common.labelPlacement !== void 0) {
227
+ const labelPlacement = common.labelPlacement;
228
+ result.labelPlacement = labelPlacement;
229
+ }
230
+ return result;
231
+ }
232
+ function extractSelectCommon(common) {
233
+ const result = {};
234
+ if (common.color !== void 0) {
235
+ const color = common.color;
236
+ result.color = color;
237
+ }
238
+ if (common.size !== void 0) {
239
+ const size = common.size;
240
+ result.size = size;
241
+ }
242
+ if (common.variant !== void 0) {
243
+ const variant = common.variant;
244
+ result.variant = variant;
245
+ }
246
+ if (common.radius !== void 0) {
247
+ const radius = common.radius;
248
+ result.radius = radius;
249
+ }
250
+ if (common.labelPlacement !== void 0) {
251
+ const labelPlacement = common.labelPlacement;
252
+ result.labelPlacement = labelPlacement;
253
+ }
254
+ return result;
255
+ }
174
256
  function useHeroHookFormDefaults() {
175
257
  const cfg = useContext(DefaultsContext) ?? {};
176
258
  const common = cfg.common ?? {};
177
- const commonInput = {
178
- ...common.color !== void 0 ? { color: common.color } : {},
179
- ...common.size !== void 0 ? { size: common.size } : {},
180
- ...common.variant !== void 0 ? { variant: common.variant } : {},
181
- ...common.radius !== void 0 ? { radius: common.radius } : {},
182
- ...common.labelPlacement !== void 0 ? {
183
- labelPlacement: common.labelPlacement
184
- } : {}
185
- };
186
- const commonTextarea = {
187
- ...common.color !== void 0 ? { color: common.color } : {},
188
- ...common.size !== void 0 ? { size: common.size } : {},
189
- ...common.variant !== void 0 ? { variant: common.variant } : {},
190
- ...common.radius !== void 0 ? { radius: common.radius } : {},
191
- ...common.labelPlacement !== void 0 ? {
192
- labelPlacement: common.labelPlacement
193
- } : {}
194
- };
195
- const commonSelect = {
196
- ...common.color !== void 0 ? { color: common.color } : {},
197
- ...common.size !== void 0 ? { size: common.size } : {},
198
- ...common.variant !== void 0 ? { variant: common.variant } : {},
199
- ...common.radius !== void 0 ? { radius: common.radius } : {},
200
- ...common.labelPlacement !== void 0 ? {
201
- labelPlacement: common.labelPlacement
202
- } : {}
203
- };
204
- const commonCheckbox = {
205
- ...common.color !== void 0 ? {
206
- color: common.color
207
- } : {},
208
- ...common.size !== void 0 ? { size: common.size } : {}
209
- };
210
- const commonRadioGroup = {
211
- ...common.color !== void 0 ? {
212
- color: common.color
213
- } : {},
214
- ...common.size !== void 0 ? { size: common.size } : {}
215
- };
216
- const commonDateInput = {
217
- ...common.color !== void 0 ? {
218
- color: common.color
219
- } : {},
220
- ...common.size !== void 0 ? { size: common.size } : {},
221
- ...common.variant !== void 0 ? {
222
- variant: common.variant
223
- } : {},
224
- ...common.radius !== void 0 ? {
225
- radius: common.radius
226
- } : {}
227
- };
228
- const commonSlider = {
229
- ...common.color !== void 0 ? { color: common.color } : {},
230
- ...common.size !== void 0 ? { size: common.size } : {}
231
- };
232
- const commonSwitch = {
233
- ...common.color !== void 0 ? { color: common.color } : {},
234
- ...common.size !== void 0 ? { size: common.size } : {}
235
- };
236
- const commonButton = {
237
- ...common.color !== void 0 ? { color: common.color } : {},
238
- ...common.size !== void 0 ? { size: common.size } : {}
239
- };
259
+ const commonInput = extractInputCommon(common);
260
+ const commonTextarea = extractTextareaCommon(common);
261
+ const commonSelect = extractSelectCommon(common);
240
262
  return {
241
- checkbox: { ...commonCheckbox, ...cfg.checkbox ?? {} },
242
- dateInput: { ...commonDateInput, ...cfg.dateInput ?? {} },
263
+ checkbox: cfg.checkbox ?? {},
264
+ dateInput: cfg.dateInput ?? {},
243
265
  input: { ...commonInput, ...cfg.input ?? {} },
244
- radioGroup: { ...commonRadioGroup, ...cfg.radioGroup ?? {} },
266
+ radioGroup: cfg.radioGroup ?? {},
245
267
  select: { ...commonSelect, ...cfg.select ?? {} },
246
- slider: { ...commonSlider, ...cfg.slider ?? {} },
247
- submitButton: { ...commonButton, ...cfg.submitButton ?? {} },
248
- switch: { ...commonSwitch, ...cfg.switch ?? {} },
268
+ slider: cfg.slider ?? {},
269
+ submitButton: cfg.submitButton ?? {},
270
+ switch: cfg.switch ?? {},
249
271
  textarea: { ...commonTextarea, ...cfg.textarea ?? {} }
250
272
  };
251
273
  }
@@ -263,31 +285,111 @@ function CheckboxField(props) {
263
285
  rules
264
286
  } = props;
265
287
  const defaults = useHeroHookFormDefaults();
288
+ const checkboxValue = checkboxProps?.value ?? "on";
266
289
  return /* @__PURE__ */ React3.createElement(
267
290
  Controller2,
268
291
  {
269
292
  control,
270
293
  name,
271
- render: ({ field: field2, fieldState }) => /* @__PURE__ */ React3.createElement("div", { className }, /* @__PURE__ */ React3.createElement(
272
- Checkbox,
273
- {
274
- ...defaults.checkbox,
275
- ...checkboxProps,
276
- isDisabled,
277
- isInvalid: Boolean(fieldState.error),
278
- isSelected: Boolean(field2.value),
279
- onBlur: field2.onBlur,
280
- onValueChange: (val) => field2.onChange(val)
281
- },
282
- label
283
- ), description ? /* @__PURE__ */ React3.createElement("p", { className: "text-small text-default-400" }, description) : null, fieldState.error?.message ? /* @__PURE__ */ React3.createElement("p", { className: "text-tiny text-danger mt-1" }, fieldState.error.message) : null),
294
+ render: ({ field: field2, fieldState }) => {
295
+ const containerRef = React3.useRef(null);
296
+ React3.useLayoutEffect(() => {
297
+ const setValue = () => {
298
+ if (containerRef.current) {
299
+ const input = containerRef.current.querySelector(
300
+ `input[type="checkbox"][name="${name}"]`
301
+ );
302
+ if (input instanceof HTMLInputElement) {
303
+ input.setAttribute("value", checkboxValue);
304
+ input.value = checkboxValue;
305
+ }
306
+ }
307
+ };
308
+ setValue();
309
+ const timeoutId = setTimeout(setValue, 0);
310
+ return () => clearTimeout(timeoutId);
311
+ }, [name, checkboxValue, field2.value]);
312
+ return /* @__PURE__ */ React3.createElement("div", { ref: containerRef, className }, /* @__PURE__ */ React3.createElement(
313
+ Checkbox,
314
+ {
315
+ ...defaults.checkbox,
316
+ ...checkboxProps,
317
+ isDisabled,
318
+ isInvalid: Boolean(fieldState.error),
319
+ isSelected: Boolean(field2.value),
320
+ name,
321
+ value: checkboxValue,
322
+ onBlur: field2.onBlur,
323
+ onValueChange: (val) => field2.onChange(val)
324
+ },
325
+ label
326
+ ), description ? /* @__PURE__ */ React3.createElement("p", { className: "text-small text-default-400" }, description) : null, fieldState.error?.message ? /* @__PURE__ */ React3.createElement("p", { className: "text-tiny text-danger mt-1" }, fieldState.error.message) : null);
327
+ },
284
328
  rules
285
329
  }
286
330
  );
287
331
  }
288
332
 
289
- // src/fields/ConditionalField.tsx
333
+ // src/fields/CheckboxGroupField.tsx
290
334
  import React4 from "react";
335
+ import { Controller as Controller3 } from "react-hook-form";
336
+ function CheckboxGroupField(props) {
337
+ const {
338
+ checkboxProps,
339
+ className,
340
+ control,
341
+ description,
342
+ isDisabled,
343
+ label,
344
+ name,
345
+ options,
346
+ orientation = "vertical",
347
+ rules
348
+ } = props;
349
+ const defaults = useHeroHookFormDefaults();
350
+ return /* @__PURE__ */ React4.createElement(
351
+ Controller3,
352
+ {
353
+ control,
354
+ name,
355
+ render: ({ field: field2, fieldState }) => {
356
+ const currentValues = field2.value || [];
357
+ const handleCheckboxChange = (optionValue, checked) => {
358
+ if (checked) {
359
+ if (!currentValues.includes(optionValue)) {
360
+ field2.onChange([...currentValues, optionValue]);
361
+ }
362
+ } else {
363
+ field2.onChange(currentValues.filter((val) => val !== optionValue));
364
+ }
365
+ };
366
+ const containerClass = orientation === "horizontal" ? "flex flex-row gap-4 flex-wrap" : "flex flex-col gap-2";
367
+ return /* @__PURE__ */ React4.createElement("div", { className }, label && /* @__PURE__ */ React4.createElement("label", { className: "text-sm font-medium text-foreground block mb-2" }, label), description && /* @__PURE__ */ React4.createElement("p", { className: "text-sm text-default-500 mb-2" }, description), /* @__PURE__ */ React4.createElement("div", { className: containerClass }, options.map((option) => {
368
+ const isSelected = currentValues.includes(option.value);
369
+ return /* @__PURE__ */ React4.createElement(
370
+ Checkbox,
371
+ {
372
+ key: String(option.value),
373
+ ...defaults.checkbox,
374
+ ...checkboxProps,
375
+ isDisabled: isDisabled || option.disabled,
376
+ isInvalid: Boolean(fieldState.error),
377
+ isSelected,
378
+ name,
379
+ onBlur: field2.onBlur,
380
+ onValueChange: (checked) => handleCheckboxChange(option.value, checked)
381
+ },
382
+ option.label
383
+ );
384
+ })), fieldState.error?.message ? /* @__PURE__ */ React4.createElement("p", { className: "text-tiny text-danger mt-1" }, fieldState.error.message) : null);
385
+ },
386
+ rules
387
+ }
388
+ );
389
+ }
390
+
391
+ // src/fields/ConditionalField.tsx
392
+ import React5 from "react";
291
393
  import { useWatch, useFormContext } from "react-hook-form";
292
394
  function ConditionalField({
293
395
  className,
@@ -301,7 +403,7 @@ function ConditionalField({
301
403
  if (!shouldShow) {
302
404
  return null;
303
405
  }
304
- return /* @__PURE__ */ React4.createElement("div", { className }, /* @__PURE__ */ React4.createElement(
406
+ return /* @__PURE__ */ React5.createElement("div", { className }, /* @__PURE__ */ React5.createElement(
305
407
  FormField,
306
408
  {
307
409
  config: field2,
@@ -317,29 +419,29 @@ function ConditionalField({
317
419
  }
318
420
 
319
421
  // src/fields/ContentField.tsx
320
- import React5 from "react";
422
+ import React6 from "react";
321
423
  function ContentField({
322
424
  config,
323
425
  form,
324
426
  submissionState
325
427
  }) {
326
428
  if (config.render) {
327
- return /* @__PURE__ */ React5.createElement("div", { className: config.className }, config.render({
429
+ return /* @__PURE__ */ React6.createElement("div", { className: config.className }, config.render({
328
430
  errors: form.formState.errors,
329
431
  form,
330
432
  isSubmitting: submissionState.isSubmitting
331
433
  }));
332
434
  }
333
- return /* @__PURE__ */ React5.createElement("div", { className: config.className }, config.title && /* @__PURE__ */ React5.createElement("h3", { className: "text-lg font-semibold text-foreground mb-2" }, config.title), config.description && /* @__PURE__ */ React5.createElement("p", { className: "text-sm text-muted-foreground" }, config.description));
435
+ return /* @__PURE__ */ React6.createElement("div", { className: config.className }, config.title && /* @__PURE__ */ React6.createElement("h3", { className: "text-lg font-semibold text-foreground mb-2" }, config.title), config.description && /* @__PURE__ */ React6.createElement("p", { className: "text-sm text-muted-foreground" }, config.description));
334
436
  }
335
437
 
336
438
  // src/fields/DateField.tsx
337
- import React6 from "react";
338
- import { Controller as Controller3 } from "react-hook-form";
439
+ import React7 from "react";
440
+ import { Controller as Controller4 } from "react-hook-form";
339
441
  function CoercedDateInput(props) {
340
442
  const { dateProps, description, disabled, errorMessage, field: field2, label } = props;
341
443
  const defaults = useHeroHookFormDefaults();
342
- return /* @__PURE__ */ React6.createElement(
444
+ return /* @__PURE__ */ React7.createElement(
343
445
  DateInput,
344
446
  {
345
447
  ...defaults.dateInput,
@@ -349,6 +451,7 @@ function CoercedDateInput(props) {
349
451
  isDisabled: disabled,
350
452
  isInvalid: Boolean(errorMessage),
351
453
  label,
454
+ name: field2.name,
352
455
  value: field2.value ?? null,
353
456
  onBlur: field2.onBlur,
354
457
  onChange: field2.onChange
@@ -367,12 +470,12 @@ function DateField(props) {
367
470
  rules,
368
471
  transform
369
472
  } = props;
370
- return /* @__PURE__ */ React6.createElement(
371
- Controller3,
473
+ return /* @__PURE__ */ React7.createElement(
474
+ Controller4,
372
475
  {
373
476
  control,
374
477
  name,
375
- render: ({ field: field2, fieldState }) => /* @__PURE__ */ React6.createElement("div", { className }, /* @__PURE__ */ React6.createElement(
478
+ render: ({ field: field2, fieldState }) => /* @__PURE__ */ React7.createElement("div", { className }, /* @__PURE__ */ React7.createElement(
376
479
  CoercedDateInput,
377
480
  {
378
481
  dateProps,
@@ -392,7 +495,7 @@ function DateField(props) {
392
495
  }
393
496
 
394
497
  // src/fields/DynamicSectionField.tsx
395
- import React7 from "react";
498
+ import React8 from "react";
396
499
  import { useWatch as useWatch2, useFormContext as useFormContext2 } from "react-hook-form";
397
500
  function DynamicSectionField({
398
501
  className,
@@ -406,7 +509,7 @@ function DynamicSectionField({
406
509
  if (!shouldShow) {
407
510
  return null;
408
511
  }
409
- return /* @__PURE__ */ React7.createElement("div", { className }, (title || description) && /* @__PURE__ */ React7.createElement("div", { className: "mb-6" }, title && /* @__PURE__ */ React7.createElement("h3", { className: "text-lg font-semibold text-gray-900 mb-2" }, title), description && /* @__PURE__ */ React7.createElement("p", { className: "text-sm text-gray-600" }, description)), /* @__PURE__ */ React7.createElement("div", { className: "space-y-4" }, fields.map((fieldConfig, index) => /* @__PURE__ */ React7.createElement(
512
+ return /* @__PURE__ */ React8.createElement("div", { className }, (title || description) && /* @__PURE__ */ React8.createElement("div", { className: "mb-6" }, title && /* @__PURE__ */ React8.createElement("h3", { className: "text-lg font-semibold text-gray-900 mb-2" }, title), description && /* @__PURE__ */ React8.createElement("p", { className: "text-sm text-gray-600" }, description)), /* @__PURE__ */ React8.createElement("div", { className: "space-y-4" }, fields.map((fieldConfig, index) => /* @__PURE__ */ React8.createElement(
410
513
  FormField,
411
514
  {
412
515
  key: `${fieldConfig.name}-${index}`,
@@ -423,7 +526,7 @@ function DynamicSectionField({
423
526
  }
424
527
 
425
528
  // src/fields/FieldArrayField.tsx
426
- import React8 from "react";
529
+ import React9 from "react";
427
530
  import { useFieldArray, useFormContext as useFormContext3 } from "react-hook-form";
428
531
  import { Button as Button2 } from "@heroui/react";
429
532
  function FieldArrayField({
@@ -451,27 +554,60 @@ function FieldArrayField({
451
554
  const { append, fields, move, remove } = useFieldArray({
452
555
  control,
453
556
  name
454
- // FieldArray name
455
557
  });
456
558
  const canAdd = fields.length < max;
457
559
  const canRemove = fields.length > min;
560
+ const getFieldPath = (fieldName, itemIndex) => {
561
+ return `${String(name)}.${itemIndex}.${fieldName}`;
562
+ };
563
+ const processFieldConfig = (fieldConfig, itemIndex) => {
564
+ const fieldName = String(fieldConfig.name);
565
+ const fullPath = getFieldPath(fieldName, itemIndex);
566
+ if ("dependsOn" in fieldConfig && fieldConfig.dependsOn && typeof fieldConfig.dependsOn === "string") {
567
+ const dependsOnPath = fieldConfig.dependsOn;
568
+ const arrayNamePrefix = `${String(name)}.`;
569
+ if (!dependsOnPath.startsWith(arrayNamePrefix)) {
570
+ const nestedDependsOn = getFieldPath(dependsOnPath, itemIndex);
571
+ return {
572
+ ...fieldConfig,
573
+ dependsOn: nestedDependsOn,
574
+ name: fullPath,
575
+ ..."dependsOnValue" in fieldConfig && {
576
+ dependsOnValue: fieldConfig.dependsOnValue
577
+ }
578
+ };
579
+ }
580
+ }
581
+ return {
582
+ ...fieldConfig,
583
+ name: fullPath
584
+ };
585
+ };
586
+ const renderField = (fieldConfig, itemIndex) => {
587
+ const processedConfig = processFieldConfig(fieldConfig, itemIndex);
588
+ return /* @__PURE__ */ React9.createElement(
589
+ FormField,
590
+ {
591
+ key: `${fieldConfig.name}-${itemIndex}`,
592
+ config: processedConfig,
593
+ form,
594
+ submissionState: {
595
+ error: void 0,
596
+ isSubmitted: false,
597
+ isSubmitting: false,
598
+ isSuccess: false
599
+ }
600
+ }
601
+ );
602
+ };
458
603
  const handleAdd = () => {
459
604
  if (canAdd) {
460
605
  if (defaultItem) {
461
606
  append(defaultItem());
462
607
  } else {
463
- const defaultValues = fieldConfigs.reduce((acc, fieldConfig) => {
464
- const fieldName = fieldConfig.name;
465
- if (fieldConfig.type === "checkbox" || fieldConfig.type === "switch") {
466
- acc[fieldName] = false;
467
- } else if (fieldConfig.type === "slider") {
468
- acc[fieldName] = 0;
469
- } else {
470
- acc[fieldName] = "";
471
- }
472
- return acc;
473
- }, {});
474
- append(defaultValues);
608
+ console.warn(
609
+ `FieldArrayField: defaultItem is required for field array "${String(name)}". Please provide a defaultItem function that returns the default item structure.`
610
+ );
475
611
  }
476
612
  }
477
613
  };
@@ -495,44 +631,15 @@ function FieldArrayField({
495
631
  const canMoveUp = enableReordering && index > 0;
496
632
  const canMoveDown = enableReordering && index < fields.length - 1;
497
633
  const itemCanRemove = canRemove;
498
- const fieldElements = fieldConfigs.map((fieldConfig) => {
499
- const fieldName = fieldConfig.name;
500
- const fullPath = `${name}.${index}.${fieldName}`;
501
- let processedConfig = { ...fieldConfig, name: fullPath };
502
- if ("dependsOn" in fieldConfig && fieldConfig.dependsOn && typeof fieldConfig.dependsOn === "string") {
503
- const dependsOnPath = fieldConfig.dependsOn;
504
- if (!dependsOnPath.startsWith(`${name}.`)) {
505
- processedConfig = {
506
- ...processedConfig,
507
- dependsOn: `${name}.${index}.${dependsOnPath}`,
508
- // Preserve dependsOnValue if it exists
509
- ..."dependsOnValue" in fieldConfig && {
510
- dependsOnValue: fieldConfig.dependsOnValue
511
- }
512
- };
513
- }
514
- }
515
- return /* @__PURE__ */ React8.createElement(
516
- FormField,
517
- {
518
- key: `${fieldConfig.name}-${index}`,
519
- config: processedConfig,
520
- form,
521
- submissionState: {
522
- error: void 0,
523
- isSubmitted: false,
524
- isSubmitting: false,
525
- isSuccess: false
526
- }
527
- }
528
- );
529
- });
634
+ const fieldElements = fieldConfigs.map(
635
+ (fieldConfig) => renderField(fieldConfig, index)
636
+ );
530
637
  if (renderItem) {
531
- return /* @__PURE__ */ React8.createElement(React8.Fragment, { key: field2.id }, renderItem({
638
+ return /* @__PURE__ */ React9.createElement(React9.Fragment, { key: field2.id }, renderItem({
532
639
  canMoveDown,
533
640
  canMoveUp,
534
641
  canRemove: itemCanRemove,
535
- children: /* @__PURE__ */ React8.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, fieldElements),
642
+ children: /* @__PURE__ */ React9.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, fieldElements),
536
643
  field: field2,
537
644
  fields,
538
645
  index,
@@ -541,13 +648,13 @@ function FieldArrayField({
541
648
  onRemove: () => handleRemove(index)
542
649
  }));
543
650
  }
544
- return /* @__PURE__ */ React8.createElement(
651
+ return /* @__PURE__ */ React9.createElement(
545
652
  "div",
546
653
  {
547
654
  key: field2.id,
548
655
  className: "border border-gray-200 rounded-lg p-4 space-y-4"
549
656
  },
550
- /* @__PURE__ */ React8.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React8.createElement("h4", { className: "text-sm font-medium text-gray-700" }, config.label, " #", index + 1), /* @__PURE__ */ React8.createElement("div", { className: "flex gap-2" }, enableReordering && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(
657
+ /* @__PURE__ */ React9.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React9.createElement("h4", { className: "text-sm font-medium text-gray-700" }, config.label, " #", index + 1), /* @__PURE__ */ React9.createElement("div", { className: "flex gap-2" }, enableReordering && /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
551
658
  Button2,
552
659
  {
553
660
  size: "sm",
@@ -557,7 +664,7 @@ function FieldArrayField({
557
664
  "aria-label": `Move ${config.label} ${index + 1} up`
558
665
  },
559
666
  reorderButtonText.up
560
- ), /* @__PURE__ */ React8.createElement(
667
+ ), /* @__PURE__ */ React9.createElement(
561
668
  Button2,
562
669
  {
563
670
  size: "sm",
@@ -567,7 +674,7 @@ function FieldArrayField({
567
674
  "aria-label": `Move ${config.label} ${index + 1} down`
568
675
  },
569
676
  reorderButtonText.down
570
- )), itemCanRemove && /* @__PURE__ */ React8.createElement(
677
+ )), itemCanRemove && /* @__PURE__ */ React9.createElement(
571
678
  Button2,
572
679
  {
573
680
  size: "sm",
@@ -579,7 +686,7 @@ function FieldArrayField({
579
686
  },
580
687
  removeButtonText
581
688
  ))),
582
- /* @__PURE__ */ React8.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, fieldElements)
689
+ /* @__PURE__ */ React9.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, fieldElements)
583
690
  );
584
691
  });
585
692
  };
@@ -593,7 +700,7 @@ function FieldArrayField({
593
700
  if (!canAdd) {
594
701
  return null;
595
702
  }
596
- return /* @__PURE__ */ React8.createElement(
703
+ return /* @__PURE__ */ React9.createElement(
597
704
  Button2,
598
705
  {
599
706
  variant: "bordered",
@@ -604,12 +711,12 @@ function FieldArrayField({
604
711
  addButtonText
605
712
  );
606
713
  };
607
- return /* @__PURE__ */ React8.createElement("div", { className }, /* @__PURE__ */ React8.createElement("div", { className: "space-y-4" }, fields.length > 0 ? renderFieldArrayItems() : /* @__PURE__ */ React8.createElement("div", { className: "text-center py-8 text-gray-500" }, /* @__PURE__ */ React8.createElement("p", null, "No ", config.label?.toLowerCase(), " added yet."), renderAddButtonElement()), fields.length > 0 && renderAddButtonElement()));
714
+ return /* @__PURE__ */ React9.createElement("div", { className }, /* @__PURE__ */ React9.createElement("div", { className: "space-y-4" }, fields.length > 0 ? renderFieldArrayItems() : /* @__PURE__ */ React9.createElement("div", { className: "text-center py-8 text-gray-500" }, /* @__PURE__ */ React9.createElement("p", null, "No ", config.label?.toLowerCase(), " added yet."), renderAddButtonElement()), fields.length > 0 && renderAddButtonElement()));
608
715
  }
609
716
 
610
717
  // src/fields/FileField.tsx
611
- import React9 from "react";
612
- import { Controller as Controller4 } from "react-hook-form";
718
+ import React10 from "react";
719
+ import { Controller as Controller5 } from "react-hook-form";
613
720
  function CoercedFileInput(props) {
614
721
  const {
615
722
  accept,
@@ -622,7 +729,7 @@ function CoercedFileInput(props) {
622
729
  multiple
623
730
  } = props;
624
731
  const defaults = useHeroHookFormDefaults();
625
- return /* @__PURE__ */ React9.createElement(
732
+ return /* @__PURE__ */ React10.createElement(
626
733
  Input,
627
734
  {
628
735
  ...defaults.input,
@@ -634,10 +741,14 @@ function CoercedFileInput(props) {
634
741
  isInvalid: Boolean(errorMessage),
635
742
  label,
636
743
  multiple,
744
+ name: field2.name,
637
745
  type: "file",
638
746
  value: field2.value ? "" : "",
639
747
  onBlur: field2.onBlur,
640
748
  onChange: (e) => {
749
+ if (!(e.target instanceof HTMLInputElement)) {
750
+ return;
751
+ }
641
752
  const target = e.target;
642
753
  field2.onChange(target.files);
643
754
  }
@@ -658,12 +769,12 @@ function FileField(props) {
658
769
  rules,
659
770
  transform
660
771
  } = props;
661
- return /* @__PURE__ */ React9.createElement(
662
- Controller4,
772
+ return /* @__PURE__ */ React10.createElement(
773
+ Controller5,
663
774
  {
664
775
  control,
665
776
  name,
666
- render: ({ field: field2, fieldState }) => /* @__PURE__ */ React9.createElement("div", { className }, /* @__PURE__ */ React9.createElement(
777
+ render: ({ field: field2, fieldState }) => /* @__PURE__ */ React10.createElement("div", { className }, /* @__PURE__ */ React10.createElement(
667
778
  CoercedFileInput,
668
779
  {
669
780
  accept,
@@ -685,8 +796,8 @@ function FileField(props) {
685
796
  }
686
797
 
687
798
  // src/fields/FontPickerField.tsx
688
- import React10 from "react";
689
- import { Controller as Controller5 } from "react-hook-form";
799
+ import React11 from "react";
800
+ import { Controller as Controller6 } from "react-hook-form";
690
801
  var FontPickerComponent = null;
691
802
  var fontPickerLoaded = false;
692
803
  var fontPickerLoading = false;
@@ -702,12 +813,12 @@ function FontPickerField(props) {
702
813
  name,
703
814
  rules
704
815
  } = props;
705
- const [fontPickerState, setFontPickerState] = React10.useState({
816
+ const [fontPickerState, setFontPickerState] = React11.useState({
706
817
  component: FontPickerComponent,
707
818
  error: null,
708
819
  loading: false
709
820
  });
710
- React10.useEffect(() => {
821
+ React11.useEffect(() => {
711
822
  if (fontPickerLoaded && FontPickerComponent) {
712
823
  setFontPickerState({
713
824
  component: FontPickerComponent,
@@ -765,17 +876,17 @@ function FontPickerField(props) {
765
876
  void loadFontPicker();
766
877
  }, []);
767
878
  if (fontPickerState.loading) {
768
- return /* @__PURE__ */ React10.createElement("div", { className }, /* @__PURE__ */ React10.createElement("div", { className: "space-y-2" }, label && /* @__PURE__ */ React10.createElement("label", { className: "block text-sm font-medium text-foreground" }, label), description && /* @__PURE__ */ React10.createElement("p", { className: "text-sm text-muted-foreground" }, description), /* @__PURE__ */ React10.createElement("div", { className: "p-4 border border-default-200 bg-default-50 rounded-medium" }, /* @__PURE__ */ React10.createElement("p", { className: "text-default-600 text-sm" }, "Loading font picker..."))));
879
+ return /* @__PURE__ */ React11.createElement("div", { className }, /* @__PURE__ */ React11.createElement("div", { className: "space-y-2" }, label && /* @__PURE__ */ React11.createElement("label", { className: "block text-sm font-medium text-foreground" }, label), description && /* @__PURE__ */ React11.createElement("p", { className: "text-sm text-muted-foreground" }, description), /* @__PURE__ */ React11.createElement("div", { className: "p-4 border border-default-200 bg-default-50 rounded-medium" }, /* @__PURE__ */ React11.createElement("p", { className: "text-default-600 text-sm" }, "Loading font picker..."))));
769
880
  }
770
881
  if (!fontPickerState.component) {
771
- return /* @__PURE__ */ React10.createElement("div", { className }, /* @__PURE__ */ React10.createElement("div", { className: "space-y-2" }, label && /* @__PURE__ */ React10.createElement("label", { className: "block text-sm font-medium text-foreground" }, label), description && /* @__PURE__ */ React10.createElement("p", { className: "text-sm text-muted-foreground" }, description), /* @__PURE__ */ React10.createElement("div", { className: "p-4 border border-warning-200 bg-warning-50 rounded-medium" }, /* @__PURE__ */ React10.createElement("p", { className: "text-warning-800 text-sm" }, "Font picker requires the @rachelallyson/heroui-font-picker package. Please install it as a peer dependency for advanced font selection features."))));
882
+ return /* @__PURE__ */ React11.createElement("div", { className }, /* @__PURE__ */ React11.createElement("div", { className: "space-y-2" }, label && /* @__PURE__ */ React11.createElement("label", { className: "block text-sm font-medium text-foreground" }, label), description && /* @__PURE__ */ React11.createElement("p", { className: "text-sm text-muted-foreground" }, description), /* @__PURE__ */ React11.createElement("div", { className: "p-4 border border-warning-200 bg-warning-50 rounded-medium" }, /* @__PURE__ */ React11.createElement("p", { className: "text-warning-800 text-sm" }, "Font picker requires the @rachelallyson/heroui-font-picker package. Please install it as a peer dependency for advanced font selection features."))));
772
883
  }
773
- return /* @__PURE__ */ React10.createElement(
774
- Controller5,
884
+ return /* @__PURE__ */ React11.createElement(
885
+ Controller6,
775
886
  {
776
887
  control,
777
888
  name,
778
- render: ({ field: field2, fieldState }) => /* @__PURE__ */ React10.createElement(
889
+ render: ({ field: field2, fieldState }) => /* @__PURE__ */ React11.createElement(
779
890
  fontPickerState.component,
780
891
  {
781
892
  label,
@@ -794,12 +905,12 @@ function FontPickerField(props) {
794
905
  }
795
906
 
796
907
  // src/fields/InputField.tsx
797
- import React11 from "react";
798
- import { Controller as Controller6 } from "react-hook-form";
908
+ import React12 from "react";
909
+ import { Controller as Controller7 } from "react-hook-form";
799
910
  function CoercedInput(props) {
800
911
  const { description, disabled, errorMessage, field: field2, inputProps, label } = props;
801
912
  const defaults = useHeroHookFormDefaults();
802
- return /* @__PURE__ */ React11.createElement(
913
+ return /* @__PURE__ */ React12.createElement(
803
914
  Input,
804
915
  {
805
916
  ...defaults.input,
@@ -809,13 +920,14 @@ function CoercedInput(props) {
809
920
  isDisabled: disabled,
810
921
  isInvalid: Boolean(errorMessage),
811
922
  label,
923
+ name: field2.name,
812
924
  value: field2.value ?? "",
813
925
  onBlur: field2.onBlur,
814
926
  onValueChange: field2.onChange
815
927
  }
816
928
  );
817
929
  }
818
- var InputField = React11.memo(
930
+ var InputField = React12.memo(
819
931
  (props) => {
820
932
  const {
821
933
  className,
@@ -828,12 +940,12 @@ var InputField = React11.memo(
828
940
  rules,
829
941
  transform
830
942
  } = props;
831
- return /* @__PURE__ */ React11.createElement(
832
- Controller6,
943
+ return /* @__PURE__ */ React12.createElement(
944
+ Controller7,
833
945
  {
834
946
  control,
835
947
  name,
836
- render: ({ field: field2, fieldState }) => /* @__PURE__ */ React11.createElement("div", { className }, /* @__PURE__ */ React11.createElement(
948
+ render: ({ field: field2, fieldState }) => /* @__PURE__ */ React12.createElement("div", { className }, /* @__PURE__ */ React12.createElement(
837
949
  CoercedInput,
838
950
  {
839
951
  description,
@@ -863,8 +975,8 @@ var InputField = React11.memo(
863
975
  );
864
976
 
865
977
  // src/fields/RadioGroupField.tsx
866
- import React12 from "react";
867
- import { Controller as Controller7 } from "react-hook-form";
978
+ import React13 from "react";
979
+ import { Controller as Controller8 } from "react-hook-form";
868
980
  function RadioGroupField(props) {
869
981
  const {
870
982
  className,
@@ -878,12 +990,12 @@ function RadioGroupField(props) {
878
990
  rules
879
991
  } = props;
880
992
  const defaults = useHeroHookFormDefaults();
881
- return /* @__PURE__ */ React12.createElement(
882
- Controller7,
993
+ return /* @__PURE__ */ React13.createElement(
994
+ Controller8,
883
995
  {
884
996
  control,
885
997
  name,
886
- render: ({ field: field2, fieldState }) => /* @__PURE__ */ React12.createElement("div", { className }, /* @__PURE__ */ React12.createElement(
998
+ render: ({ field: field2, fieldState }) => /* @__PURE__ */ React13.createElement("div", { className }, /* @__PURE__ */ React13.createElement(
887
999
  RadioGroup,
888
1000
  {
889
1001
  ...defaults.radioGroup,
@@ -892,11 +1004,12 @@ function RadioGroupField(props) {
892
1004
  isDisabled,
893
1005
  isInvalid: Boolean(fieldState.error),
894
1006
  label,
1007
+ name,
895
1008
  value: String(field2.value ?? ""),
896
1009
  onBlur: field2.onBlur,
897
1010
  onValueChange: (val) => field2.onChange(val)
898
1011
  },
899
- options.map((opt) => /* @__PURE__ */ React12.createElement(
1012
+ options.map((opt) => /* @__PURE__ */ React13.createElement(
900
1013
  Radio,
901
1014
  {
902
1015
  key: String(opt.value),
@@ -905,15 +1018,15 @@ function RadioGroupField(props) {
905
1018
  },
906
1019
  opt.label
907
1020
  ))
908
- ), fieldState.error?.message ? /* @__PURE__ */ React12.createElement("p", { className: "text-tiny text-danger mt-1" }, fieldState.error.message) : null),
1021
+ ), fieldState.error?.message ? /* @__PURE__ */ React13.createElement("p", { className: "text-tiny text-danger mt-1" }, fieldState.error.message) : null),
909
1022
  rules
910
1023
  }
911
1024
  );
912
1025
  }
913
1026
 
914
1027
  // src/fields/SelectField.tsx
915
- import React13 from "react";
916
- import { Controller as Controller8 } from "react-hook-form";
1028
+ import React14 from "react";
1029
+ import { Controller as Controller9 } from "react-hook-form";
917
1030
  function SelectField(props) {
918
1031
  const {
919
1032
  className,
@@ -928,14 +1041,14 @@ function SelectField(props) {
928
1041
  selectProps
929
1042
  } = props;
930
1043
  const defaults = useHeroHookFormDefaults();
931
- return /* @__PURE__ */ React13.createElement(
932
- Controller8,
1044
+ return /* @__PURE__ */ React14.createElement(
1045
+ Controller9,
933
1046
  {
934
1047
  control,
935
1048
  name,
936
1049
  render: ({ field: field2, fieldState }) => {
937
1050
  const selectedKey = field2.value;
938
- return /* @__PURE__ */ React13.createElement("div", { className }, /* @__PURE__ */ React13.createElement(
1051
+ return /* @__PURE__ */ React14.createElement("div", { className }, /* @__PURE__ */ React14.createElement(
939
1052
  Select,
940
1053
  {
941
1054
  ...defaults.select,
@@ -945,6 +1058,7 @@ function SelectField(props) {
945
1058
  isDisabled,
946
1059
  isInvalid: Boolean(fieldState.error),
947
1060
  label,
1061
+ name,
948
1062
  placeholder,
949
1063
  selectedKeys: selectedKey != null ? /* @__PURE__ */ new Set([String(selectedKey)]) : /* @__PURE__ */ new Set(),
950
1064
  onSelectionChange: (keys) => {
@@ -953,7 +1067,7 @@ function SelectField(props) {
953
1067
  field2.onChange(next);
954
1068
  }
955
1069
  },
956
- options.map((opt) => /* @__PURE__ */ React13.createElement(
1070
+ options.map((opt) => /* @__PURE__ */ React14.createElement(
957
1071
  SelectItem,
958
1072
  {
959
1073
  key: String(opt.value),
@@ -970,12 +1084,12 @@ function SelectField(props) {
970
1084
  }
971
1085
 
972
1086
  // src/fields/SliderField.tsx
973
- import React14 from "react";
974
- import { Controller as Controller9 } from "react-hook-form";
1087
+ import React15 from "react";
1088
+ import { Controller as Controller10 } from "react-hook-form";
975
1089
  function CoercedSlider(props) {
976
1090
  const { description, disabled, errorMessage, field: field2, label, sliderProps } = props;
977
1091
  const defaults = useHeroHookFormDefaults();
978
- return /* @__PURE__ */ React14.createElement(
1092
+ return /* @__PURE__ */ React15.createElement(
979
1093
  Slider,
980
1094
  {
981
1095
  ...defaults.slider,
@@ -985,6 +1099,7 @@ function CoercedSlider(props) {
985
1099
  isDisabled: disabled,
986
1100
  isInvalid: Boolean(errorMessage),
987
1101
  label,
1102
+ name: field2.name,
988
1103
  value: field2.value ?? 0,
989
1104
  onBlur: field2.onBlur,
990
1105
  onValueChange: field2.onChange
@@ -1003,12 +1118,12 @@ function SliderField(props) {
1003
1118
  sliderProps,
1004
1119
  transform
1005
1120
  } = props;
1006
- return /* @__PURE__ */ React14.createElement(
1007
- Controller9,
1121
+ return /* @__PURE__ */ React15.createElement(
1122
+ Controller10,
1008
1123
  {
1009
1124
  control,
1010
1125
  name,
1011
- render: ({ field: field2, fieldState }) => /* @__PURE__ */ React14.createElement("div", { className }, /* @__PURE__ */ React14.createElement(
1126
+ render: ({ field: field2, fieldState }) => /* @__PURE__ */ React15.createElement("div", { className }, /* @__PURE__ */ React15.createElement(
1012
1127
  CoercedSlider,
1013
1128
  {
1014
1129
  description,
@@ -1027,9 +1142,123 @@ function SliderField(props) {
1027
1142
  );
1028
1143
  }
1029
1144
 
1145
+ // src/fields/StringArrayField.tsx
1146
+ import React16, { useState as useState2 } from "react";
1147
+ import { Controller as Controller11 } from "react-hook-form";
1148
+ function StringArrayInput(props) {
1149
+ const {
1150
+ description,
1151
+ disabled,
1152
+ errorMessage,
1153
+ field: field2,
1154
+ label,
1155
+ stringArrayProps
1156
+ } = props;
1157
+ const [inputValue, setInputValue] = useState2("");
1158
+ const items = field2.value || [];
1159
+ const {
1160
+ addButtonText = "Add",
1161
+ allowDuplicates = false,
1162
+ maxItems,
1163
+ minItems,
1164
+ placeholder = "Add item...",
1165
+ showAddButton = true,
1166
+ transformItem = (item) => item.trim(),
1167
+ validateItem = () => true
1168
+ } = stringArrayProps || {};
1169
+ const canAddMore = !maxItems || items.length < maxItems;
1170
+ const handleAddItem = () => {
1171
+ const trimmedValue = inputValue.trim();
1172
+ if (!trimmedValue) return;
1173
+ const transformedValue = transformItem(trimmedValue);
1174
+ const validation = validateItem(transformedValue);
1175
+ if (validation !== true) return;
1176
+ if (!allowDuplicates && items.includes(transformedValue)) return;
1177
+ const newItems = [...items, transformedValue];
1178
+ field2.onChange(newItems);
1179
+ setInputValue("");
1180
+ };
1181
+ const handleRemoveItem = (indexToRemove) => {
1182
+ const newItems = items.filter((_, index) => index !== indexToRemove);
1183
+ field2.onChange(newItems);
1184
+ };
1185
+ const handleKeyPress = (e) => {
1186
+ if (e.key === "Enter") {
1187
+ e.preventDefault();
1188
+ if (!showAddButton) {
1189
+ handleAddItem();
1190
+ }
1191
+ }
1192
+ };
1193
+ return /* @__PURE__ */ React16.createElement("div", { className: "space-y-2" }, label && /* @__PURE__ */ React16.createElement("label", { className: "block text-sm font-medium text-foreground" }, label, minItems !== void 0 && /* @__PURE__ */ React16.createElement("span", { className: "text-xs text-muted-foreground ml-1" }, "(min ", minItems, ")"), maxItems !== void 0 && /* @__PURE__ */ React16.createElement("span", { className: "text-xs text-muted-foreground ml-1" }, "(max ", maxItems, ")")), description && /* @__PURE__ */ React16.createElement("p", { className: "text-sm text-muted-foreground" }, description), canAddMore && /* @__PURE__ */ React16.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React16.createElement(
1194
+ Input,
1195
+ {
1196
+ className: "flex-1",
1197
+ disabled,
1198
+ placeholder,
1199
+ value: inputValue,
1200
+ onChange: (e) => setInputValue(e.target.value),
1201
+ onKeyPress: handleKeyPress,
1202
+ isInvalid: !!errorMessage,
1203
+ errorMessage
1204
+ }
1205
+ ), showAddButton && /* @__PURE__ */ React16.createElement(
1206
+ Button,
1207
+ {
1208
+ type: "button",
1209
+ variant: "flat",
1210
+ onClick: handleAddItem,
1211
+ disabled: disabled || !inputValue.trim(),
1212
+ size: "sm"
1213
+ },
1214
+ addButtonText
1215
+ )), items.length > 0 && /* @__PURE__ */ React16.createElement("div", { className: "space-y-1" }, items.map((item, index) => /* @__PURE__ */ React16.createElement(
1216
+ "div",
1217
+ {
1218
+ key: index,
1219
+ className: "flex items-center gap-2 p-2 bg-content2 rounded-md"
1220
+ },
1221
+ /* @__PURE__ */ React16.createElement("span", { className: "flex-1 text-sm" }, item),
1222
+ /* @__PURE__ */ React16.createElement(
1223
+ Button,
1224
+ {
1225
+ type: "button",
1226
+ variant: "light",
1227
+ size: "sm",
1228
+ onClick: () => handleRemoveItem(index),
1229
+ disabled,
1230
+ className: "min-w-[60px]"
1231
+ },
1232
+ "Remove"
1233
+ )
1234
+ ))), minItems !== void 0 && items.length < minItems && /* @__PURE__ */ React16.createElement("p", { className: "text-xs text-danger" }, "At least ", minItems, " item", minItems === 1 ? "" : "s", " required"), maxItems !== void 0 && items.length >= maxItems && /* @__PURE__ */ React16.createElement("p", { className: "text-xs text-muted-foreground" }, "Maximum ", maxItems, " item", maxItems === 1 ? "" : "s", " allowed"));
1235
+ }
1236
+ function StringArrayField(props) {
1237
+ const { control, label, name, rules, ...fieldProps } = props;
1238
+ return /* @__PURE__ */ React16.createElement(
1239
+ Controller11,
1240
+ {
1241
+ control,
1242
+ name,
1243
+ rules,
1244
+ render: ({ field: field2, fieldState }) => /* @__PURE__ */ React16.createElement(
1245
+ StringArrayInput,
1246
+ {
1247
+ field: field2,
1248
+ label,
1249
+ description: fieldProps.description,
1250
+ disabled: fieldProps.isDisabled,
1251
+ errorMessage: fieldState.error?.message,
1252
+ stringArrayProps: fieldProps.stringArrayProps
1253
+ }
1254
+ )
1255
+ }
1256
+ );
1257
+ }
1258
+
1030
1259
  // src/fields/SwitchField.tsx
1031
- import React15 from "react";
1032
- import { Controller as Controller10 } from "react-hook-form";
1260
+ import React17 from "react";
1261
+ import { Controller as Controller12 } from "react-hook-form";
1033
1262
  function SwitchField(props) {
1034
1263
  const {
1035
1264
  className,
@@ -1042,31 +1271,32 @@ function SwitchField(props) {
1042
1271
  switchProps
1043
1272
  } = props;
1044
1273
  const defaults = useHeroHookFormDefaults();
1045
- return /* @__PURE__ */ React15.createElement(
1046
- Controller10,
1274
+ return /* @__PURE__ */ React17.createElement(
1275
+ Controller12,
1047
1276
  {
1048
1277
  control,
1049
1278
  name,
1050
- render: ({ field: field2, fieldState }) => /* @__PURE__ */ React15.createElement("div", { className }, /* @__PURE__ */ React15.createElement(
1279
+ render: ({ field: field2, fieldState }) => /* @__PURE__ */ React17.createElement("div", { className }, /* @__PURE__ */ React17.createElement(
1051
1280
  Switch,
1052
1281
  {
1053
1282
  ...defaults.switch,
1054
1283
  ...switchProps,
1055
1284
  isDisabled,
1056
1285
  isSelected: Boolean(field2.value),
1286
+ name,
1057
1287
  onBlur: field2.onBlur,
1058
1288
  onValueChange: (val) => field2.onChange(val)
1059
1289
  },
1060
1290
  label
1061
- ), description ? /* @__PURE__ */ React15.createElement("p", { className: "text-small text-default-400" }, description) : null, fieldState.error?.message ? /* @__PURE__ */ React15.createElement("p", { className: "text-tiny text-danger mt-1" }, fieldState.error.message) : null),
1291
+ ), description ? /* @__PURE__ */ React17.createElement("p", { className: "text-small text-default-400" }, description) : null, fieldState.error?.message ? /* @__PURE__ */ React17.createElement("p", { className: "text-tiny text-danger mt-1" }, fieldState.error.message) : null),
1062
1292
  rules
1063
1293
  }
1064
1294
  );
1065
1295
  }
1066
1296
 
1067
1297
  // src/fields/TextareaField.tsx
1068
- import React16 from "react";
1069
- import { Controller as Controller11 } from "react-hook-form";
1298
+ import React18 from "react";
1299
+ import { Controller as Controller13 } from "react-hook-form";
1070
1300
  function TextareaField(props) {
1071
1301
  const {
1072
1302
  className,
@@ -1079,12 +1309,12 @@ function TextareaField(props) {
1079
1309
  textareaProps
1080
1310
  } = props;
1081
1311
  const defaults = useHeroHookFormDefaults();
1082
- return /* @__PURE__ */ React16.createElement(
1083
- Controller11,
1312
+ return /* @__PURE__ */ React18.createElement(
1313
+ Controller13,
1084
1314
  {
1085
1315
  control,
1086
1316
  name,
1087
- render: ({ field: field2, fieldState }) => /* @__PURE__ */ React16.createElement("div", { className }, /* @__PURE__ */ React16.createElement(
1317
+ render: ({ field: field2, fieldState }) => /* @__PURE__ */ React18.createElement("div", { className }, /* @__PURE__ */ React18.createElement(
1088
1318
  Textarea,
1089
1319
  {
1090
1320
  ...defaults.textarea,
@@ -1094,6 +1324,7 @@ function TextareaField(props) {
1094
1324
  isDisabled,
1095
1325
  isInvalid: Boolean(fieldState.error),
1096
1326
  label,
1327
+ name: field2.name,
1097
1328
  value: field2.value ?? "",
1098
1329
  onBlur: field2.onBlur,
1099
1330
  onValueChange: field2.onChange
@@ -1105,213 +1336,319 @@ function TextareaField(props) {
1105
1336
  }
1106
1337
 
1107
1338
  // src/components/FormField.tsx
1108
- var FormField = React17.memo(
1109
- ({
1110
- config,
1111
- form,
1112
- submissionState
1113
- }) => {
1114
- if (!form || !form.control) {
1115
- return null;
1116
- }
1117
- const { control } = form;
1118
- const watchedValues = useWatch3({ control });
1119
- if (config.type === "content") {
1120
- return /* @__PURE__ */ React17.createElement(
1339
+ function FormFieldComponent({
1340
+ config,
1341
+ form,
1342
+ submissionState
1343
+ }) {
1344
+ if (!form || !form.control) {
1345
+ return null;
1346
+ }
1347
+ const { control } = form;
1348
+ const watchedValues = useWatch3({ control });
1349
+ const fieldConfig = config;
1350
+ if ("type" in fieldConfig && fieldConfig.type === "content") {
1351
+ if ("render" in fieldConfig || "content" in fieldConfig) {
1352
+ return /* @__PURE__ */ React19.createElement(
1121
1353
  ContentField,
1122
1354
  {
1123
- config,
1355
+ config: fieldConfig,
1124
1356
  form,
1125
1357
  submissionState
1126
1358
  }
1127
1359
  );
1128
1360
  }
1129
- if (config.condition && !config.condition(watchedValues)) {
1361
+ }
1362
+ if ("condition" in fieldConfig && fieldConfig.condition && !fieldConfig.condition(watchedValues)) {
1363
+ return null;
1364
+ }
1365
+ if ("dependsOn" in fieldConfig && fieldConfig.dependsOn) {
1366
+ const dependentValue = get(watchedValues, fieldConfig.dependsOn);
1367
+ if ("dependsOnValue" in fieldConfig && fieldConfig.dependsOnValue !== void 0 && dependentValue !== fieldConfig.dependsOnValue) {
1130
1368
  return null;
1131
1369
  }
1132
- if (config.dependsOn) {
1133
- const dependentValue = get(watchedValues, config.dependsOn);
1134
- if (config.dependsOnValue !== void 0 && dependentValue !== config.dependsOnValue) {
1370
+ }
1371
+ const baseProps = {
1372
+ ariaDescribedBy: "ariaDescribedBy" in fieldConfig ? fieldConfig.ariaDescribedBy : void 0,
1373
+ ariaLabel: "ariaLabel" in fieldConfig ? fieldConfig.ariaLabel : void 0,
1374
+ className: "className" in fieldConfig ? fieldConfig.className : void 0,
1375
+ description: "description" in fieldConfig ? fieldConfig.description : void 0,
1376
+ isDisabled: ("isDisabled" in fieldConfig ? fieldConfig.isDisabled : void 0) ?? submissionState.isSubmitting,
1377
+ label: "label" in fieldConfig ? fieldConfig.label : void 0,
1378
+ // name is Path<TFieldValues> | string, but FieldBaseProps expects Path<TFieldValues>
1379
+ // We pass it directly to each component instead of through baseProps
1380
+ rules: "rules" in fieldConfig ? fieldConfig.rules : void 0
1381
+ };
1382
+ switch (fieldConfig.type) {
1383
+ case "input": {
1384
+ return /* @__PURE__ */ React19.createElement(
1385
+ InputField,
1386
+ {
1387
+ ...baseProps,
1388
+ name: fieldConfig.name,
1389
+ control,
1390
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0,
1391
+ inputProps: "inputProps" in fieldConfig ? fieldConfig.inputProps : void 0
1392
+ }
1393
+ );
1394
+ }
1395
+ case "textarea": {
1396
+ return /* @__PURE__ */ React19.createElement(
1397
+ TextareaField,
1398
+ {
1399
+ ...baseProps,
1400
+ name: fieldConfig.name,
1401
+ control,
1402
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0,
1403
+ textareaProps: "textareaProps" in fieldConfig ? fieldConfig.textareaProps : void 0
1404
+ }
1405
+ );
1406
+ }
1407
+ case "select": {
1408
+ return /* @__PURE__ */ React19.createElement(
1409
+ SelectField,
1410
+ {
1411
+ ...baseProps,
1412
+ name: fieldConfig.name,
1413
+ control,
1414
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0,
1415
+ options: "options" in fieldConfig && fieldConfig.options ? fieldConfig.options.map((opt) => ({
1416
+ label: opt.label,
1417
+ value: String(opt.value)
1418
+ })) : [],
1419
+ selectProps: "selectProps" in fieldConfig ? fieldConfig.selectProps : void 0
1420
+ }
1421
+ );
1422
+ }
1423
+ case "autocomplete": {
1424
+ return /* @__PURE__ */ React19.createElement(
1425
+ AutocompleteField,
1426
+ {
1427
+ ...baseProps,
1428
+ name: fieldConfig.name,
1429
+ control,
1430
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0,
1431
+ items: ("options" in fieldConfig && fieldConfig.options ? fieldConfig.options : []).map((opt) => ({
1432
+ label: opt.label,
1433
+ value: String(opt.value)
1434
+ })),
1435
+ autocompleteProps: "autocompleteProps" in fieldConfig ? fieldConfig.autocompleteProps : void 0
1436
+ }
1437
+ );
1438
+ }
1439
+ case "checkbox": {
1440
+ return /* @__PURE__ */ React19.createElement(
1441
+ CheckboxField,
1442
+ {
1443
+ ...baseProps,
1444
+ name: fieldConfig.name,
1445
+ checkboxProps: "checkboxProps" in fieldConfig ? fieldConfig.checkboxProps : void 0,
1446
+ control,
1447
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0
1448
+ }
1449
+ );
1450
+ }
1451
+ case "checkboxGroup": {
1452
+ return /* @__PURE__ */ React19.createElement(
1453
+ CheckboxGroupField,
1454
+ {
1455
+ ...baseProps,
1456
+ name: fieldConfig.name,
1457
+ checkboxProps: "checkboxProps" in fieldConfig ? fieldConfig.checkboxProps : void 0,
1458
+ control,
1459
+ defaultValue: "defaultValue" in fieldConfig && fieldConfig.defaultValue && Array.isArray(fieldConfig.defaultValue) ? fieldConfig.defaultValue.map((v) => String(v)) : void 0,
1460
+ options: ("checkboxGroupOptions" in fieldConfig && fieldConfig.checkboxGroupOptions ? fieldConfig.checkboxGroupOptions : []).map((opt) => ({
1461
+ label: opt.label,
1462
+ value: String(opt.value)
1463
+ })),
1464
+ orientation: "orientation" in fieldConfig ? fieldConfig.orientation : void 0
1465
+ }
1466
+ );
1467
+ }
1468
+ case "radio": {
1469
+ return /* @__PURE__ */ React19.createElement(
1470
+ RadioGroupField,
1471
+ {
1472
+ ...baseProps,
1473
+ name: fieldConfig.name,
1474
+ control,
1475
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0,
1476
+ options: ("radioOptions" in fieldConfig && fieldConfig.radioOptions ? fieldConfig.radioOptions : []).map((opt) => ({
1477
+ label: opt.label,
1478
+ value: String(opt.value)
1479
+ })),
1480
+ radioGroupProps: "radioProps" in fieldConfig ? fieldConfig.radioProps : void 0
1481
+ }
1482
+ );
1483
+ }
1484
+ case "switch": {
1485
+ return /* @__PURE__ */ React19.createElement(
1486
+ SwitchField,
1487
+ {
1488
+ ...baseProps,
1489
+ name: fieldConfig.name,
1490
+ control,
1491
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0,
1492
+ switchProps: "switchProps" in fieldConfig ? fieldConfig.switchProps : void 0
1493
+ }
1494
+ );
1495
+ }
1496
+ case "slider": {
1497
+ return /* @__PURE__ */ React19.createElement(
1498
+ SliderField,
1499
+ {
1500
+ ...baseProps,
1501
+ name: fieldConfig.name,
1502
+ control,
1503
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0,
1504
+ sliderProps: "sliderProps" in fieldConfig ? fieldConfig.sliderProps : void 0
1505
+ }
1506
+ );
1507
+ }
1508
+ case "stringArray": {
1509
+ return /* @__PURE__ */ React19.createElement(
1510
+ StringArrayField,
1511
+ {
1512
+ ...baseProps,
1513
+ name: fieldConfig.name,
1514
+ control,
1515
+ stringArrayProps: "stringArrayProps" in fieldConfig ? fieldConfig.stringArrayProps : void 0,
1516
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0
1517
+ }
1518
+ );
1519
+ }
1520
+ case "date": {
1521
+ return /* @__PURE__ */ React19.createElement(
1522
+ DateField,
1523
+ {
1524
+ ...baseProps,
1525
+ name: fieldConfig.name,
1526
+ control,
1527
+ dateProps: "dateProps" in fieldConfig ? fieldConfig.dateProps : void 0,
1528
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0
1529
+ }
1530
+ );
1531
+ }
1532
+ case "file": {
1533
+ return /* @__PURE__ */ React19.createElement(
1534
+ FileField,
1535
+ {
1536
+ ...baseProps,
1537
+ name: fieldConfig.name,
1538
+ accept: "accept" in fieldConfig ? fieldConfig.accept : void 0,
1539
+ control,
1540
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0,
1541
+ fileProps: "fileProps" in fieldConfig ? fieldConfig.fileProps : void 0,
1542
+ multiple: "multiple" in fieldConfig ? fieldConfig.multiple : void 0
1543
+ }
1544
+ );
1545
+ }
1546
+ case "fontPicker": {
1547
+ return /* @__PURE__ */ React19.createElement(
1548
+ FontPickerField,
1549
+ {
1550
+ ...baseProps,
1551
+ name: fieldConfig.name,
1552
+ control,
1553
+ defaultValue: "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0,
1554
+ fontPickerProps: "fontPickerProps" in fieldConfig ? fieldConfig.fontPickerProps : void 0
1555
+ }
1556
+ );
1557
+ }
1558
+ case "custom": {
1559
+ if (!("render" in fieldConfig)) {
1135
1560
  return null;
1136
1561
  }
1562
+ return fieldConfig.render({
1563
+ control,
1564
+ errors: form.formState.errors,
1565
+ form,
1566
+ isSubmitting: submissionState.isSubmitting,
1567
+ name: fieldConfig.name
1568
+ });
1137
1569
  }
1138
- const baseProps = {
1139
- ariaDescribedBy: config.ariaDescribedBy,
1140
- ariaLabel: config.ariaLabel,
1141
- className: config.className,
1142
- description: config.description,
1143
- isDisabled: config.isDisabled ?? submissionState.isSubmitting,
1144
- label: config.label,
1145
- name: config.name,
1146
- rules: config.rules
1147
- };
1148
- switch (config.type) {
1149
- case "input":
1150
- return /* @__PURE__ */ React17.createElement(
1151
- InputField,
1152
- {
1153
- ...baseProps,
1154
- control,
1155
- defaultValue: config.defaultValue,
1156
- inputProps: config.inputProps
1157
- }
1158
- );
1159
- case "textarea":
1160
- return /* @__PURE__ */ React17.createElement(
1161
- TextareaField,
1162
- {
1163
- ...baseProps,
1164
- control,
1165
- defaultValue: config.defaultValue,
1166
- textareaProps: config.textareaProps
1167
- }
1168
- );
1169
- case "select":
1170
- return /* @__PURE__ */ React17.createElement(
1171
- SelectField,
1172
- {
1173
- ...baseProps,
1174
- control,
1175
- defaultValue: config.defaultValue,
1176
- options: (config.options ?? []).map((opt) => ({
1177
- label: opt.label,
1178
- value: String(opt.value)
1179
- })),
1180
- selectProps: config.selectProps
1181
- }
1182
- );
1183
- case "autocomplete":
1184
- return /* @__PURE__ */ React17.createElement(
1185
- AutocompleteField,
1186
- {
1187
- ...baseProps,
1188
- control,
1189
- defaultValue: config.defaultValue,
1190
- items: (config.options ?? []).map((opt) => ({
1191
- label: opt.label,
1192
- value: String(opt.value)
1193
- })),
1194
- autocompleteProps: config.autocompleteProps
1195
- }
1196
- );
1197
- case "checkbox":
1198
- return /* @__PURE__ */ React17.createElement(
1199
- CheckboxField,
1200
- {
1201
- ...baseProps,
1202
- checkboxProps: config.checkboxProps,
1203
- control,
1204
- defaultValue: config.defaultValue
1205
- }
1206
- );
1207
- case "radio":
1208
- return /* @__PURE__ */ React17.createElement(
1209
- RadioGroupField,
1210
- {
1211
- ...baseProps,
1212
- control,
1213
- defaultValue: config.defaultValue,
1214
- options: (config.radioOptions ?? []).map((opt) => ({
1215
- label: opt.label,
1216
- value: String(opt.value)
1217
- })),
1218
- radioGroupProps: config.radioProps
1219
- }
1220
- );
1221
- case "switch":
1222
- return /* @__PURE__ */ React17.createElement(
1223
- SwitchField,
1224
- {
1225
- ...baseProps,
1226
- control,
1227
- defaultValue: config.defaultValue,
1228
- switchProps: config.switchProps
1229
- }
1230
- );
1231
- case "slider":
1232
- return /* @__PURE__ */ React17.createElement(
1233
- SliderField,
1234
- {
1235
- ...baseProps,
1236
- control,
1237
- defaultValue: config.defaultValue,
1238
- sliderProps: config.sliderProps
1239
- }
1240
- );
1241
- case "date":
1242
- return /* @__PURE__ */ React17.createElement(
1243
- DateField,
1244
- {
1245
- ...baseProps,
1246
- control,
1247
- dateProps: config.dateProps,
1248
- defaultValue: config.defaultValue
1249
- }
1250
- );
1251
- case "file":
1252
- return /* @__PURE__ */ React17.createElement(
1253
- FileField,
1254
- {
1255
- ...baseProps,
1256
- accept: config.accept,
1257
- control,
1258
- defaultValue: config.defaultValue,
1259
- fileProps: config.fileProps,
1260
- multiple: config.multiple
1261
- }
1262
- );
1263
- case "fontPicker":
1264
- return /* @__PURE__ */ React17.createElement(
1265
- FontPickerField,
1266
- {
1267
- ...baseProps,
1268
- control,
1269
- defaultValue: config.defaultValue,
1270
- fontPickerProps: config.fontPickerProps
1271
- }
1272
- );
1273
- case "custom":
1274
- return config.render({
1570
+ case "conditional": {
1571
+ if (!("condition" in fieldConfig) || !("field" in fieldConfig)) {
1572
+ return null;
1573
+ }
1574
+ const conditionalConfig = {
1575
+ className: "className" in fieldConfig ? fieldConfig.className : void 0,
1576
+ condition: fieldConfig.condition,
1577
+ description: "description" in fieldConfig ? fieldConfig.description : void 0,
1578
+ field: fieldConfig.field,
1579
+ label: "label" in fieldConfig ? fieldConfig.label : void 0,
1580
+ name: fieldConfig.name,
1581
+ type: "conditional"
1582
+ };
1583
+ return /* @__PURE__ */ React19.createElement(
1584
+ ConditionalField,
1585
+ {
1586
+ config: conditionalConfig,
1275
1587
  control,
1276
- errors: form.formState.errors,
1277
- form,
1278
- isSubmitting: submissionState.isSubmitting,
1279
- name: config.name
1280
- });
1281
- case "conditional":
1282
- return /* @__PURE__ */ React17.createElement(
1283
- ConditionalField,
1284
- {
1285
- config,
1286
- control,
1287
- className: config.className
1288
- }
1289
- );
1290
- case "fieldArray":
1291
- return /* @__PURE__ */ React17.createElement(
1292
- FieldArrayField,
1293
- {
1294
- config,
1295
- className: config.className
1296
- }
1297
- );
1298
- case "dynamicSection":
1299
- return /* @__PURE__ */ React17.createElement(
1300
- DynamicSectionField,
1301
- {
1302
- config,
1303
- control,
1304
- className: config.className
1305
- }
1306
- );
1307
- default: {
1308
- const fieldType = config.type;
1309
- console.warn(`Unknown field type: ${fieldType}`);
1588
+ className: conditionalConfig.className
1589
+ }
1590
+ );
1591
+ }
1592
+ case "fieldArray": {
1593
+ if (!("fields" in fieldConfig) || !fieldConfig.fields) {
1594
+ return null;
1595
+ }
1596
+ const fieldArrayConfig = {
1597
+ addButtonText: "addButtonText" in fieldConfig ? fieldConfig.addButtonText : void 0,
1598
+ className: "className" in fieldConfig ? fieldConfig.className : void 0,
1599
+ defaultItem: "defaultItem" in fieldConfig ? fieldConfig.defaultItem : void 0,
1600
+ description: "description" in fieldConfig ? fieldConfig.description : void 0,
1601
+ enableReordering: "enableReordering" in fieldConfig ? fieldConfig.enableReordering : void 0,
1602
+ fields: fieldConfig.fields,
1603
+ label: "label" in fieldConfig ? fieldConfig.label : void 0,
1604
+ max: "max" in fieldConfig ? fieldConfig.max : void 0,
1605
+ min: "min" in fieldConfig ? fieldConfig.min : void 0,
1606
+ name: fieldConfig.name,
1607
+ removeButtonText: "removeButtonText" in fieldConfig ? fieldConfig.removeButtonText : void 0,
1608
+ renderAddButton: "renderAddButton" in fieldConfig ? fieldConfig.renderAddButton : void 0,
1609
+ renderItem: "renderItem" in fieldConfig ? fieldConfig.renderItem : void 0,
1610
+ reorderButtonText: "reorderButtonText" in fieldConfig ? fieldConfig.reorderButtonText : void 0,
1611
+ type: "fieldArray"
1612
+ };
1613
+ return /* @__PURE__ */ React19.createElement(
1614
+ FieldArrayField,
1615
+ {
1616
+ config: fieldArrayConfig,
1617
+ className: fieldArrayConfig.className
1618
+ }
1619
+ );
1620
+ }
1621
+ case "dynamicSection": {
1622
+ if (!("sections" in fieldConfig) || !("condition" in fieldConfig) || !("fields" in fieldConfig)) {
1310
1623
  return null;
1311
1624
  }
1625
+ const dynamicSectionConfig = {
1626
+ className: "className" in fieldConfig ? fieldConfig.className : void 0,
1627
+ condition: fieldConfig.condition,
1628
+ description: "description" in fieldConfig ? fieldConfig.description : void 0,
1629
+ fields: fieldConfig.fields,
1630
+ label: "label" in fieldConfig ? fieldConfig.label : void 0,
1631
+ name: fieldConfig.name,
1632
+ title: "title" in fieldConfig ? fieldConfig.title : void 0,
1633
+ type: "dynamicSection"
1634
+ };
1635
+ return /* @__PURE__ */ React19.createElement(
1636
+ DynamicSectionField,
1637
+ {
1638
+ config: dynamicSectionConfig,
1639
+ control,
1640
+ className: dynamicSectionConfig.className
1641
+ }
1642
+ );
1643
+ }
1644
+ default: {
1645
+ const fieldType = "type" in config ? config.type : "unknown";
1646
+ console.warn(`Unknown field type: ${fieldType}`);
1647
+ return null;
1312
1648
  }
1313
1649
  }
1314
- );
1650
+ }
1651
+ var FormField = FormFieldComponent;
1315
1652
 
1316
1653
  // src/components/Form.tsx
1317
1654
  function ConfigurableForm({
@@ -1348,12 +1685,12 @@ function ConfigurableForm({
1348
1685
  });
1349
1686
  const renderFields = () => {
1350
1687
  if (layout === "grid") {
1351
- return /* @__PURE__ */ React18.createElement(
1688
+ return /* @__PURE__ */ React20.createElement(
1352
1689
  "div",
1353
1690
  {
1354
1691
  className: `grid gap-${spacing} ${columns === 1 ? "grid-cols-1" : columns === 2 ? "grid-cols-1 md:grid-cols-2" : "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"}`
1355
1692
  },
1356
- fields.map((field2) => /* @__PURE__ */ React18.createElement(
1693
+ fields.map((field2) => /* @__PURE__ */ React20.createElement(
1357
1694
  FormField,
1358
1695
  {
1359
1696
  key: field2.name,
@@ -1365,7 +1702,7 @@ function ConfigurableForm({
1365
1702
  );
1366
1703
  }
1367
1704
  if (layout === "horizontal") {
1368
- return /* @__PURE__ */ React18.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, fields.map((field2) => /* @__PURE__ */ React18.createElement(
1705
+ return /* @__PURE__ */ React20.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, fields.map((field2) => /* @__PURE__ */ React20.createElement(
1369
1706
  FormField,
1370
1707
  {
1371
1708
  key: field2.name,
@@ -1375,10 +1712,10 @@ function ConfigurableForm({
1375
1712
  }
1376
1713
  )));
1377
1714
  }
1378
- return /* @__PURE__ */ React18.createElement("div", { className: `space-y-${spacing}` }, fields.map((field2) => /* @__PURE__ */ React18.createElement(
1715
+ return /* @__PURE__ */ React20.createElement("div", { className: `space-y-${spacing}` }, fields.map((field2) => /* @__PURE__ */ React20.createElement(
1379
1716
  FormField,
1380
1717
  {
1381
- key: field2.name,
1718
+ key: field2.name ? pathToString(field2.name) : `field-${Math.random()}`,
1382
1719
  config: field2,
1383
1720
  form,
1384
1721
  submissionState
@@ -1389,23 +1726,23 @@ function ConfigurableForm({
1389
1726
  e.preventDefault();
1390
1727
  void handleSubmit();
1391
1728
  };
1392
- return /* @__PURE__ */ React18.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, title && /* @__PURE__ */ React18.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React18.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React18.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)), isSubmitted && isSuccess && /* @__PURE__ */ React18.createElement(
1729
+ return /* @__PURE__ */ React20.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, title && /* @__PURE__ */ React20.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React20.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React20.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)), isSubmitted && isSuccess && /* @__PURE__ */ React20.createElement(
1393
1730
  "div",
1394
1731
  {
1395
1732
  className: "mb-6 p-4 bg-success-50 border border-success-200 rounded-lg",
1396
1733
  "data-testid": "success-message"
1397
1734
  },
1398
- /* @__PURE__ */ React18.createElement("p", { className: "text-success-800 font-medium" }, "Success!"),
1399
- /* @__PURE__ */ React18.createElement("p", { className: "text-success-700 text-sm mt-1" }, "Your request has been processed successfully.")
1400
- ), error && /* @__PURE__ */ React18.createElement(
1735
+ /* @__PURE__ */ React20.createElement("p", { className: "text-success-800 font-medium" }, "Success!"),
1736
+ /* @__PURE__ */ React20.createElement("p", { className: "text-success-700 text-sm mt-1" }, "Your request has been processed successfully.")
1737
+ ), error && /* @__PURE__ */ React20.createElement(
1401
1738
  "div",
1402
1739
  {
1403
1740
  className: "mb-6 p-4 bg-danger-50 border border-danger-200 rounded-lg",
1404
1741
  "data-testid": "error-message"
1405
1742
  },
1406
- /* @__PURE__ */ React18.createElement("p", { className: "text-danger-800 font-medium" }, "Error"),
1407
- /* @__PURE__ */ React18.createElement("p", { className: "text-danger-700 text-sm mt-1" }, error)
1408
- ), renderFields(), /* @__PURE__ */ React18.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React18.createElement(
1743
+ /* @__PURE__ */ React20.createElement("p", { className: "text-danger-800 font-medium" }, "Error"),
1744
+ /* @__PURE__ */ React20.createElement("p", { className: "text-danger-700 text-sm mt-1" }, error)
1745
+ ), renderFields(), /* @__PURE__ */ React20.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React20.createElement(
1409
1746
  Button3,
1410
1747
  {
1411
1748
  color: "primary",
@@ -1415,7 +1752,7 @@ function ConfigurableForm({
1415
1752
  ...submitButtonProps
1416
1753
  },
1417
1754
  submitButtonText
1418
- ), showResetButton && /* @__PURE__ */ React18.createElement(
1755
+ ), showResetButton && /* @__PURE__ */ React20.createElement(
1419
1756
  Button3,
1420
1757
  {
1421
1758
  isDisabled: isSubmitting,
@@ -1428,7 +1765,7 @@ function ConfigurableForm({
1428
1765
  }
1429
1766
 
1430
1767
  // src/components/ServerActionForm.tsx
1431
- import React19 from "react";
1768
+ import React21 from "react";
1432
1769
  import { useActionState } from "react";
1433
1770
  function ServerActionForm({
1434
1771
  action,
@@ -1453,10 +1790,10 @@ function ServerActionForm({
1453
1790
  action,
1454
1791
  initialState ?? { errors: void 0, message: void 0, success: false }
1455
1792
  );
1456
- const formRef = React19.useRef(null);
1457
- const [clientErrors, setClientErrors] = React19.useState({});
1458
- const lastSubmittedFormData = React19.useRef(null);
1459
- React19.useEffect(() => {
1793
+ const formRef = React21.useRef(null);
1794
+ const [clientErrors, setClientErrors] = React21.useState({});
1795
+ const lastSubmittedFormData = React21.useRef(null);
1796
+ React21.useEffect(() => {
1460
1797
  if (state && (state.errors || state.message && !state.success)) {
1461
1798
  onError?.({
1462
1799
  errors: state.errors,
@@ -1464,7 +1801,7 @@ function ServerActionForm({
1464
1801
  });
1465
1802
  }
1466
1803
  }, [state, onError]);
1467
- React19.useEffect(() => {
1804
+ React21.useEffect(() => {
1468
1805
  if (state?.success && lastSubmittedFormData.current) {
1469
1806
  onSuccess?.(lastSubmittedFormData.current);
1470
1807
  }
@@ -1477,14 +1814,14 @@ function ServerActionForm({
1477
1814
  e.preventDefault();
1478
1815
  if (clientValidationSchema) {
1479
1816
  const formData2 = new FormData(e.currentTarget);
1817
+ const form = e.currentTarget;
1480
1818
  const values = {};
1481
1819
  formData2.forEach((val, key) => {
1482
- if (val === "on") {
1820
+ const formElement = form.querySelector(
1821
+ `input[type="checkbox"][name="${key}"], input[role="switch"][name="${key}"]`
1822
+ );
1823
+ if (formElement instanceof HTMLInputElement && (formElement.type === "checkbox" || formElement.getAttribute("role") === "switch")) {
1483
1824
  values[key] = true;
1484
- } else if (val === "") {
1485
- if (!values[key]) {
1486
- values[key] = false;
1487
- }
1488
1825
  } else {
1489
1826
  values[key] = val;
1490
1827
  }
@@ -1507,12 +1844,12 @@ function ServerActionForm({
1507
1844
  };
1508
1845
  const renderFields = () => {
1509
1846
  if (layout === "grid") {
1510
- return /* @__PURE__ */ React19.createElement(
1847
+ return /* @__PURE__ */ React21.createElement(
1511
1848
  "div",
1512
1849
  {
1513
1850
  className: `grid gap-${spacing} ${columns === 1 ? "grid-cols-1" : columns === 2 ? "grid-cols-1 md:grid-cols-2" : "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"}`
1514
1851
  },
1515
- fields.map((field2) => /* @__PURE__ */ React19.createElement(
1852
+ fields.map((field2) => /* @__PURE__ */ React21.createElement(
1516
1853
  ServerActionField,
1517
1854
  {
1518
1855
  key: field2.name,
@@ -1525,7 +1862,7 @@ function ServerActionForm({
1525
1862
  );
1526
1863
  }
1527
1864
  if (layout === "horizontal") {
1528
- return /* @__PURE__ */ React19.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, fields.map((field2) => /* @__PURE__ */ React19.createElement(
1865
+ return /* @__PURE__ */ React21.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, fields.map((field2) => /* @__PURE__ */ React21.createElement(
1529
1866
  ServerActionField,
1530
1867
  {
1531
1868
  key: field2.name,
@@ -1536,10 +1873,10 @@ function ServerActionForm({
1536
1873
  }
1537
1874
  )));
1538
1875
  }
1539
- return /* @__PURE__ */ React19.createElement("div", { className: `space-y-${spacing}` }, fields.map((field2) => /* @__PURE__ */ React19.createElement(
1876
+ return /* @__PURE__ */ React21.createElement("div", { className: `space-y-${spacing}` }, fields.map((field2) => /* @__PURE__ */ React21.createElement(
1540
1877
  ServerActionField,
1541
1878
  {
1542
- key: field2.name,
1879
+ key: pathToString(field2.name),
1543
1880
  clientErrors,
1544
1881
  defaultValues,
1545
1882
  errors: state?.errors,
@@ -1547,7 +1884,7 @@ function ServerActionForm({
1547
1884
  }
1548
1885
  )));
1549
1886
  };
1550
- return /* @__PURE__ */ React19.createElement(
1887
+ return /* @__PURE__ */ React21.createElement(
1551
1888
  "form",
1552
1889
  {
1553
1890
  ref: formRef,
@@ -1555,27 +1892,27 @@ function ServerActionForm({
1555
1892
  role: "form",
1556
1893
  onSubmit: handleSubmit
1557
1894
  },
1558
- title && /* @__PURE__ */ React19.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React19.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React19.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)),
1559
- state?.success && !pending && /* @__PURE__ */ React19.createElement(
1895
+ title && /* @__PURE__ */ React21.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)),
1896
+ state?.success && !pending && /* @__PURE__ */ React21.createElement(
1560
1897
  "div",
1561
1898
  {
1562
1899
  className: "mb-6 p-4 bg-success-50 border border-success-200 rounded-lg",
1563
1900
  "data-testid": "success-message"
1564
1901
  },
1565
- /* @__PURE__ */ React19.createElement("p", { className: "text-success-800 font-medium" }, "Success!"),
1566
- state.message && /* @__PURE__ */ React19.createElement("p", { className: "text-success-700 text-sm mt-1" }, state.message)
1902
+ /* @__PURE__ */ React21.createElement("p", { className: "text-success-800 font-medium" }, "Success!"),
1903
+ state.message && /* @__PURE__ */ React21.createElement("p", { className: "text-success-700 text-sm mt-1" }, state.message)
1567
1904
  ),
1568
- state?.message && !state.success && /* @__PURE__ */ React19.createElement(
1905
+ state?.message && !state.success && /* @__PURE__ */ React21.createElement(
1569
1906
  "div",
1570
1907
  {
1571
1908
  className: "mb-6 p-4 bg-danger-50 border border-danger-200 rounded-lg",
1572
1909
  "data-testid": "error-message"
1573
1910
  },
1574
- /* @__PURE__ */ React19.createElement("p", { className: "text-danger-800 font-medium" }, "Error"),
1575
- /* @__PURE__ */ React19.createElement("p", { className: "text-danger-700 text-sm mt-1" }, state.message)
1911
+ /* @__PURE__ */ React21.createElement("p", { className: "text-danger-800 font-medium" }, "Error"),
1912
+ /* @__PURE__ */ React21.createElement("p", { className: "text-danger-700 text-sm mt-1" }, state.message)
1576
1913
  ),
1577
1914
  renderFields(),
1578
- /* @__PURE__ */ React19.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React19.createElement(
1915
+ /* @__PURE__ */ React21.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React21.createElement(
1579
1916
  Button,
1580
1917
  {
1581
1918
  color: "primary",
@@ -1585,7 +1922,7 @@ function ServerActionForm({
1585
1922
  ...submitButtonProps
1586
1923
  },
1587
1924
  submitButtonText
1588
- ), showResetButton && /* @__PURE__ */ React19.createElement(
1925
+ ), showResetButton && /* @__PURE__ */ React21.createElement(
1589
1926
  Button,
1590
1927
  {
1591
1928
  isDisabled: pending,
@@ -1603,24 +1940,44 @@ function ServerActionField({
1603
1940
  errors,
1604
1941
  field: field2
1605
1942
  }) {
1606
- if (field2.type === "content") {
1607
- const contentField2 = field2;
1608
- if (contentField2.render) {
1609
- return /* @__PURE__ */ React19.createElement("div", { className: contentField2.className }, contentField2.render({
1943
+ const fieldConfig = field2;
1944
+ const getBaseProps = () => {
1945
+ const baseProps2 = {};
1946
+ if ("label" in fieldConfig) {
1947
+ baseProps2.label = fieldConfig.label;
1948
+ }
1949
+ if ("description" in fieldConfig) {
1950
+ baseProps2.description = fieldConfig.description;
1951
+ }
1952
+ if ("isDisabled" in fieldConfig) {
1953
+ baseProps2.isDisabled = fieldConfig.isDisabled;
1954
+ }
1955
+ return baseProps2;
1956
+ };
1957
+ const baseProps = getBaseProps();
1958
+ if (fieldConfig.type === "content") {
1959
+ const contentField = fieldConfig;
1960
+ if (contentField.render) {
1961
+ const mockForm = {
1962
+ formState: { errors: {} },
1963
+ watch: () => ({})
1964
+ };
1965
+ const renderFn = contentField.render;
1966
+ return /* @__PURE__ */ React21.createElement("div", { className: contentField.className }, renderFn({
1610
1967
  errors: {},
1611
- form: null,
1968
+ form: mockForm,
1612
1969
  isSubmitting: false
1613
1970
  }));
1614
1971
  }
1615
- return /* @__PURE__ */ React19.createElement("div", { className: contentField2.className }, contentField2.title && /* @__PURE__ */ React19.createElement("h3", { className: "text-lg font-semibold text-foreground mb-2" }, contentField2.title), contentField2.description && /* @__PURE__ */ React19.createElement("p", { className: "text-sm text-muted-foreground" }, contentField2.description));
1972
+ return /* @__PURE__ */ React21.createElement("div", { className: contentField.className }, contentField.title && /* @__PURE__ */ React21.createElement("h3", { className: "text-lg font-semibold text-foreground mb-2" }, contentField.title), contentField.description && /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-muted-foreground" }, contentField.description));
1616
1973
  }
1617
- const fieldName = field2.name;
1974
+ const fieldName = pathToString(fieldConfig.name);
1618
1975
  const fieldErrors = errors?.[fieldName];
1619
1976
  const clientError = clientErrors?.[fieldName];
1620
1977
  const errorMessage = clientError || (fieldErrors && fieldErrors.length > 0 ? fieldErrors[0] : void 0);
1621
1978
  const getDefaultValue = () => {
1622
1979
  const fromProps = defaultValues?.[fieldName];
1623
- const fromField = field2.defaultValue;
1980
+ const fromField = "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0;
1624
1981
  if (fromProps !== void 0 && fromProps !== null) {
1625
1982
  return typeof fromProps === "string" ? fromProps : String(fromProps);
1626
1983
  }
@@ -1631,7 +1988,7 @@ function ServerActionField({
1631
1988
  };
1632
1989
  const getDefaultChecked = () => {
1633
1990
  const fromProps = defaultValues?.[fieldName];
1634
- const fromField = field2.defaultValue;
1991
+ const fromField = "defaultValue" in fieldConfig ? fieldConfig.defaultValue : void 0;
1635
1992
  if (fromProps !== void 0 && fromProps !== null) {
1636
1993
  return typeof fromProps === "boolean" ? fromProps : false;
1637
1994
  }
@@ -1640,94 +1997,182 @@ function ServerActionField({
1640
1997
  }
1641
1998
  return false;
1642
1999
  };
1643
- const [value, setValue] = React19.useState(getDefaultValue);
1644
- const [checked, setChecked] = React19.useState(getDefaultChecked);
1645
- React19.useEffect(() => {
2000
+ const [value, setValue] = React21.useState(getDefaultValue);
2001
+ const [checked, setChecked] = React21.useState(getDefaultChecked);
2002
+ React21.useEffect(() => {
1646
2003
  const newDefaultValue = defaultValues?.[fieldName];
1647
2004
  if (newDefaultValue !== void 0 && newDefaultValue !== null) {
1648
- if (field2.type === "checkbox") {
2005
+ if (fieldConfig.type === "checkbox") {
1649
2006
  setChecked(
1650
2007
  typeof newDefaultValue === "boolean" ? newDefaultValue : false
1651
2008
  );
2009
+ } else if (fieldConfig.type === "checkboxGroup") {
2010
+ const arrayValue = Array.isArray(newDefaultValue) ? newDefaultValue.map(String).join(",") : "";
2011
+ setValue(arrayValue);
1652
2012
  } else {
1653
2013
  setValue(
1654
2014
  typeof newDefaultValue === "string" ? newDefaultValue : String(newDefaultValue)
1655
2015
  );
1656
2016
  }
1657
2017
  }
1658
- }, [defaultValues, fieldName, field2.type]);
1659
- React19.useEffect(() => {
2018
+ }, [defaultValues, fieldName, fieldConfig.type]);
2019
+ React21.useEffect(() => {
2020
+ if (fieldConfig.type !== "date") {
2021
+ return;
2022
+ }
1660
2023
  const hiddenInput = document.querySelector(
1661
2024
  `input[type="hidden"][name="${fieldName}"]`
1662
2025
  );
2026
+ if (!(hiddenInput instanceof HTMLInputElement)) {
2027
+ throw new Error(`Expected HTMLInputElement for field ${fieldName}`);
2028
+ }
1663
2029
  if (hiddenInput) {
1664
- if (field2.type === "checkbox") {
1665
- hiddenInput.value = checked ? "on" : "";
1666
- } else {
1667
- hiddenInput.value = value;
1668
- }
2030
+ hiddenInput.value = value || "";
1669
2031
  }
1670
- }, [value, checked, fieldName, field2.type]);
1671
- switch (field2.type) {
2032
+ }, [value, fieldName, fieldConfig.type]);
2033
+ switch (fieldConfig.type) {
1672
2034
  case "input": {
1673
- const inputType = field2.inputProps?.type || "text";
1674
- return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React19.createElement(
2035
+ const stringConfig = fieldConfig;
2036
+ const inputType = stringConfig.inputProps?.type || "text";
2037
+ return /* @__PURE__ */ React21.createElement(
1675
2038
  Input,
1676
2039
  {
1677
- ...field2.inputProps,
2040
+ ...stringConfig.inputProps,
2041
+ name: fieldName,
1678
2042
  "data-field-name": fieldName,
1679
2043
  type: inputType,
1680
- label: field2.label,
1681
- description: field2.description,
1682
- isDisabled: field2.isDisabled,
2044
+ label: baseProps.label,
2045
+ description: baseProps.description,
2046
+ isDisabled: baseProps.isDisabled,
1683
2047
  isInvalid: Boolean(errorMessage),
1684
2048
  errorMessage,
1685
2049
  value,
1686
2050
  onValueChange: setValue
1687
2051
  }
1688
- ));
2052
+ );
1689
2053
  }
1690
2054
  case "textarea": {
1691
- return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React19.createElement(
2055
+ const stringConfig = fieldConfig;
2056
+ return /* @__PURE__ */ React21.createElement(
1692
2057
  Textarea,
1693
2058
  {
1694
- ...field2.textareaProps,
2059
+ ...stringConfig.textareaProps,
2060
+ name: fieldName,
1695
2061
  "data-field-name": fieldName,
1696
- label: field2.label,
1697
- description: field2.description,
1698
- isDisabled: field2.isDisabled,
2062
+ label: baseProps.label,
2063
+ description: baseProps.description,
2064
+ isDisabled: baseProps.isDisabled,
1699
2065
  isInvalid: Boolean(errorMessage),
1700
2066
  errorMessage,
1701
2067
  value,
1702
2068
  onValueChange: setValue
1703
2069
  }
1704
- ));
2070
+ );
1705
2071
  }
1706
2072
  case "checkbox": {
1707
- return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("input", { type: "hidden", name: fieldName, value: checked ? "on" : "" }), /* @__PURE__ */ React19.createElement(
2073
+ const booleanConfig = fieldConfig;
2074
+ const checkboxValue = booleanConfig.checkboxProps?.value ?? "on";
2075
+ const containerRef = React21.useRef(null);
2076
+ React21.useLayoutEffect(() => {
2077
+ const setValue2 = () => {
2078
+ if (containerRef.current) {
2079
+ const input = containerRef.current.querySelector(
2080
+ `input[type="checkbox"][name="${fieldName}"]`
2081
+ );
2082
+ if (input instanceof HTMLInputElement) {
2083
+ input.setAttribute("value", checkboxValue);
2084
+ input.value = checkboxValue;
2085
+ }
2086
+ }
2087
+ };
2088
+ setValue2();
2089
+ const timeoutId = setTimeout(setValue2, 0);
2090
+ return () => clearTimeout(timeoutId);
2091
+ }, [fieldName, checkboxValue, checked]);
2092
+ return /* @__PURE__ */ React21.createElement("div", { ref: containerRef }, /* @__PURE__ */ React21.createElement(
1708
2093
  Checkbox,
1709
2094
  {
1710
- ...field2.checkboxProps,
2095
+ ...booleanConfig.checkboxProps,
2096
+ name: fieldName,
1711
2097
  "data-field-name": fieldName,
1712
- isDisabled: field2.isDisabled,
2098
+ value: checkboxValue,
2099
+ isDisabled: baseProps.isDisabled,
1713
2100
  isSelected: checked,
1714
2101
  onValueChange: setChecked,
1715
2102
  isInvalid: Boolean(errorMessage),
1716
2103
  errorMessage
1717
2104
  },
1718
- field2.label
2105
+ baseProps.label
1719
2106
  ));
1720
2107
  }
2108
+ case "checkboxGroup": {
2109
+ const checkboxGroupConfig = fieldConfig;
2110
+ const options = checkboxGroupConfig.checkboxGroupOptions || [];
2111
+ const currentValues = value ? String(value).split(",").filter(Boolean) : [];
2112
+ return /* @__PURE__ */ React21.createElement("div", null, baseProps.label && /* @__PURE__ */ React21.createElement("label", { className: "text-sm font-medium text-foreground block mb-2" }, baseProps.label), baseProps.description && /* @__PURE__ */ React21.createElement("p", { className: "text-sm text-default-500 mb-2" }, baseProps.description), /* @__PURE__ */ React21.createElement(
2113
+ "div",
2114
+ {
2115
+ className: checkboxGroupConfig.orientation === "horizontal" ? "flex flex-row gap-4 flex-wrap" : "flex flex-col gap-2"
2116
+ },
2117
+ options.map(
2118
+ (option) => {
2119
+ const optionValue = String(option.value);
2120
+ const isSelected = currentValues.includes(optionValue);
2121
+ return /* @__PURE__ */ React21.createElement(
2122
+ Checkbox,
2123
+ {
2124
+ key: optionValue,
2125
+ ...checkboxGroupConfig.checkboxProps,
2126
+ name: fieldName,
2127
+ "data-field-name": fieldName,
2128
+ "data-checkbox-value": optionValue,
2129
+ isDisabled: baseProps.isDisabled,
2130
+ isSelected,
2131
+ onValueChange: (checked2) => {
2132
+ const newValues = checked2 ? [
2133
+ ...currentValues.filter((v) => v !== optionValue),
2134
+ optionValue
2135
+ ] : currentValues.filter((v) => v !== optionValue);
2136
+ setValue(newValues.join(","));
2137
+ },
2138
+ isInvalid: Boolean(errorMessage),
2139
+ errorMessage
2140
+ },
2141
+ option.label
2142
+ );
2143
+ }
2144
+ )
2145
+ ), errorMessage && /* @__PURE__ */ React21.createElement("p", { className: "text-tiny text-danger mt-1" }, errorMessage));
2146
+ }
2147
+ case "switch": {
2148
+ const booleanConfig = fieldConfig;
2149
+ return /* @__PURE__ */ React21.createElement(
2150
+ Switch,
2151
+ {
2152
+ ...booleanConfig.switchProps,
2153
+ name: fieldName,
2154
+ "data-field-name": fieldName,
2155
+ isDisabled: baseProps.isDisabled,
2156
+ isSelected: checked,
2157
+ onValueChange: setChecked,
2158
+ isInvalid: Boolean(errorMessage),
2159
+ errorMessage
2160
+ },
2161
+ baseProps.label
2162
+ );
2163
+ }
1721
2164
  case "select": {
1722
- const options = field2.options || [];
1723
- return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React19.createElement(
2165
+ const stringConfig = fieldConfig;
2166
+ const options = stringConfig.options || [];
2167
+ return /* @__PURE__ */ React21.createElement(
1724
2168
  Select,
1725
2169
  {
1726
- ...field2.selectProps,
2170
+ ...stringConfig.selectProps,
2171
+ name: fieldName,
1727
2172
  "data-field-name": fieldName,
1728
- label: field2.label,
1729
- description: field2.description,
1730
- isDisabled: field2.isDisabled,
2173
+ label: baseProps.label,
2174
+ description: baseProps.description,
2175
+ isDisabled: baseProps.isDisabled,
1731
2176
  isInvalid: Boolean(errorMessage),
1732
2177
  errorMessage,
1733
2178
  selectedKeys: value ? [value] : [],
@@ -1736,25 +2181,142 @@ function ServerActionField({
1736
2181
  setValue(selectedValue || "");
1737
2182
  }
1738
2183
  },
1739
- options.map(
1740
- (option) => /* @__PURE__ */ React19.createElement(SelectItem, { key: String(option.value) }, option.label)
1741
- )
2184
+ options.map((option) => /* @__PURE__ */ React21.createElement(SelectItem, { key: String(option.value) }, option.label))
2185
+ );
2186
+ }
2187
+ case "radio": {
2188
+ const radioConfig = fieldConfig;
2189
+ const options = radioConfig.radioOptions || [];
2190
+ return /* @__PURE__ */ React21.createElement(
2191
+ RadioGroup,
2192
+ {
2193
+ ...radioConfig.radioProps,
2194
+ name: fieldName,
2195
+ "data-field-name": fieldName,
2196
+ label: baseProps.label,
2197
+ description: baseProps.description,
2198
+ isDisabled: baseProps.isDisabled,
2199
+ isInvalid: Boolean(errorMessage),
2200
+ errorMessage,
2201
+ value: value || "",
2202
+ onValueChange: setValue
2203
+ },
2204
+ options.map((option) => /* @__PURE__ */ React21.createElement(Radio, { key: String(option.value), value: String(option.value) }, option.label))
2205
+ );
2206
+ }
2207
+ case "autocomplete": {
2208
+ const stringConfig = fieldConfig;
2209
+ const items = stringConfig.options?.map((opt) => ({
2210
+ label: opt.label,
2211
+ value: String(opt.value)
2212
+ })) || [];
2213
+ return /* @__PURE__ */ React21.createElement(
2214
+ Autocomplete,
2215
+ {
2216
+ ...stringConfig.autocompleteProps,
2217
+ name: fieldName,
2218
+ "data-field-name": fieldName,
2219
+ label: baseProps.label,
2220
+ description: baseProps.description,
2221
+ isDisabled: baseProps.isDisabled,
2222
+ isInvalid: Boolean(errorMessage),
2223
+ errorMessage,
2224
+ selectedKey: value || null,
2225
+ inputValue: value || "",
2226
+ onSelectionChange: (key) => {
2227
+ setValue(key ? String(key) : "");
2228
+ },
2229
+ onInputChange: setValue,
2230
+ items
2231
+ },
2232
+ items.map((item) => /* @__PURE__ */ React21.createElement(AutocompleteItem, { key: String(item.value) }, item.label))
2233
+ );
2234
+ }
2235
+ case "slider": {
2236
+ const sliderConfig = fieldConfig;
2237
+ const numValue = value ? Number(value) : 0;
2238
+ return /* @__PURE__ */ React21.createElement(
2239
+ Slider,
2240
+ {
2241
+ ...sliderConfig.sliderProps,
2242
+ name: fieldName,
2243
+ "data-field-name": fieldName,
2244
+ label: baseProps.label,
2245
+ description: baseProps.description,
2246
+ isDisabled: baseProps.isDisabled,
2247
+ value: numValue,
2248
+ onChange: (val) => {
2249
+ const newValue = Array.isArray(val) ? val[0] : val;
2250
+ setValue(String(newValue));
2251
+ }
2252
+ }
2253
+ );
2254
+ }
2255
+ case "date": {
2256
+ const dateConfig = fieldConfig;
2257
+ return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("input", { type: "hidden", name: fieldName, value: value || "" }), /* @__PURE__ */ React21.createElement(
2258
+ DateInput,
2259
+ {
2260
+ ...dateConfig.dateProps,
2261
+ "data-field-name": fieldName,
2262
+ label: baseProps.label,
2263
+ description: baseProps.description,
2264
+ isDisabled: baseProps.isDisabled,
2265
+ isInvalid: Boolean(errorMessage),
2266
+ errorMessage,
2267
+ value: value ? value : null,
2268
+ onChange: (date) => {
2269
+ const dateString = date ? `${date.year}-${String(date.month).padStart(2, "0")}-${String(date.day).padStart(2, "0")}` : "";
2270
+ setValue(dateString);
2271
+ }
2272
+ }
2273
+ ));
2274
+ }
2275
+ case "file": {
2276
+ const fileConfig = fieldConfig;
2277
+ const multiple = fileConfig.multiple || false;
2278
+ const accept = fileConfig.accept;
2279
+ return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(
2280
+ Input,
2281
+ {
2282
+ ...fileConfig.fileProps,
2283
+ name: fieldName,
2284
+ "data-field-name": fieldName,
2285
+ type: "file",
2286
+ label: baseProps.label,
2287
+ description: baseProps.description,
2288
+ isDisabled: baseProps.isDisabled,
2289
+ isInvalid: Boolean(errorMessage),
2290
+ errorMessage,
2291
+ multiple,
2292
+ accept,
2293
+ onChange: (e) => {
2294
+ if (!(e.target instanceof HTMLInputElement)) {
2295
+ return;
2296
+ }
2297
+ const target = e.target;
2298
+ if (target.files) {
2299
+ setValue(String(target.files.length));
2300
+ }
2301
+ }
2302
+ }
1742
2303
  ));
1743
2304
  }
1744
2305
  default:
1745
- return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React19.createElement(
2306
+ return /* @__PURE__ */ React21.createElement(
1746
2307
  Input,
1747
2308
  {
2309
+ name: fieldName,
1748
2310
  "data-field-name": fieldName,
1749
- label: field2.label,
1750
- description: field2.description,
1751
- isDisabled: field2.isDisabled,
2311
+ label: baseProps.label,
2312
+ description: baseProps.description,
2313
+ isDisabled: baseProps.isDisabled,
1752
2314
  isInvalid: Boolean(errorMessage),
1753
2315
  errorMessage,
1754
2316
  value,
1755
2317
  onValueChange: setValue
1756
2318
  }
1757
- ));
2319
+ );
1758
2320
  }
1759
2321
  }
1760
2322
 
@@ -1772,10 +2334,10 @@ function useHeroForm() {
1772
2334
  }
1773
2335
 
1774
2336
  // src/providers/FormProvider.tsx
1775
- import React20 from "react";
2337
+ import React22 from "react";
1776
2338
  import { FormProvider as RHFProvider } from "react-hook-form";
1777
2339
  function FormProvider(props) {
1778
- return /* @__PURE__ */ React20.createElement(RHFProvider, { ...props.methods }, /* @__PURE__ */ React20.createElement(
2340
+ return /* @__PURE__ */ React22.createElement(RHFProvider, { ...props.methods }, /* @__PURE__ */ React22.createElement(
1779
2341
  "form",
1780
2342
  {
1781
2343
  className: props.className,
@@ -1788,7 +2350,7 @@ function FormProvider(props) {
1788
2350
  }
1789
2351
 
1790
2352
  // src/submit/SubmitButton.tsx
1791
- import React21 from "react";
2353
+ import React23 from "react";
1792
2354
  function SubmitButton(props) {
1793
2355
  const ctx = useFormContext5();
1794
2356
  const loading = props.isLoading ?? ctx.formState.isSubmitting;
@@ -1798,10 +2360,10 @@ function SubmitButton(props) {
1798
2360
  const defaults = useHeroHookFormDefaults();
1799
2361
  const getButtonContent = () => {
1800
2362
  if (enhancedState?.isSuccess) {
1801
- return /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2" }, "\u2705", props.successText || "Success!");
2363
+ return /* @__PURE__ */ React23.createElement("span", { className: "inline-flex items-center gap-2" }, "\u2705", props.successText || "Success!");
1802
2364
  }
1803
2365
  if (loading) {
1804
- return /* @__PURE__ */ React21.createElement("span", { className: "inline-flex items-center gap-2" }, "\u23F3", props.loadingText || "Submitting...");
2366
+ return /* @__PURE__ */ React23.createElement("span", { className: "inline-flex items-center gap-2" }, "\u23F3", props.loadingText || "Submitting...");
1805
2367
  }
1806
2368
  return props.children;
1807
2369
  };
@@ -1814,7 +2376,7 @@ function SubmitButton(props) {
1814
2376
  }
1815
2377
  return props.buttonProps?.color || defaults.submitButton.color;
1816
2378
  };
1817
- return /* @__PURE__ */ React21.createElement(
2379
+ return /* @__PURE__ */ React23.createElement(
1818
2380
  Button,
1819
2381
  {
1820
2382
  type: "submit",
@@ -2055,7 +2617,7 @@ var commonValidations = {
2055
2617
  import { useFormContext as useFormContext5 } from "react-hook-form";
2056
2618
 
2057
2619
  // src/components/ZodForm.tsx
2058
- import React23 from "react";
2620
+ import React25 from "react";
2059
2621
  import { Button as Button5 } from "@heroui/react";
2060
2622
  import {
2061
2623
  FormProvider as FormProvider2
@@ -2079,8 +2641,15 @@ function createZodResolver(schema) {
2079
2641
  const path = err.path.join(".");
2080
2642
  errors[path] = { message: err.message };
2081
2643
  });
2644
+ const fieldErrors = {};
2645
+ Object.entries(errors).forEach(([path, error2]) => {
2646
+ fieldErrors[path] = error2;
2647
+ });
2082
2648
  return {
2083
- errors,
2649
+ // TypeScript can't prove all paths are valid field paths, but at runtime they will be
2650
+ // because Zod validates against the schema which matches T
2651
+ // This is a necessary type assertion due to TypeScript's limitations with dynamic paths
2652
+ errors: fieldErrors,
2084
2653
  values: {}
2085
2654
  };
2086
2655
  }
@@ -2098,14 +2667,12 @@ function createZodFormConfig(schema, fields, defaultValues) {
2098
2667
  return {
2099
2668
  fields,
2100
2669
  schema,
2101
- ...defaultValues && {
2102
- defaultValues
2103
- }
2670
+ ...defaultValues && { defaultValues }
2104
2671
  };
2105
2672
  }
2106
2673
 
2107
2674
  // src/hooks/useEnhancedFormState.ts
2108
- import { useCallback, useEffect, useState as useState2 } from "react";
2675
+ import { useCallback, useEffect, useState as useState3 } from "react";
2109
2676
  function useEnhancedFormState(form, options = {}) {
2110
2677
  const {
2111
2678
  autoReset = true,
@@ -2117,9 +2684,9 @@ function useEnhancedFormState(form, options = {}) {
2117
2684
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2118
2685
  successMessage: _successMessage = "Form submitted successfully!"
2119
2686
  } = options;
2120
- const [status, setStatus] = useState2("idle");
2121
- const [error, setError] = useState2(void 0);
2122
- const [submittedData, setSubmittedData] = useState2(void 0);
2687
+ const [status, setStatus] = useState3("idle");
2688
+ const [error, setError] = useState3(void 0);
2689
+ const [submittedData, setSubmittedData] = useState3(void 0);
2123
2690
  const { formState, getValues: _getValues } = form;
2124
2691
  const { dirtyFields, errors, isSubmitting, touchedFields } = formState;
2125
2692
  useEffect(() => {
@@ -2178,7 +2745,7 @@ function useEnhancedFormState(form, options = {}) {
2178
2745
  }
2179
2746
 
2180
2747
  // src/components/FormStatus.tsx
2181
- import React22 from "react";
2748
+ import React24 from "react";
2182
2749
  import { Button as Button4 } from "@heroui/react";
2183
2750
  function FormStatus({
2184
2751
  className = "",
@@ -2191,25 +2758,25 @@ function FormStatus({
2191
2758
  return null;
2192
2759
  }
2193
2760
  if (isSubmitting) {
2194
- return /* @__PURE__ */ React22.createElement(
2761
+ return /* @__PURE__ */ React24.createElement(
2195
2762
  "div",
2196
2763
  {
2197
2764
  className: `flex items-center gap-3 p-4 bg-blue-50 border border-blue-200 rounded-lg ${className}`
2198
2765
  },
2199
- /* @__PURE__ */ React22.createElement("span", { className: "text-blue-600" }, "\u23F3"),
2200
- /* @__PURE__ */ React22.createElement("div", null, /* @__PURE__ */ React22.createElement("p", { className: "text-sm font-medium text-blue-900" }, "Submitting form..."), showDetails && /* @__PURE__ */ React22.createElement("p", { className: "text-xs text-blue-700" }, "Please wait while we process your request."))
2766
+ /* @__PURE__ */ React24.createElement("span", { className: "text-blue-600" }, "\u23F3"),
2767
+ /* @__PURE__ */ React24.createElement("div", null, /* @__PURE__ */ React24.createElement("p", { className: "text-sm font-medium text-blue-900" }, "Submitting form..."), showDetails && /* @__PURE__ */ React24.createElement("p", { className: "text-xs text-blue-700" }, "Please wait while we process your request."))
2201
2768
  );
2202
2769
  }
2203
2770
  if (isSuccess) {
2204
- return /* @__PURE__ */ React22.createElement(
2771
+ return /* @__PURE__ */ React24.createElement(
2205
2772
  "div",
2206
2773
  {
2207
2774
  className: `flex items-center gap-3 p-4 bg-green-50 border border-green-200 rounded-lg ${className}`,
2208
2775
  "data-testid": "success-message"
2209
2776
  },
2210
- /* @__PURE__ */ React22.createElement("span", { className: "text-green-600" }, "\u2705"),
2211
- /* @__PURE__ */ React22.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React22.createElement("p", { className: "text-sm font-medium text-green-900" }, "Form submitted successfully!"), showDetails && submittedData && /* @__PURE__ */ React22.createElement("p", { className: "text-xs text-green-700" }, "Your data has been saved. Thank you for your submission.")),
2212
- onDismiss && /* @__PURE__ */ React22.createElement(
2777
+ /* @__PURE__ */ React24.createElement("span", { className: "text-green-600" }, "\u2705"),
2778
+ /* @__PURE__ */ React24.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React24.createElement("p", { className: "text-sm font-medium text-green-900" }, "Form submitted successfully!"), showDetails && submittedData && /* @__PURE__ */ React24.createElement("p", { className: "text-xs text-green-700" }, "Your data has been saved. Thank you for your submission.")),
2779
+ onDismiss && /* @__PURE__ */ React24.createElement(
2213
2780
  Button4,
2214
2781
  {
2215
2782
  size: "sm",
@@ -2223,15 +2790,15 @@ function FormStatus({
2223
2790
  );
2224
2791
  }
2225
2792
  if (isError && error) {
2226
- return /* @__PURE__ */ React22.createElement(
2793
+ return /* @__PURE__ */ React24.createElement(
2227
2794
  "div",
2228
2795
  {
2229
2796
  className: `flex items-center gap-3 p-4 bg-red-50 border border-red-200 rounded-lg ${className}`,
2230
2797
  "data-testid": "error-message"
2231
2798
  },
2232
- /* @__PURE__ */ React22.createElement("span", { className: "text-red-600" }, "\u26A0\uFE0F"),
2233
- /* @__PURE__ */ React22.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React22.createElement("p", { className: "text-sm font-medium text-red-900" }, "Error submitting form"), /* @__PURE__ */ React22.createElement("p", { className: "text-xs text-red-700" }, error)),
2234
- onDismiss && /* @__PURE__ */ React22.createElement(
2799
+ /* @__PURE__ */ React24.createElement("span", { className: "text-red-600" }, "\u26A0\uFE0F"),
2800
+ /* @__PURE__ */ React24.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React24.createElement("p", { className: "text-sm font-medium text-red-900" }, "Error submitting form"), /* @__PURE__ */ React24.createElement("p", { className: "text-xs text-red-700" }, error)),
2801
+ onDismiss && /* @__PURE__ */ React24.createElement(
2235
2802
  Button4,
2236
2803
  {
2237
2804
  size: "sm",
@@ -2252,8 +2819,8 @@ function FormToast({
2252
2819
  position = "top-right",
2253
2820
  state
2254
2821
  }) {
2255
- const [isVisible, setIsVisible] = React22.useState(false);
2256
- React22.useEffect(() => {
2822
+ const [isVisible, setIsVisible] = React24.useState(false);
2823
+ React24.useEffect(() => {
2257
2824
  if (state.isSuccess || state.isError) {
2258
2825
  setIsVisible(true);
2259
2826
  if (duration > 0) {
@@ -2274,7 +2841,7 @@ function FormToast({
2274
2841
  "top-left": "top-4 left-4",
2275
2842
  "top-right": "top-4 right-4"
2276
2843
  };
2277
- return /* @__PURE__ */ React22.createElement("div", { className: `fixed z-50 ${positionClasses[position]}` }, /* @__PURE__ */ React22.createElement(FormStatus, { state, onDismiss }));
2844
+ return /* @__PURE__ */ React24.createElement("div", { className: `fixed z-50 ${positionClasses[position]}` }, /* @__PURE__ */ React24.createElement(FormStatus, { state, onDismiss }));
2278
2845
  }
2279
2846
 
2280
2847
  // src/components/ZodForm.tsx
@@ -2294,7 +2861,10 @@ function ZodForm({
2294
2861
  subtitle,
2295
2862
  title
2296
2863
  }) {
2297
- const form = useZodForm(config);
2864
+ const formConfig = {
2865
+ ...config
2866
+ };
2867
+ const form = useZodForm(formConfig);
2298
2868
  const enhancedState = useEnhancedFormState(form, {
2299
2869
  autoReset: true,
2300
2870
  onError: (error) => onError?.({ field: "form", message: error }),
@@ -2324,12 +2894,12 @@ function ZodForm({
2324
2894
  };
2325
2895
  const renderFields = () => {
2326
2896
  if (layout === "grid") {
2327
- return /* @__PURE__ */ React23.createElement(
2897
+ return /* @__PURE__ */ React25.createElement(
2328
2898
  "div",
2329
2899
  {
2330
2900
  className: `grid gap-${spacing} ${columns === 1 ? "grid-cols-1" : columns === 2 ? "grid-cols-1 md:grid-cols-2" : "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"}`
2331
2901
  },
2332
- config.fields.map((field2) => /* @__PURE__ */ React23.createElement(
2902
+ config.fields.map((field2) => /* @__PURE__ */ React25.createElement(
2333
2903
  FormField,
2334
2904
  {
2335
2905
  key: field2.name,
@@ -2346,7 +2916,7 @@ function ZodForm({
2346
2916
  );
2347
2917
  }
2348
2918
  if (layout === "horizontal") {
2349
- return /* @__PURE__ */ React23.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, config.fields.map((field2) => /* @__PURE__ */ React23.createElement(
2919
+ return /* @__PURE__ */ React25.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, config.fields.map((field2) => /* @__PURE__ */ React25.createElement(
2350
2920
  FormField,
2351
2921
  {
2352
2922
  key: field2.name,
@@ -2361,10 +2931,10 @@ function ZodForm({
2361
2931
  }
2362
2932
  )));
2363
2933
  }
2364
- return /* @__PURE__ */ React23.createElement("div", { className: `space-y-${spacing}` }, config.fields.map((field2) => /* @__PURE__ */ React23.createElement(
2934
+ return /* @__PURE__ */ React25.createElement("div", { className: `space-y-${spacing}` }, config.fields.map((field2) => /* @__PURE__ */ React25.createElement(
2365
2935
  FormField,
2366
2936
  {
2367
- key: field2.name,
2937
+ key: pathToString(field2.name),
2368
2938
  config: field2,
2369
2939
  form,
2370
2940
  submissionState: {
@@ -2380,19 +2950,19 @@ function ZodForm({
2380
2950
  e.preventDefault();
2381
2951
  void handleSubmit();
2382
2952
  };
2383
- React23.useEffect(() => {
2953
+ React25.useEffect(() => {
2384
2954
  if (config.onError && Object.keys(form.formState.errors).length > 0) {
2385
2955
  config.onError(form.formState.errors);
2386
2956
  }
2387
2957
  }, [form.formState.errors, config.onError]);
2388
- return /* @__PURE__ */ React23.createElement(FormProvider2, { ...form }, /* @__PURE__ */ React23.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, title && /* @__PURE__ */ React23.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React23.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React23.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)), /* @__PURE__ */ React23.createElement(
2958
+ return /* @__PURE__ */ React25.createElement(FormProvider2, { ...form }, /* @__PURE__ */ React25.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, title && /* @__PURE__ */ React25.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React25.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React25.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)), /* @__PURE__ */ React25.createElement(
2389
2959
  FormStatus,
2390
2960
  {
2391
2961
  state: enhancedState,
2392
2962
  onDismiss: () => enhancedState.reset(),
2393
2963
  showDetails: true
2394
2964
  }
2395
- ), renderFields(), /* @__PURE__ */ React23.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React23.createElement(
2965
+ ), renderFields(), /* @__PURE__ */ React25.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React25.createElement(
2396
2966
  Button5,
2397
2967
  {
2398
2968
  color: "primary",
@@ -2402,7 +2972,7 @@ function ZodForm({
2402
2972
  ...submitButtonProps
2403
2973
  },
2404
2974
  enhancedState.isSuccess ? "Success!" : submitButtonText
2405
- ), showResetButton && /* @__PURE__ */ React23.createElement(
2975
+ ), showResetButton && /* @__PURE__ */ React25.createElement(
2406
2976
  Button5,
2407
2977
  {
2408
2978
  isDisabled: enhancedState.isSubmitting,
@@ -2415,7 +2985,7 @@ function ZodForm({
2415
2985
  }
2416
2986
 
2417
2987
  // src/components/SimpleForm.tsx
2418
- import React24 from "react";
2988
+ import React26 from "react";
2419
2989
  function SimpleForm({
2420
2990
  className,
2421
2991
  defaultValues,
@@ -2429,7 +2999,7 @@ function SimpleForm({
2429
2999
  subtitle,
2430
3000
  title
2431
3001
  }) {
2432
- return /* @__PURE__ */ React24.createElement(
3002
+ return /* @__PURE__ */ React26.createElement(
2433
3003
  ZodForm,
2434
3004
  {
2435
3005
  className,
@@ -2553,6 +3123,29 @@ var BasicFormBuilder = class {
2553
3123
  function createBasicFormBuilder() {
2554
3124
  return new BasicFormBuilder();
2555
3125
  }
3126
+ function inputHelper(name, label, typeOrProps, inputProps) {
3127
+ if (typeOrProps && typeof typeOrProps === "object" && !("type" in typeOrProps && typeof typeOrProps.type === "string" && ["text", "email", "tel", "password"].includes(typeOrProps.type))) {
3128
+ return {
3129
+ inputProps: {
3130
+ type: "text",
3131
+ ...typeOrProps
3132
+ },
3133
+ label,
3134
+ name,
3135
+ type: "input"
3136
+ };
3137
+ }
3138
+ const type = typeof typeOrProps === "string" ? typeOrProps : void 0;
3139
+ return {
3140
+ inputProps: {
3141
+ type: type || "text",
3142
+ ...inputProps
3143
+ },
3144
+ label,
3145
+ name,
3146
+ type: "input"
3147
+ };
3148
+ }
2556
3149
  var FormFieldHelpers = {
2557
3150
  /**
2558
3151
  * Create an autocomplete field
@@ -2603,6 +3196,34 @@ var FormFieldHelpers = {
2603
3196
  name,
2604
3197
  type: "checkbox"
2605
3198
  }),
3199
+ /**
3200
+ * Create a checkbox group field (multiple checkboxes saving to an array)
3201
+ *
3202
+ * @example
3203
+ * ```tsx
3204
+ * // Simple checkbox group
3205
+ * FormFieldHelpers.checkboxGroup("interests", "Interests", [
3206
+ * { label: "Reading", value: "reading" },
3207
+ * { label: "Sports", value: "sports" },
3208
+ * { label: "Music", value: "music" },
3209
+ * ])
3210
+ *
3211
+ * // With horizontal layout and custom styling
3212
+ * FormFieldHelpers.checkboxGroup("interests", "Interests", options, {
3213
+ * orientation: "horizontal",
3214
+ * checkboxProps: { color: "primary", size: "lg" }
3215
+ * })
3216
+ * ```
3217
+ */
3218
+ checkboxGroup: (name, label, options, config) => ({
3219
+ checkboxGroupOptions: options,
3220
+ checkboxProps: config?.checkboxProps,
3221
+ description: config?.description,
3222
+ label,
3223
+ name,
3224
+ orientation: config?.orientation || "vertical",
3225
+ type: "checkboxGroup"
3226
+ }),
2606
3227
  /**
2607
3228
  * Create a conditional field that shows/hides based on form data
2608
3229
  *
@@ -2627,12 +3248,13 @@ var FormFieldHelpers = {
2627
3248
  * ```
2628
3249
  */
2629
3250
  conditional: (name, condition, field2) => {
2630
- return {
3251
+ const config = {
2631
3252
  condition,
2632
3253
  field: field2,
2633
3254
  name,
2634
3255
  type: "conditional"
2635
3256
  };
3257
+ return config;
2636
3258
  },
2637
3259
  /**
2638
3260
  * Create a content field for headers, questions, or custom content between fields
@@ -2649,7 +3271,7 @@ var FormFieldHelpers = {
2649
3271
  * ```
2650
3272
  */
2651
3273
  content: (title, description, options) => {
2652
- return {
3274
+ const config = {
2653
3275
  className: options?.className,
2654
3276
  description: description || void 0,
2655
3277
  name: options?.name,
@@ -2657,7 +3279,31 @@ var FormFieldHelpers = {
2657
3279
  title: title || void 0,
2658
3280
  type: "content"
2659
3281
  };
3282
+ return config;
2660
3283
  },
3284
+ /**
3285
+ * Create a custom field with full control over rendering
3286
+ *
3287
+ * @example
3288
+ * ```tsx
3289
+ * // Custom field with render function
3290
+ * FormFieldHelpers.custom<FormData>(
3291
+ * "skills",
3292
+ * "Skills",
3293
+ * ({ form, control }) => {
3294
+ * // Custom rendering logic
3295
+ * return <div>...</div>;
3296
+ * }
3297
+ * )
3298
+ * ```
3299
+ */
3300
+ custom: (name, label, render, options) => ({
3301
+ label,
3302
+ name,
3303
+ render,
3304
+ type: "custom",
3305
+ ...options
3306
+ }),
2661
3307
  /**
2662
3308
  * Create a date field
2663
3309
  *
@@ -2743,7 +3389,10 @@ var FormFieldHelpers = {
2743
3389
  * // With type
2744
3390
  * FormFieldHelpers.input("email", "Email", "email")
2745
3391
  *
2746
- * // With full customization
3392
+ * // With props only (no type)
3393
+ * FormFieldHelpers.input("name", "Name", { placeholder: "Enter name" })
3394
+ *
3395
+ * // With type and props
2747
3396
  * FormFieldHelpers.input("email", "Email", "email", {
2748
3397
  * placeholder: "Enter your email",
2749
3398
  * classNames: { input: "custom-input" },
@@ -2752,15 +3401,25 @@ var FormFieldHelpers = {
2752
3401
  * })
2753
3402
  * ```
2754
3403
  */
2755
- input: (name, label, type, inputProps) => ({
2756
- inputProps: {
2757
- type: type || "text",
2758
- ...inputProps
2759
- },
2760
- label,
2761
- name,
2762
- type: "input"
2763
- }),
3404
+ input: inputHelper,
3405
+ /**
3406
+ * Create a radio group field
3407
+ *
3408
+ * @example
3409
+ * ```tsx
3410
+ * // Simple radio group
3411
+ * FormFieldHelpers.radio("gender", "Gender", [
3412
+ * { label: "Male", value: "male" },
3413
+ * { label: "Female", value: "female" }
3414
+ * ])
3415
+ *
3416
+ * // With full customization
3417
+ * FormFieldHelpers.radio("gender", "Gender", options, {
3418
+ * orientation: "horizontal",
3419
+ * classNames: { base: "custom-radio" }
3420
+ * })
3421
+ * ```
3422
+ */
2764
3423
  /**
2765
3424
  * Create a radio group field
2766
3425
  *
@@ -2893,6 +3552,8 @@ var CommonFields = {
2893
3552
  * Address fields
2894
3553
  */
2895
3554
  address: () => [
3555
+ // Type assertions are necessary: TypeScript can't prove these strings are valid Path<T>
3556
+ // for an arbitrary T, but they will be valid when used with a matching schema
2896
3557
  FormFieldHelpers.input("street", "Street Address"),
2897
3558
  FormFieldHelpers.input("city", "City"),
2898
3559
  FormFieldHelpers.input("state", "State/Province"),
@@ -2911,6 +3572,7 @@ var CommonFields = {
2911
3572
  * Personal information fields
2912
3573
  */
2913
3574
  personal: () => [
3575
+ // Type assertions are necessary - see CommonFields documentation above
2914
3576
  FormFieldHelpers.input("firstName", "First Name"),
2915
3577
  FormFieldHelpers.input("lastName", "Last Name"),
2916
3578
  FormFieldHelpers.input("email", "Email", "email"),
@@ -2920,6 +3582,7 @@ var CommonFields = {
2920
3582
  * Terms and conditions fields
2921
3583
  */
2922
3584
  terms: () => [
3585
+ // Type assertions are necessary - see CommonFields documentation above
2923
3586
  FormFieldHelpers.checkbox(
2924
3587
  "terms",
2925
3588
  "I agree to the terms and conditions"
@@ -2936,7 +3599,7 @@ var CommonFields = {
2936
3599
  };
2937
3600
 
2938
3601
  // src/builders/AdvancedFormBuilder.ts
2939
- function inputField(name, label, props) {
3602
+ function createInputField(name, label, props) {
2940
3603
  return {
2941
3604
  label,
2942
3605
  name,
@@ -2952,7 +3615,7 @@ function inputField(name, label, props) {
2952
3615
  }
2953
3616
  };
2954
3617
  }
2955
- function textareaField(name, label, props) {
3618
+ function createTextareaField(name, label, props) {
2956
3619
  return {
2957
3620
  label,
2958
3621
  name,
@@ -2968,7 +3631,7 @@ function textareaField(name, label, props) {
2968
3631
  }
2969
3632
  };
2970
3633
  }
2971
- function selectField(name, label, options) {
3634
+ function createSelectField(name, label, options) {
2972
3635
  return {
2973
3636
  label,
2974
3637
  name,
@@ -2976,7 +3639,7 @@ function selectField(name, label, options) {
2976
3639
  type: "select"
2977
3640
  };
2978
3641
  }
2979
- function checkboxField(name, label, props) {
3642
+ function createCheckboxField(name, label, props) {
2980
3643
  return {
2981
3644
  label,
2982
3645
  name,
@@ -2989,7 +3652,7 @@ function checkboxField(name, label, props) {
2989
3652
  }
2990
3653
  };
2991
3654
  }
2992
- function switchField(name, label, props) {
3655
+ function createSwitchField(name, label, props) {
2993
3656
  return {
2994
3657
  description: props?.description,
2995
3658
  isDisabled: props?.isDisabled,
@@ -3003,7 +3666,7 @@ function switchField(name, label, props) {
3003
3666
  }
3004
3667
  };
3005
3668
  }
3006
- function radioField(name, label, options, props) {
3669
+ function createRadioField(name, label, options, props) {
3007
3670
  return {
3008
3671
  label,
3009
3672
  name,
@@ -3018,7 +3681,7 @@ function radioField(name, label, options, props) {
3018
3681
  }
3019
3682
  };
3020
3683
  }
3021
- function sliderField(name, label, props) {
3684
+ function createSliderField(name, label, props) {
3022
3685
  return {
3023
3686
  label,
3024
3687
  name,
@@ -3033,20 +3696,19 @@ function sliderField(name, label, props) {
3033
3696
  }
3034
3697
  };
3035
3698
  }
3036
- function dateField(name, label, props) {
3699
+ function createDateField(name, label, props) {
3700
+ const dateProps = {};
3701
+ if (props?.className !== void 0) {
3702
+ dateProps.className = props.className;
3703
+ }
3037
3704
  return {
3038
3705
  label,
3039
3706
  name,
3040
3707
  type: "date",
3041
- ...props && {
3042
- dateProps: {
3043
- className: props.className,
3044
- placeholder: props.placeholder
3045
- }
3046
- }
3708
+ ...Object.keys(dateProps).length > 0 && { dateProps }
3047
3709
  };
3048
3710
  }
3049
- function fileField(name, label, props) {
3711
+ function createFileField(name, label, props) {
3050
3712
  return {
3051
3713
  label,
3052
3714
  name,
@@ -3061,7 +3723,7 @@ function fileField(name, label, props) {
3061
3723
  }
3062
3724
  };
3063
3725
  }
3064
- function fontPickerField(name, label, props) {
3726
+ function createFontPickerField(name, label, props) {
3065
3727
  return {
3066
3728
  className: props?.className,
3067
3729
  description: props?.description,
@@ -3071,83 +3733,119 @@ function fontPickerField(name, label, props) {
3071
3733
  type: "fontPicker"
3072
3734
  };
3073
3735
  }
3074
- function contentField(title, description, options) {
3736
+ function createStringArrayField(name, label, props) {
3737
+ return {
3738
+ className: props?.className,
3739
+ description: props?.description,
3740
+ isDisabled: props?.isDisabled,
3741
+ label,
3742
+ name,
3743
+ stringArrayProps: {
3744
+ addButtonText: props?.addButtonText,
3745
+ allowDuplicates: props?.allowDuplicates,
3746
+ maxItems: props?.maxItems,
3747
+ minItems: props?.minItems,
3748
+ placeholder: props?.placeholder,
3749
+ showAddButton: props?.showAddButton,
3750
+ transformItem: props?.transformItem,
3751
+ validateItem: props?.validateItem
3752
+ },
3753
+ type: "stringArray"
3754
+ };
3755
+ }
3756
+ function createContentField(config) {
3075
3757
  return {
3076
- className: options?.className,
3077
- description: description || void 0,
3078
- name: options?.name,
3079
- render: options?.render,
3080
- title: title || void 0,
3758
+ className: config.className,
3759
+ description: config.description || void 0,
3760
+ name: config.name,
3761
+ render: config.render,
3762
+ title: config.title || void 0,
3081
3763
  type: "content"
3082
3764
  };
3083
3765
  }
3084
- function createField(type, name, label, optionsOrProps, props) {
3085
- switch (type) {
3766
+ function createFieldFromParams(params) {
3767
+ switch (params.type) {
3086
3768
  case "input":
3087
- return inputField(name, label, optionsOrProps);
3769
+ return createInputField(params.name, params.label, params.props);
3088
3770
  case "textarea":
3089
- return textareaField(name, label, optionsOrProps);
3771
+ return createTextareaField(params.name, params.label, params.props);
3090
3772
  case "select":
3091
- return selectField(name, label, optionsOrProps);
3773
+ return createSelectField(params.name, params.label, params.options);
3092
3774
  case "checkbox":
3093
- return checkboxField(name, label, optionsOrProps);
3775
+ return createCheckboxField(params.name, params.label, params.props);
3094
3776
  case "switch":
3095
- return switchField(name, label, optionsOrProps);
3777
+ return createSwitchField(params.name, params.label, params.props);
3096
3778
  case "radio":
3097
- return radioField(name, label, optionsOrProps, props);
3779
+ return createRadioField(
3780
+ params.name,
3781
+ params.label,
3782
+ params.options,
3783
+ params.props
3784
+ );
3098
3785
  case "slider":
3099
- return sliderField(name, label, optionsOrProps);
3786
+ return createSliderField(params.name, params.label, params.props);
3100
3787
  case "date":
3101
- return dateField(name, label, optionsOrProps);
3788
+ return createDateField(params.name, params.label, params.props);
3102
3789
  case "file":
3103
- return fileField(name, label, optionsOrProps);
3790
+ return createFileField(params.name, params.label, params.props);
3104
3791
  case "fontPicker":
3105
- return fontPickerField(name, label, optionsOrProps);
3792
+ return createFontPickerField(params.name, params.label, params.props);
3793
+ case "stringArray":
3794
+ return createStringArrayField(params.name, params.label, params.props);
3795
+ case "autocomplete":
3796
+ return {
3797
+ autocompleteProps: params.props,
3798
+ label: params.label,
3799
+ name: params.name,
3800
+ options: params.options,
3801
+ type: "autocomplete"
3802
+ };
3106
3803
  case "content":
3107
- if (typeof optionsOrProps === "string" || optionsOrProps === null) {
3108
- return contentField(optionsOrProps, props);
3109
- }
3110
- if (typeof optionsOrProps === "object" && optionsOrProps !== null) {
3111
- return contentField(
3112
- optionsOrProps.title,
3113
- optionsOrProps.description,
3114
- optionsOrProps
3115
- );
3116
- }
3117
- return contentField(
3118
- name,
3119
- label,
3120
- optionsOrProps
3121
- );
3122
- default:
3123
- throw new Error(`Unknown field type: ${type}`);
3804
+ return createContentField({
3805
+ className: params.className,
3806
+ description: params.description,
3807
+ name: params.name,
3808
+ render: params.render,
3809
+ title: params.title
3810
+ });
3811
+ default: {
3812
+ const _exhaustive = params;
3813
+ throw new Error(`Unknown field type: ${_exhaustive.type}`);
3814
+ }
3124
3815
  }
3125
3816
  }
3817
+ function createField(params) {
3818
+ return createFieldFromParams(params);
3819
+ }
3126
3820
  var AdvancedFieldBuilder = class {
3127
3821
  constructor() {
3128
3822
  this.fields = [];
3129
3823
  }
3130
- field(type, name, label, optionsOrProps, props) {
3131
- this.fields.push(createField(type, name, label, optionsOrProps, props));
3824
+ /**
3825
+ * Add any field type using the unified API
3826
+ */
3827
+ field(params) {
3828
+ this.fields.push(createField(params));
3132
3829
  return this;
3133
3830
  }
3134
3831
  /**
3135
3832
  * Add a conditional field that shows/hides based on form data
3136
3833
  */
3137
3834
  conditionalField(name, condition, field2) {
3138
- this.fields.push({
3835
+ const config = {
3139
3836
  condition,
3140
3837
  field: field2,
3141
3838
  name,
3142
3839
  type: "conditional"
3143
- });
3840
+ };
3841
+ this.fields.push(config);
3144
3842
  return this;
3145
3843
  }
3146
3844
  /**
3147
3845
  * Add a field array for dynamic repeating field groups
3148
3846
  */
3149
3847
  fieldArray(name, label, fields, options) {
3150
- this.fields.push({
3848
+ const config = {
3151
3849
  addButtonText: options?.addButtonText,
3152
3850
  fields,
3153
3851
  label,
@@ -3156,21 +3854,23 @@ var AdvancedFieldBuilder = class {
3156
3854
  name,
3157
3855
  removeButtonText: options?.removeButtonText,
3158
3856
  type: "fieldArray"
3159
- });
3857
+ };
3858
+ this.fields.push(config);
3160
3859
  return this;
3161
3860
  }
3162
3861
  /**
3163
3862
  * Add a dynamic section that shows/hides based on form data
3164
3863
  */
3165
3864
  dynamicSection(name, condition, fields, options) {
3166
- this.fields.push({
3865
+ const config = {
3167
3866
  condition,
3168
3867
  description: options?.description,
3169
3868
  fields,
3170
3869
  name,
3171
3870
  title: options?.title,
3172
3871
  type: "dynamicSection"
3173
- });
3872
+ };
3873
+ this.fields.push(config);
3174
3874
  return this;
3175
3875
  }
3176
3876
  /**
@@ -3184,8 +3884,11 @@ var FieldArrayItemBuilder = class {
3184
3884
  constructor() {
3185
3885
  this.fields = [];
3186
3886
  }
3187
- field(type, name, label, optionsOrProps, props) {
3188
- this.fields.push(createField(type, name, label, optionsOrProps, props));
3887
+ /**
3888
+ * Add any field type using the unified API for array items
3889
+ */
3890
+ field(params) {
3891
+ this.fields.push(createField(params));
3189
3892
  return this;
3190
3893
  }
3191
3894
  /**
@@ -3203,15 +3906,12 @@ var FieldArrayBuilder = class {
3203
3906
  this.arrayName = arrayName;
3204
3907
  this.fields = [];
3205
3908
  }
3206
- field(type, name, label, optionsOrProps, props) {
3207
- const fullPath = `${this.arrayName}.${name}`;
3208
- const fieldConfig = createField(
3209
- type,
3210
- fullPath,
3211
- label,
3212
- optionsOrProps,
3213
- props
3214
- );
3909
+ field(params) {
3910
+ const fullPath = `${this.arrayName}.${params.name}`;
3911
+ const fieldConfig = createField({
3912
+ ...params,
3913
+ name: fullPath
3914
+ });
3215
3915
  this.fields.push(fieldConfig);
3216
3916
  return this;
3217
3917
  }
@@ -3254,7 +3954,7 @@ var TypeInferredBuilder = class {
3254
3954
  new RegExp(pattern),
3255
3955
  `${label} format is invalid`
3256
3956
  );
3257
- this.schemaFields[name] = zodType;
3957
+ this.schemaFields[pathToString(name)] = zodType;
3258
3958
  this.formFields.push({
3259
3959
  inputProps: { type: "text", ...fieldOptions },
3260
3960
  label,
@@ -3267,7 +3967,7 @@ var TypeInferredBuilder = class {
3267
3967
  * Add an email field
3268
3968
  */
3269
3969
  email(name, label, options) {
3270
- this.schemaFields[name] = z3.string().email(`Please enter a valid email address`);
3970
+ this.schemaFields[pathToString(name)] = z3.string().email(`Please enter a valid email address`);
3271
3971
  this.formFields.push({
3272
3972
  inputProps: { type: "email", ...options },
3273
3973
  label,
@@ -3286,7 +3986,7 @@ var TypeInferredBuilder = class {
3286
3986
  zodType = zodType.min(min, `${label} must be at least ${min}`);
3287
3987
  if (max !== void 0)
3288
3988
  zodType = zodType.max(max, `${label} must be no more than ${max}`);
3289
- this.schemaFields[name] = zodType;
3989
+ this.schemaFields[pathToString(name)] = zodType;
3290
3990
  this.formFields.push({
3291
3991
  inputProps: { max, min, step, type: "number", ...fieldOptions },
3292
3992
  label,
@@ -3306,7 +4006,7 @@ var TypeInferredBuilder = class {
3306
4006
  minLength,
3307
4007
  `${label} must be at least ${minLength} characters`
3308
4008
  );
3309
- this.schemaFields[name] = zodType;
4009
+ this.schemaFields[pathToString(name)] = zodType;
3310
4010
  this.formFields.push({
3311
4011
  label,
3312
4012
  name,
@@ -3319,7 +4019,7 @@ var TypeInferredBuilder = class {
3319
4019
  * Add a select field
3320
4020
  */
3321
4021
  select(name, label, options) {
3322
- this.schemaFields[name] = z3.string().min(1, `Please select a ${label.toLowerCase()}`);
4022
+ this.schemaFields[pathToString(name)] = z3.string().min(1, `Please select a ${label.toLowerCase()}`);
3323
4023
  this.formFields.push({
3324
4024
  label,
3325
4025
  name,
@@ -3340,7 +4040,7 @@ var TypeInferredBuilder = class {
3340
4040
  `You must agree to ${label.toLowerCase()}`
3341
4041
  );
3342
4042
  }
3343
- this.schemaFields[name] = zodType;
4043
+ this.schemaFields[pathToString(name)] = zodType;
3344
4044
  this.formFields.push({
3345
4045
  checkboxProps: fieldOptions,
3346
4046
  label,
@@ -3353,7 +4053,7 @@ var TypeInferredBuilder = class {
3353
4053
  * Add a switch field
3354
4054
  */
3355
4055
  switch(name, label, options) {
3356
- this.schemaFields[name] = z3.boolean().optional();
4056
+ this.schemaFields[pathToString(name)] = z3.boolean().optional();
3357
4057
  this.formFields.push({
3358
4058
  label,
3359
4059
  name,
@@ -3366,7 +4066,7 @@ var TypeInferredBuilder = class {
3366
4066
  * Add a radio field
3367
4067
  */
3368
4068
  radio(name, label, options, fieldOptions) {
3369
- this.schemaFields[name] = z3.string().min(1, `Please select a ${label.toLowerCase()}`);
4069
+ this.schemaFields[pathToString(name)] = z3.string().min(1, `Please select a ${label.toLowerCase()}`);
3370
4070
  this.formFields.push({
3371
4071
  label,
3372
4072
  name,
@@ -3386,15 +4086,19 @@ var TypeInferredBuilder = class {
3386
4086
  zodType = zodType.min(min, `${label} must be at least ${min}`);
3387
4087
  if (max !== void 0)
3388
4088
  zodType = zodType.max(max, `${label} must be no more than ${max}`);
3389
- this.schemaFields[name] = zodType;
4089
+ this.schemaFields[pathToString(name)] = zodType;
4090
+ const { className, description, isDisabled, ...validSliderProps } = fieldOptions || {};
3390
4091
  this.formFields.push({
4092
+ className,
4093
+ description,
4094
+ isDisabled,
3391
4095
  label,
3392
4096
  name,
3393
4097
  sliderProps: {
3394
4098
  maxValue: max,
3395
4099
  minValue: min,
3396
4100
  step,
3397
- ...fieldOptions
4101
+ ...validSliderProps
3398
4102
  },
3399
4103
  type: "slider"
3400
4104
  });
@@ -3404,7 +4108,7 @@ var TypeInferredBuilder = class {
3404
4108
  * Add a date field
3405
4109
  */
3406
4110
  date(name, label, options) {
3407
- this.schemaFields[name] = z3.string().min(1, `${label} is required`);
4111
+ this.schemaFields[pathToString(name)] = z3.string().min(1, `${label} is required`);
3408
4112
  this.formFields.push({
3409
4113
  dateProps: options,
3410
4114
  label,
@@ -3417,7 +4121,7 @@ var TypeInferredBuilder = class {
3417
4121
  * Add a file field
3418
4122
  */
3419
4123
  file(name, label, options) {
3420
- this.schemaFields[name] = z3.any().optional();
4124
+ this.schemaFields[pathToString(name)] = z3.any().optional();
3421
4125
  this.formFields.push({
3422
4126
  fileProps: options,
3423
4127
  label,
@@ -3494,11 +4198,18 @@ var field = {
3494
4198
  // src/builders/NestedPathBuilder.ts
3495
4199
  var NestedPathBuilder = class {
3496
4200
  constructor() {
4201
+ // fields is accessed by nested builder classes, so it needs to be accessible
4202
+ // Making it public allows nested builders to add fields while maintaining encapsulation
3497
4203
  this.fields = [];
3498
4204
  }
3499
4205
  /**
3500
4206
  * Create a nested object path builder
3501
4207
  * Usage: builder.nest("address").field("street", "Street Address")
4208
+ *
4209
+ * @param path - A path in the form data structure. When called from root level,
4210
+ * accepts Path<T>. When called after .end() from a nested context,
4211
+ * accepts any string for nested paths under sections.
4212
+ * @returns A builder for nested paths under the specified path
3502
4213
  */
3503
4214
  nest(path) {
3504
4215
  return new NestedObjectBuilder(this, path);
@@ -3512,29 +4223,18 @@ var NestedPathBuilder = class {
3512
4223
  }
3513
4224
  /**
3514
4225
  * Add a field with single path
3515
- * Usage: builder.field("firstName", "First Name")
4226
+ * Usage: builder.field({ type: "input", name: "firstName", label: "First Name" })
3516
4227
  */
3517
- field(name, label, type = "input", props) {
3518
- this.fields.push({
3519
- label,
3520
- name,
3521
- type,
3522
- ...props
3523
- });
4228
+ field(params) {
4229
+ this.fields.push(createField(params));
3524
4230
  return this;
3525
4231
  }
3526
4232
  /**
3527
4233
  * Add a field with path segments
3528
- * Usage: builder.fieldPath(["user", "profile", "name"], "Full Name")
4234
+ * Usage: builder.fieldPath({ type: "input", name: path.join("."), label: "Full Name" })
3529
4235
  */
3530
- fieldPath(path, label, type = "input", props) {
3531
- const name = path.join(".");
3532
- this.fields.push({
3533
- label,
3534
- name,
3535
- type,
3536
- ...props
3537
- });
4236
+ fieldPath(params) {
4237
+ this.fields.push(createField(params));
3538
4238
  return this;
3539
4239
  }
3540
4240
  /**
@@ -3563,23 +4263,28 @@ var NestedObjectBuilder = class _NestedObjectBuilder {
3563
4263
  /**
3564
4264
  * Add a field to the current nested path
3565
4265
  */
3566
- field(fieldName, label, type = "input", props) {
3567
- const fullPath = `${this.path}.${fieldName}`;
3568
- this.parent.fields.push({
3569
- label,
3570
- name: fullPath,
3571
- type,
3572
- ...props
3573
- });
4266
+ field(params) {
4267
+ const fullPath = typeof params.name === "string" ? `${this.path}.${params.name}` : params.name;
4268
+ const fieldParams = {
4269
+ ...params,
4270
+ name: fullPath
4271
+ };
4272
+ this.parent.fields.push(createField(fieldParams));
3574
4273
  return this;
3575
4274
  }
3576
4275
  /**
3577
4276
  * Nest deeper into the object
4277
+ *
4278
+ * @param subPath - A string representing a nested path under the current path.
4279
+ * The parameter accepts any string; TypeScript validates the constructed
4280
+ * path (basePath.subPath) in the return type.
4281
+ * @returns A builder for the nested path
3578
4282
  */
3579
4283
  nest(subPath) {
4284
+ const fullPath = `${this.path}.${subPath}`;
3580
4285
  return new _NestedObjectBuilder(
3581
4286
  this.parent,
3582
- `${this.path}.${subPath}`
4287
+ fullPath
3583
4288
  );
3584
4289
  }
3585
4290
  /**
@@ -3597,14 +4302,13 @@ var SectionBuilder = class {
3597
4302
  /**
3598
4303
  * Add a field to the current section
3599
4304
  */
3600
- field(fieldName, label, type = "input", props) {
3601
- const fullPath = `${this.path}.${fieldName}`;
3602
- this.parent.fields.push({
3603
- label,
3604
- name: fullPath,
3605
- type,
3606
- ...props
3607
- });
4305
+ field(params) {
4306
+ const fullPath = typeof params.name === "string" ? `${this.path}.${params.name}` : params.name;
4307
+ const fieldParams = {
4308
+ ...params,
4309
+ name: fullPath
4310
+ };
4311
+ this.parent.fields.push(createField(fieldParams));
3608
4312
  return this;
3609
4313
  }
3610
4314
  /**
@@ -3612,17 +4316,29 @@ var SectionBuilder = class {
3612
4316
  */
3613
4317
  fields(fieldDefinitions) {
3614
4318
  fieldDefinitions.forEach((field2) => {
3615
- this.field(field2.name, field2.label, field2.type, field2.props);
4319
+ const fullPath = `${this.path}.${field2.name}`;
4320
+ this.parent.fields.push({
4321
+ label: field2.label,
4322
+ name: fullPath,
4323
+ type: field2.type || "input",
4324
+ ...field2.props
4325
+ });
3616
4326
  });
3617
4327
  return this;
3618
4328
  }
3619
4329
  /**
3620
4330
  * Nest deeper into the section
4331
+ *
4332
+ * @param subPath - A string representing a nested path under the current section path.
4333
+ * The parameter accepts any string; TypeScript validates the constructed
4334
+ * path (basePath.subPath) in the return type.
4335
+ * @returns A builder for the nested path
3621
4336
  */
3622
4337
  nest(subPath) {
4338
+ const fullPath = `${this.path}.${subPath}`;
3623
4339
  return new NestedObjectBuilder(
3624
4340
  this.parent,
3625
- `${this.path}.${subPath}`
4341
+ fullPath
3626
4342
  );
3627
4343
  }
3628
4344
  /**
@@ -3640,13 +4356,12 @@ var FieldTemplateBuilder = class {
3640
4356
  /**
3641
4357
  * Complete the field definition
3642
4358
  */
3643
- complete(label, type = "input", props) {
3644
- this.parent.fields.push({
3645
- label,
3646
- name: this.path,
3647
- type,
3648
- ...props
3649
- });
4359
+ complete(params) {
4360
+ const fieldParams = {
4361
+ ...params,
4362
+ name: params.name ? `${this.path}.${params.name}` : this.path
4363
+ };
4364
+ this.parent.fields.push(createField(fieldParams));
3650
4365
  return this.parent;
3651
4366
  }
3652
4367
  };
@@ -3904,7 +4619,7 @@ function syncArrays(options) {
3904
4619
  }
3905
4620
 
3906
4621
  // src/utils/createFieldArrayCustomConfig.tsx
3907
- import React25 from "react";
4622
+ import React27 from "react";
3908
4623
  import { useFieldArray as useFieldArray2 } from "react-hook-form";
3909
4624
  import { Button as Button6 } from "@heroui/react";
3910
4625
  function createFieldArrayCustomConfig(options) {
@@ -3923,11 +4638,12 @@ function createFieldArrayCustomConfig(options) {
3923
4638
  className,
3924
4639
  label,
3925
4640
  name,
3926
- // ArrayPath is compatible with Path for CustomFieldConfig
4641
+ // ArrayPath is now accepted by CustomFieldConfig
3927
4642
  render: ({ control, errors, form }) => {
3928
4643
  const { append, fields, move, remove } = useFieldArray2({
3929
4644
  control,
3930
4645
  name
4646
+ // ArrayPath is the correct type for useFieldArray
3931
4647
  });
3932
4648
  const canAdd = fields.length < max;
3933
4649
  const canRemove = fields.length > min;
@@ -3955,14 +4671,15 @@ function createFieldArrayCustomConfig(options) {
3955
4671
  move(index, index + 1);
3956
4672
  }
3957
4673
  };
3958
- return /* @__PURE__ */ React25.createElement("div", { className }, /* @__PURE__ */ React25.createElement("div", { className: "space-y-4" }, fields.map((field2, index) => {
4674
+ return /* @__PURE__ */ React27.createElement("div", { className }, /* @__PURE__ */ React27.createElement("div", { className: "space-y-4" }, fields.map((field2, index) => {
3959
4675
  const canMoveUp = enableReordering && index > 0;
3960
4676
  const canMoveDown = enableReordering && index < fields.length - 1;
3961
- return /* @__PURE__ */ React25.createElement(React25.Fragment, { key: field2.id }, renderItem({
4677
+ return /* @__PURE__ */ React27.createElement(React27.Fragment, { key: field2.id }, renderItem({
3962
4678
  canMoveDown,
3963
4679
  canMoveUp,
3964
4680
  control,
3965
4681
  errors,
4682
+ // fields from useFieldArray are already typed correctly
3966
4683
  field: field2,
3967
4684
  fields,
3968
4685
  form,
@@ -3971,7 +4688,7 @@ function createFieldArrayCustomConfig(options) {
3971
4688
  onMoveUp: () => handleMoveUp(index),
3972
4689
  onRemove: () => handleRemove(index)
3973
4690
  }));
3974
- }), fields.length === 0 && renderAddButton ? /* @__PURE__ */ React25.createElement("div", { className: "text-center py-8 text-gray-500" }, /* @__PURE__ */ React25.createElement("p", null, "No ", label?.toLowerCase() || "items", " added yet."), renderAddButton({ canAdd, onAdd: handleAdd })) : null, fields.length > 0 && renderAddButton ? renderAddButton({ canAdd, onAdd: handleAdd }) : canAdd && /* @__PURE__ */ React25.createElement(
4691
+ }), fields.length === 0 && renderAddButton ? /* @__PURE__ */ React27.createElement("div", { className: "text-center py-8 text-gray-500" }, /* @__PURE__ */ React27.createElement("p", null, "No ", label?.toLowerCase() || "items", " added yet."), renderAddButton({ canAdd, onAdd: handleAdd })) : null, fields.length > 0 && renderAddButton ? renderAddButton({ canAdd, onAdd: handleAdd }) : canAdd && /* @__PURE__ */ React27.createElement(
3975
4692
  Button6,
3976
4693
  {
3977
4694
  variant: "bordered",
@@ -4137,6 +4854,7 @@ export {
4137
4854
  AutocompleteField,
4138
4855
  BasicFormBuilder,
4139
4856
  CheckboxField,
4857
+ CheckboxGroupField,
4140
4858
  CommonFields,
4141
4859
  ConditionalField,
4142
4860
  ConfigurableForm,
@@ -4204,6 +4922,7 @@ export {
4204
4922
  getFormErrors,
4205
4923
  hasFieldError,
4206
4924
  hasFormErrors,
4925
+ pathToString,
4207
4926
  serverValidation,
4208
4927
  shallowEqual,
4209
4928
  simulateFieldInput,