@rachelallyson/hero-hook-form 2.0.0 → 2.1.1

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.
@@ -225,11 +225,11 @@ function CheckboxField(props) {
225
225
  import React3 from "react";
226
226
  import { useWatch, useFormContext } from "react-hook-form";
227
227
  function ConditionalField({
228
+ className,
228
229
  config,
229
- control,
230
- className
230
+ control
231
231
  }) {
232
- const { condition, field: field2, name } = config;
232
+ const { condition, field: field2 } = config;
233
233
  const form = useFormContext();
234
234
  const formValues = useWatch({ control });
235
235
  const shouldShow = condition(formValues);
@@ -242,10 +242,10 @@ function ConditionalField({
242
242
  config: field2,
243
243
  form,
244
244
  submissionState: {
245
- isSubmitting: false,
245
+ error: void 0,
246
246
  isSubmitted: false,
247
- isSuccess: false,
248
- error: void 0
247
+ isSubmitting: false,
248
+ isSuccess: false
249
249
  }
250
250
  }
251
251
  ));
@@ -313,11 +313,11 @@ function DateField(props) {
313
313
  import React5 from "react";
314
314
  import { useWatch as useWatch2, useFormContext as useFormContext2 } from "react-hook-form";
315
315
  function DynamicSectionField({
316
+ className,
316
317
  config,
317
- control,
318
- className
318
+ control
319
319
  }) {
320
- const { condition, fields, title, description } = config;
320
+ const { condition, description, fields, title } = config;
321
321
  const form = useFormContext2();
322
322
  const formValues = useWatch2({ control });
323
323
  const shouldShow = condition(formValues);
@@ -331,10 +331,10 @@ function DynamicSectionField({
331
331
  config: fieldConfig,
332
332
  form,
333
333
  submissionState: {
334
- isSubmitting: false,
334
+ error: void 0,
335
335
  isSubmitted: false,
336
- isSuccess: false,
337
- error: void 0
336
+ isSubmitting: false,
337
+ isSuccess: false
338
338
  }
339
339
  }
340
340
  ))));
@@ -345,15 +345,15 @@ import React6 from "react";
345
345
  import { useFieldArray, useFormContext as useFormContext3 } from "react-hook-form";
346
346
  import { Button as Button2 } from "@heroui/react";
347
347
  function FieldArrayField({
348
- config,
349
- className
348
+ className,
349
+ config
350
350
  }) {
351
351
  const {
352
- name,
352
+ addButtonText = "Add Item",
353
353
  fields: fieldConfigs,
354
- min = 0,
355
354
  max = 10,
356
- addButtonText = "Add Item",
355
+ min = 0,
356
+ name,
357
357
  removeButtonText = "Remove"
358
358
  } = config;
359
359
  const form = useFormContext3();
@@ -361,7 +361,7 @@ function FieldArrayField({
361
361
  return null;
362
362
  }
363
363
  const { control } = form;
364
- const { fields, append, remove } = useFieldArray({
364
+ const { append, fields, remove } = useFieldArray({
365
365
  control,
366
366
  name
367
367
  // FieldArray name
@@ -389,34 +389,42 @@ function FieldArrayField({
389
389
  remove(index);
390
390
  }
391
391
  };
392
- return /* @__PURE__ */ React6.createElement("div", { className }, /* @__PURE__ */ React6.createElement("div", { className: "space-y-4" }, fields.map((field2, index) => /* @__PURE__ */ React6.createElement("div", { key: field2.id, className: "border border-gray-200 rounded-lg p-4 space-y-4" }, /* @__PURE__ */ React6.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React6.createElement("h4", { className: "text-sm font-medium text-gray-700" }, config.label, " #", index + 1), canRemove && /* @__PURE__ */ React6.createElement(
393
- Button2,
392
+ return /* @__PURE__ */ React6.createElement("div", { className }, /* @__PURE__ */ React6.createElement("div", { className: "space-y-4" }, fields.map((field2, index) => /* @__PURE__ */ React6.createElement(
393
+ "div",
394
394
  {
395
- size: "sm",
396
- variant: "light",
397
- color: "danger",
398
- startContent: "\u{1F5D1}\uFE0F",
399
- onPress: () => handleRemove(index),
400
- "aria-label": `${removeButtonText} ${config.label} ${index + 1}`
395
+ key: field2.id,
396
+ className: "border border-gray-200 rounded-lg p-4 space-y-4"
401
397
  },
402
- removeButtonText
403
- )), /* @__PURE__ */ React6.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, fieldConfigs.map((fieldConfig) => /* @__PURE__ */ React6.createElement(
404
- FormField,
405
- {
406
- key: `${fieldConfig.name}-${index}`,
407
- config: {
408
- ...fieldConfig,
409
- name: `${name}.${index}.${fieldConfig.name}`
398
+ /* @__PURE__ */ React6.createElement("div", { className: "flex justify-between items-center" }, /* @__PURE__ */ React6.createElement("h4", { className: "text-sm font-medium text-gray-700" }, config.label, " #", index + 1), canRemove && /* @__PURE__ */ React6.createElement(
399
+ Button2,
400
+ {
401
+ size: "sm",
402
+ variant: "light",
403
+ color: "danger",
404
+ startContent: "\u{1F5D1}\uFE0F",
405
+ onPress: () => handleRemove(index),
406
+ "aria-label": `${removeButtonText} ${config.label} ${index + 1}`
410
407
  },
411
- form,
412
- submissionState: {
413
- isSubmitting: false,
414
- isSubmitted: false,
415
- isSuccess: false,
416
- error: void 0
408
+ removeButtonText
409
+ )),
410
+ /* @__PURE__ */ React6.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4" }, fieldConfigs.map((fieldConfig) => /* @__PURE__ */ React6.createElement(
411
+ FormField,
412
+ {
413
+ key: `${fieldConfig.name}-${index}`,
414
+ config: {
415
+ ...fieldConfig,
416
+ name: `${name}.${index}.${fieldConfig.name}`
417
+ },
418
+ form,
419
+ submissionState: {
420
+ error: void 0,
421
+ isSubmitted: false,
422
+ isSubmitting: false,
423
+ isSuccess: false
424
+ }
417
425
  }
418
- }
419
- ))))), canAdd && /* @__PURE__ */ React6.createElement(
426
+ )))
427
+ )), canAdd && /* @__PURE__ */ React6.createElement(
420
428
  Button2,
421
429
  {
422
430
  variant: "bordered",
@@ -534,15 +542,15 @@ function FontPickerField(props) {
534
542
  } = props;
535
543
  const [fontPickerState, setFontPickerState] = React8.useState({
536
544
  component: FontPickerComponent,
537
- loading: false,
538
- error: null
545
+ error: null,
546
+ loading: false
539
547
  });
540
548
  React8.useEffect(() => {
541
549
  if (fontPickerLoaded && FontPickerComponent) {
542
550
  setFontPickerState({
543
551
  component: FontPickerComponent,
544
- loading: false,
545
- error: null
552
+ error: null,
553
+ loading: false
546
554
  });
547
555
  return;
548
556
  }
@@ -552,14 +560,14 @@ function FontPickerField(props) {
552
560
  if (fontPickerLoaded && FontPickerComponent) {
553
561
  setFontPickerState({
554
562
  component: FontPickerComponent,
555
- loading: false,
556
- error: null
563
+ error: null,
564
+ loading: false
557
565
  });
558
566
  } else {
559
567
  setFontPickerState({
560
568
  component: null,
561
- loading: false,
562
- error: "Font picker package not found"
569
+ error: "Font picker package not found",
570
+ loading: false
563
571
  });
564
572
  }
565
573
  };
@@ -576,17 +584,17 @@ function FontPickerField(props) {
576
584
  fontPickerLoading = false;
577
585
  setFontPickerState({
578
586
  component: FontPickerComponent,
579
- loading: false,
580
- error: null
587
+ error: null,
588
+ loading: false
581
589
  });
582
590
  loadingCallbacks.forEach((callback) => callback());
583
591
  loadingCallbacks.length = 0;
584
- } catch (error) {
592
+ } catch {
585
593
  fontPickerLoading = false;
586
594
  setFontPickerState({
587
595
  component: null,
588
- loading: false,
589
- error: "Font picker package not found"
596
+ error: "Font picker package not found",
597
+ loading: false
590
598
  });
591
599
  loadingCallbacks.forEach((callback) => callback());
592
600
  loadingCallbacks.length = 0;
@@ -645,50 +653,52 @@ function CoercedInput(props) {
645
653
  }
646
654
  );
647
655
  }
648
- var InputField = React9.memo((props) => {
649
- const {
650
- className,
651
- control,
652
- description,
653
- inputProps,
654
- isDisabled,
655
- label,
656
- name,
657
- rules,
658
- transform
659
- } = props;
660
- return /* @__PURE__ */ React9.createElement(
661
- Controller5,
662
- {
656
+ var InputField = React9.memo(
657
+ (props) => {
658
+ const {
659
+ className,
663
660
  control,
661
+ description,
662
+ inputProps,
663
+ isDisabled,
664
+ label,
664
665
  name,
665
- render: ({ field: field2, fieldState }) => /* @__PURE__ */ React9.createElement("div", { className }, /* @__PURE__ */ React9.createElement(
666
- CoercedInput,
667
- {
668
- description,
669
- disabled: isDisabled,
670
- errorMessage: fieldState.error?.message,
671
- field: {
672
- ...field2,
673
- onChange: (value) => {
674
- if (inputProps?.type === "number") {
675
- const numValue = value === "" ? void 0 : Number(value);
676
- field2.onChange(
677
- transform ? transform(String(numValue)) : numValue
678
- );
679
- } else {
680
- field2.onChange(transform ? transform(value) : value);
666
+ rules,
667
+ transform
668
+ } = props;
669
+ return /* @__PURE__ */ React9.createElement(
670
+ Controller5,
671
+ {
672
+ control,
673
+ name,
674
+ render: ({ field: field2, fieldState }) => /* @__PURE__ */ React9.createElement("div", { className }, /* @__PURE__ */ React9.createElement(
675
+ CoercedInput,
676
+ {
677
+ description,
678
+ disabled: isDisabled,
679
+ errorMessage: fieldState.error?.message,
680
+ field: {
681
+ ...field2,
682
+ onChange: (value) => {
683
+ if (inputProps?.type === "number") {
684
+ const numValue = value === "" ? void 0 : Number(value);
685
+ field2.onChange(
686
+ transform ? transform(String(numValue)) : numValue
687
+ );
688
+ } else {
689
+ field2.onChange(transform ? transform(value) : value);
690
+ }
681
691
  }
682
- }
683
- },
684
- inputProps,
685
- label
686
- }
687
- )),
688
- rules
689
- }
690
- );
691
- });
692
+ },
693
+ inputProps,
694
+ label
695
+ }
696
+ )),
697
+ rules
698
+ }
699
+ );
700
+ }
701
+ );
692
702
 
693
703
  // src/fields/RadioGroupField.tsx
694
704
  import React10 from "react";
@@ -933,187 +943,189 @@ function TextareaField(props) {
933
943
  }
934
944
 
935
945
  // src/components/FormField.tsx
936
- var FormField = React15.memo(({
937
- config,
938
- form,
939
- submissionState
940
- }) => {
941
- if (!form || !form.control) {
942
- return null;
943
- }
944
- const { control } = form;
945
- const watchedValues = useWatch3({ control });
946
- if (config.condition && !config.condition(watchedValues)) {
947
- return null;
948
- }
949
- if (config.dependsOn) {
950
- const dependentValue = watchedValues[config.dependsOn];
951
- if (config.dependsOnValue !== void 0 && dependentValue !== config.dependsOnValue) {
946
+ var FormField = React15.memo(
947
+ ({
948
+ config,
949
+ form,
950
+ submissionState
951
+ }) => {
952
+ if (!form || !form.control) {
952
953
  return null;
953
954
  }
954
- }
955
- const baseProps = {
956
- ariaDescribedBy: config.ariaDescribedBy,
957
- ariaLabel: config.ariaLabel,
958
- className: config.className,
959
- description: config.description,
960
- isDisabled: config.isDisabled ?? submissionState.isSubmitting,
961
- label: config.label,
962
- name: config.name,
963
- rules: config.rules
964
- };
965
- switch (config.type) {
966
- case "input":
967
- return /* @__PURE__ */ React15.createElement(
968
- InputField,
969
- {
970
- ...baseProps,
971
- control,
972
- defaultValue: config.defaultValue,
973
- inputProps: config.inputProps
974
- }
975
- );
976
- case "textarea":
977
- return /* @__PURE__ */ React15.createElement(
978
- TextareaField,
979
- {
980
- ...baseProps,
981
- control,
982
- defaultValue: config.defaultValue,
983
- textareaProps: config.textareaProps
984
- }
985
- );
986
- case "select":
987
- return /* @__PURE__ */ React15.createElement(
988
- SelectField,
989
- {
990
- ...baseProps,
991
- control,
992
- defaultValue: config.defaultValue,
993
- options: (config.options ?? []).map((opt) => ({
994
- label: opt.label,
995
- value: String(opt.value)
996
- })),
997
- selectProps: config.selectProps
998
- }
999
- );
1000
- case "checkbox":
1001
- return /* @__PURE__ */ React15.createElement(
1002
- CheckboxField,
1003
- {
1004
- ...baseProps,
1005
- checkboxProps: config.checkboxProps,
1006
- control,
1007
- defaultValue: config.defaultValue
1008
- }
1009
- );
1010
- case "radio":
1011
- return /* @__PURE__ */ React15.createElement(
1012
- RadioGroupField,
1013
- {
1014
- ...baseProps,
1015
- control,
1016
- defaultValue: config.defaultValue,
1017
- options: (config.radioOptions ?? []).map((opt) => ({
1018
- label: opt.label,
1019
- value: String(opt.value)
1020
- })),
1021
- radioGroupProps: config.radioProps
1022
- }
1023
- );
1024
- case "switch":
1025
- return /* @__PURE__ */ React15.createElement(
1026
- SwitchField,
1027
- {
1028
- ...baseProps,
1029
- control,
1030
- defaultValue: config.defaultValue,
1031
- switchProps: config.switchProps
1032
- }
1033
- );
1034
- case "slider":
1035
- return /* @__PURE__ */ React15.createElement(
1036
- SliderField,
1037
- {
1038
- ...baseProps,
1039
- control,
1040
- defaultValue: config.defaultValue,
1041
- sliderProps: config.sliderProps
1042
- }
1043
- );
1044
- case "date":
1045
- return /* @__PURE__ */ React15.createElement(
1046
- DateField,
1047
- {
1048
- ...baseProps,
1049
- control,
1050
- dateProps: config.dateProps,
1051
- defaultValue: config.defaultValue
1052
- }
1053
- );
1054
- case "file":
1055
- return /* @__PURE__ */ React15.createElement(
1056
- FileField,
1057
- {
1058
- ...baseProps,
1059
- accept: config.accept,
1060
- control,
1061
- defaultValue: config.defaultValue,
1062
- fileProps: config.fileProps,
1063
- multiple: config.multiple
1064
- }
1065
- );
1066
- case "fontPicker":
1067
- return /* @__PURE__ */ React15.createElement(
1068
- FontPickerField,
1069
- {
1070
- ...baseProps,
1071
- control,
1072
- defaultValue: config.defaultValue,
1073
- fontPickerProps: config.fontPickerProps
1074
- }
1075
- );
1076
- case "custom":
1077
- return config.render({
1078
- control,
1079
- errors: form.formState.errors,
1080
- form,
1081
- isSubmitting: submissionState.isSubmitting,
1082
- name: config.name
1083
- });
1084
- case "conditional":
1085
- return /* @__PURE__ */ React15.createElement(
1086
- ConditionalField,
1087
- {
1088
- config,
1089
- control,
1090
- className: config.className
1091
- }
1092
- );
1093
- case "fieldArray":
1094
- return /* @__PURE__ */ React15.createElement(
1095
- FieldArrayField,
1096
- {
1097
- config,
1098
- className: config.className
1099
- }
1100
- );
1101
- case "dynamicSection":
1102
- return /* @__PURE__ */ React15.createElement(
1103
- DynamicSectionField,
1104
- {
1105
- config,
1106
- control,
1107
- className: config.className
1108
- }
1109
- );
1110
- default: {
1111
- const fieldType = config.type;
1112
- console.warn(`Unknown field type: ${fieldType}`);
955
+ const { control } = form;
956
+ const watchedValues = useWatch3({ control });
957
+ if (config.condition && !config.condition(watchedValues)) {
1113
958
  return null;
1114
959
  }
960
+ if (config.dependsOn) {
961
+ const dependentValue = watchedValues[config.dependsOn];
962
+ if (config.dependsOnValue !== void 0 && dependentValue !== config.dependsOnValue) {
963
+ return null;
964
+ }
965
+ }
966
+ const baseProps = {
967
+ ariaDescribedBy: config.ariaDescribedBy,
968
+ ariaLabel: config.ariaLabel,
969
+ className: config.className,
970
+ description: config.description,
971
+ isDisabled: config.isDisabled ?? submissionState.isSubmitting,
972
+ label: config.label,
973
+ name: config.name,
974
+ rules: config.rules
975
+ };
976
+ switch (config.type) {
977
+ case "input":
978
+ return /* @__PURE__ */ React15.createElement(
979
+ InputField,
980
+ {
981
+ ...baseProps,
982
+ control,
983
+ defaultValue: config.defaultValue,
984
+ inputProps: config.inputProps
985
+ }
986
+ );
987
+ case "textarea":
988
+ return /* @__PURE__ */ React15.createElement(
989
+ TextareaField,
990
+ {
991
+ ...baseProps,
992
+ control,
993
+ defaultValue: config.defaultValue,
994
+ textareaProps: config.textareaProps
995
+ }
996
+ );
997
+ case "select":
998
+ return /* @__PURE__ */ React15.createElement(
999
+ SelectField,
1000
+ {
1001
+ ...baseProps,
1002
+ control,
1003
+ defaultValue: config.defaultValue,
1004
+ options: (config.options ?? []).map((opt) => ({
1005
+ label: opt.label,
1006
+ value: String(opt.value)
1007
+ })),
1008
+ selectProps: config.selectProps
1009
+ }
1010
+ );
1011
+ case "checkbox":
1012
+ return /* @__PURE__ */ React15.createElement(
1013
+ CheckboxField,
1014
+ {
1015
+ ...baseProps,
1016
+ checkboxProps: config.checkboxProps,
1017
+ control,
1018
+ defaultValue: config.defaultValue
1019
+ }
1020
+ );
1021
+ case "radio":
1022
+ return /* @__PURE__ */ React15.createElement(
1023
+ RadioGroupField,
1024
+ {
1025
+ ...baseProps,
1026
+ control,
1027
+ defaultValue: config.defaultValue,
1028
+ options: (config.radioOptions ?? []).map((opt) => ({
1029
+ label: opt.label,
1030
+ value: String(opt.value)
1031
+ })),
1032
+ radioGroupProps: config.radioProps
1033
+ }
1034
+ );
1035
+ case "switch":
1036
+ return /* @__PURE__ */ React15.createElement(
1037
+ SwitchField,
1038
+ {
1039
+ ...baseProps,
1040
+ control,
1041
+ defaultValue: config.defaultValue,
1042
+ switchProps: config.switchProps
1043
+ }
1044
+ );
1045
+ case "slider":
1046
+ return /* @__PURE__ */ React15.createElement(
1047
+ SliderField,
1048
+ {
1049
+ ...baseProps,
1050
+ control,
1051
+ defaultValue: config.defaultValue,
1052
+ sliderProps: config.sliderProps
1053
+ }
1054
+ );
1055
+ case "date":
1056
+ return /* @__PURE__ */ React15.createElement(
1057
+ DateField,
1058
+ {
1059
+ ...baseProps,
1060
+ control,
1061
+ dateProps: config.dateProps,
1062
+ defaultValue: config.defaultValue
1063
+ }
1064
+ );
1065
+ case "file":
1066
+ return /* @__PURE__ */ React15.createElement(
1067
+ FileField,
1068
+ {
1069
+ ...baseProps,
1070
+ accept: config.accept,
1071
+ control,
1072
+ defaultValue: config.defaultValue,
1073
+ fileProps: config.fileProps,
1074
+ multiple: config.multiple
1075
+ }
1076
+ );
1077
+ case "fontPicker":
1078
+ return /* @__PURE__ */ React15.createElement(
1079
+ FontPickerField,
1080
+ {
1081
+ ...baseProps,
1082
+ control,
1083
+ defaultValue: config.defaultValue,
1084
+ fontPickerProps: config.fontPickerProps
1085
+ }
1086
+ );
1087
+ case "custom":
1088
+ return config.render({
1089
+ control,
1090
+ errors: form.formState.errors,
1091
+ form,
1092
+ isSubmitting: submissionState.isSubmitting,
1093
+ name: config.name
1094
+ });
1095
+ case "conditional":
1096
+ return /* @__PURE__ */ React15.createElement(
1097
+ ConditionalField,
1098
+ {
1099
+ config,
1100
+ control,
1101
+ className: config.className
1102
+ }
1103
+ );
1104
+ case "fieldArray":
1105
+ return /* @__PURE__ */ React15.createElement(
1106
+ FieldArrayField,
1107
+ {
1108
+ config,
1109
+ className: config.className
1110
+ }
1111
+ );
1112
+ case "dynamicSection":
1113
+ return /* @__PURE__ */ React15.createElement(
1114
+ DynamicSectionField,
1115
+ {
1116
+ config,
1117
+ control,
1118
+ className: config.className
1119
+ }
1120
+ );
1121
+ default: {
1122
+ const fieldType = config.type;
1123
+ console.warn(`Unknown field type: ${fieldType}`);
1124
+ return null;
1125
+ }
1126
+ }
1115
1127
  }
1116
- });
1128
+ );
1117
1129
 
1118
1130
  // src/components/Form.tsx
1119
1131
  function ConfigurableForm({
@@ -1229,6 +1241,326 @@ function ConfigurableForm({
1229
1241
  )));
1230
1242
  }
1231
1243
 
1244
+ // src/components/ServerActionForm.tsx
1245
+ import React17 from "react";
1246
+ import { useActionState } from "react";
1247
+ function ServerActionForm({
1248
+ action,
1249
+ className,
1250
+ clientValidationSchema,
1251
+ columns = 1,
1252
+ defaultValues,
1253
+ fields,
1254
+ initialState,
1255
+ layout = "vertical",
1256
+ onError,
1257
+ onSuccess,
1258
+ resetButtonText = "Reset",
1259
+ showResetButton = false,
1260
+ spacing = "4",
1261
+ submitButtonProps = {},
1262
+ submitButtonText = "Submit",
1263
+ subtitle,
1264
+ title
1265
+ }) {
1266
+ const [state, formAction, pending] = useActionState(
1267
+ action,
1268
+ initialState ?? { errors: void 0, message: void 0, success: false }
1269
+ );
1270
+ const formRef = React17.useRef(null);
1271
+ const [clientErrors, setClientErrors] = React17.useState({});
1272
+ const lastSubmittedFormData = React17.useRef(null);
1273
+ React17.useEffect(() => {
1274
+ if (state && (state.errors || state.message && !state.success)) {
1275
+ onError?.({
1276
+ errors: state.errors,
1277
+ message: state.message
1278
+ });
1279
+ }
1280
+ }, [state, onError]);
1281
+ React17.useEffect(() => {
1282
+ if (state?.success && lastSubmittedFormData.current) {
1283
+ onSuccess?.(lastSubmittedFormData.current);
1284
+ }
1285
+ }, [state?.success, onSuccess]);
1286
+ const handleReset = () => {
1287
+ formRef.current?.reset();
1288
+ setClientErrors({});
1289
+ };
1290
+ const handleSubmit = async (e) => {
1291
+ e.preventDefault();
1292
+ if (clientValidationSchema) {
1293
+ const formData2 = new FormData(e.currentTarget);
1294
+ const values = {};
1295
+ formData2.forEach((val, key) => {
1296
+ if (val === "on") {
1297
+ values[key] = true;
1298
+ } else if (val === "") {
1299
+ if (!values[key]) {
1300
+ values[key] = false;
1301
+ }
1302
+ } else {
1303
+ values[key] = val;
1304
+ }
1305
+ });
1306
+ const result = clientValidationSchema.safeParse(values);
1307
+ if (!result.success) {
1308
+ const errors = {};
1309
+ result.error.issues.forEach((issue) => {
1310
+ const path = issue.path.join(".");
1311
+ errors[path] = issue.message;
1312
+ });
1313
+ setClientErrors((prev) => ({ ...prev, ...errors }));
1314
+ return;
1315
+ }
1316
+ setClientErrors({});
1317
+ }
1318
+ const formData = new FormData(e.currentTarget);
1319
+ lastSubmittedFormData.current = formData;
1320
+ formAction(formData);
1321
+ };
1322
+ const renderFields = () => {
1323
+ if (layout === "grid") {
1324
+ return /* @__PURE__ */ React17.createElement(
1325
+ "div",
1326
+ {
1327
+ 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"}`
1328
+ },
1329
+ fields.map((field2) => /* @__PURE__ */ React17.createElement(
1330
+ ServerActionField,
1331
+ {
1332
+ key: field2.name,
1333
+ clientErrors,
1334
+ defaultValues,
1335
+ errors: state?.errors,
1336
+ field: field2
1337
+ }
1338
+ ))
1339
+ );
1340
+ }
1341
+ if (layout === "horizontal") {
1342
+ return /* @__PURE__ */ React17.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, fields.map((field2) => /* @__PURE__ */ React17.createElement(
1343
+ ServerActionField,
1344
+ {
1345
+ key: field2.name,
1346
+ clientErrors,
1347
+ defaultValues,
1348
+ errors: state?.errors,
1349
+ field: field2
1350
+ }
1351
+ )));
1352
+ }
1353
+ return /* @__PURE__ */ React17.createElement("div", { className: `space-y-${spacing}` }, fields.map((field2) => /* @__PURE__ */ React17.createElement(
1354
+ ServerActionField,
1355
+ {
1356
+ key: field2.name,
1357
+ clientErrors,
1358
+ defaultValues,
1359
+ errors: state?.errors,
1360
+ field: field2
1361
+ }
1362
+ )));
1363
+ };
1364
+ return /* @__PURE__ */ React17.createElement(
1365
+ "form",
1366
+ {
1367
+ ref: formRef,
1368
+ className,
1369
+ role: "form",
1370
+ onSubmit: handleSubmit
1371
+ },
1372
+ title && /* @__PURE__ */ React17.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React17.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ React17.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)),
1373
+ state?.success && !pending && /* @__PURE__ */ React17.createElement(
1374
+ "div",
1375
+ {
1376
+ className: "mb-6 p-4 bg-success-50 border border-success-200 rounded-lg",
1377
+ "data-testid": "success-message"
1378
+ },
1379
+ /* @__PURE__ */ React17.createElement("p", { className: "text-success-800 font-medium" }, "Success!"),
1380
+ state.message && /* @__PURE__ */ React17.createElement("p", { className: "text-success-700 text-sm mt-1" }, state.message)
1381
+ ),
1382
+ state?.message && !state.success && /* @__PURE__ */ React17.createElement(
1383
+ "div",
1384
+ {
1385
+ className: "mb-6 p-4 bg-danger-50 border border-danger-200 rounded-lg",
1386
+ "data-testid": "error-message"
1387
+ },
1388
+ /* @__PURE__ */ React17.createElement("p", { className: "text-danger-800 font-medium" }, "Error"),
1389
+ /* @__PURE__ */ React17.createElement("p", { className: "text-danger-700 text-sm mt-1" }, state.message)
1390
+ ),
1391
+ renderFields(),
1392
+ /* @__PURE__ */ React17.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React17.createElement(
1393
+ Button,
1394
+ {
1395
+ color: "primary",
1396
+ isDisabled: pending,
1397
+ isLoading: pending,
1398
+ type: "submit",
1399
+ ...submitButtonProps
1400
+ },
1401
+ submitButtonText
1402
+ ), showResetButton && /* @__PURE__ */ React17.createElement(
1403
+ Button,
1404
+ {
1405
+ isDisabled: pending,
1406
+ type: "button",
1407
+ variant: "bordered",
1408
+ onPress: handleReset
1409
+ },
1410
+ resetButtonText
1411
+ ))
1412
+ );
1413
+ }
1414
+ function ServerActionField({
1415
+ clientErrors,
1416
+ defaultValues,
1417
+ errors,
1418
+ field: field2
1419
+ }) {
1420
+ const fieldName = field2.name;
1421
+ const fieldErrors = errors?.[fieldName];
1422
+ const clientError = clientErrors?.[fieldName];
1423
+ const errorMessage = clientError || (fieldErrors && fieldErrors.length > 0 ? fieldErrors[0] : void 0);
1424
+ const getDefaultValue = () => {
1425
+ const fromProps = defaultValues?.[fieldName];
1426
+ const fromField = field2.defaultValue;
1427
+ if (fromProps !== void 0 && fromProps !== null) {
1428
+ return typeof fromProps === "string" ? fromProps : String(fromProps);
1429
+ }
1430
+ if (fromField !== void 0 && fromField !== null) {
1431
+ return typeof fromField === "string" ? fromField : String(fromField);
1432
+ }
1433
+ return "";
1434
+ };
1435
+ const getDefaultChecked = () => {
1436
+ const fromProps = defaultValues?.[fieldName];
1437
+ const fromField = field2.defaultValue;
1438
+ if (fromProps !== void 0 && fromProps !== null) {
1439
+ return typeof fromProps === "boolean" ? fromProps : false;
1440
+ }
1441
+ if (fromField !== void 0 && fromField !== null) {
1442
+ return typeof fromField === "boolean" ? fromField : false;
1443
+ }
1444
+ return false;
1445
+ };
1446
+ const [value, setValue] = React17.useState(getDefaultValue);
1447
+ const [checked, setChecked] = React17.useState(getDefaultChecked);
1448
+ React17.useEffect(() => {
1449
+ const newDefaultValue = defaultValues?.[fieldName];
1450
+ if (newDefaultValue !== void 0 && newDefaultValue !== null) {
1451
+ if (field2.type === "checkbox") {
1452
+ setChecked(
1453
+ typeof newDefaultValue === "boolean" ? newDefaultValue : false
1454
+ );
1455
+ } else {
1456
+ setValue(
1457
+ typeof newDefaultValue === "string" ? newDefaultValue : String(newDefaultValue)
1458
+ );
1459
+ }
1460
+ }
1461
+ }, [defaultValues, fieldName, field2.type]);
1462
+ React17.useEffect(() => {
1463
+ const hiddenInput = document.querySelector(
1464
+ `input[type="hidden"][name="${fieldName}"]`
1465
+ );
1466
+ if (hiddenInput) {
1467
+ if (field2.type === "checkbox") {
1468
+ hiddenInput.value = checked ? "on" : "";
1469
+ } else {
1470
+ hiddenInput.value = value;
1471
+ }
1472
+ }
1473
+ }, [value, checked, fieldName, field2.type]);
1474
+ switch (field2.type) {
1475
+ case "input": {
1476
+ const inputType = field2.inputProps?.type || "text";
1477
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
1478
+ Input,
1479
+ {
1480
+ ...field2.inputProps,
1481
+ "data-field-name": fieldName,
1482
+ type: inputType,
1483
+ label: field2.label,
1484
+ description: field2.description,
1485
+ isDisabled: field2.isDisabled,
1486
+ isInvalid: Boolean(errorMessage),
1487
+ errorMessage,
1488
+ value,
1489
+ onValueChange: setValue
1490
+ }
1491
+ ));
1492
+ }
1493
+ case "textarea": {
1494
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
1495
+ Textarea,
1496
+ {
1497
+ ...field2.textareaProps,
1498
+ "data-field-name": fieldName,
1499
+ label: field2.label,
1500
+ description: field2.description,
1501
+ isDisabled: field2.isDisabled,
1502
+ isInvalid: Boolean(errorMessage),
1503
+ errorMessage,
1504
+ value,
1505
+ onValueChange: setValue
1506
+ }
1507
+ ));
1508
+ }
1509
+ case "checkbox": {
1510
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value: checked ? "on" : "" }), /* @__PURE__ */ React17.createElement(
1511
+ Checkbox,
1512
+ {
1513
+ ...field2.checkboxProps,
1514
+ "data-field-name": fieldName,
1515
+ isDisabled: field2.isDisabled,
1516
+ isSelected: checked,
1517
+ onValueChange: setChecked,
1518
+ isInvalid: Boolean(errorMessage),
1519
+ errorMessage
1520
+ },
1521
+ field2.label
1522
+ ));
1523
+ }
1524
+ case "select": {
1525
+ const options = field2.options || [];
1526
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
1527
+ Select,
1528
+ {
1529
+ ...field2.selectProps,
1530
+ "data-field-name": fieldName,
1531
+ label: field2.label,
1532
+ description: field2.description,
1533
+ isDisabled: field2.isDisabled,
1534
+ isInvalid: Boolean(errorMessage),
1535
+ errorMessage,
1536
+ selectedKeys: value ? [value] : [],
1537
+ onSelectionChange: (keys) => {
1538
+ const selectedValue = Array.from(keys)[0];
1539
+ setValue(selectedValue || "");
1540
+ }
1541
+ },
1542
+ options.map(
1543
+ (option) => /* @__PURE__ */ React17.createElement(SelectItem, { key: String(option.value) }, option.label)
1544
+ )
1545
+ ));
1546
+ }
1547
+ default:
1548
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
1549
+ Input,
1550
+ {
1551
+ "data-field-name": fieldName,
1552
+ label: field2.label,
1553
+ description: field2.description,
1554
+ isDisabled: field2.isDisabled,
1555
+ isInvalid: Boolean(errorMessage),
1556
+ errorMessage,
1557
+ value,
1558
+ onValueChange: setValue
1559
+ }
1560
+ ));
1561
+ }
1562
+ }
1563
+
1232
1564
  // src/hooks/useHeroForm.ts
1233
1565
  import { useFormContext as useFormContext4 } from "react-hook-form";
1234
1566
  function useHeroForm() {
@@ -1243,10 +1575,10 @@ function useHeroForm() {
1243
1575
  }
1244
1576
 
1245
1577
  // src/providers/FormProvider.tsx
1246
- import React17 from "react";
1578
+ import React18 from "react";
1247
1579
  import { FormProvider as RHFProvider } from "react-hook-form";
1248
1580
  function FormProvider(props) {
1249
- return /* @__PURE__ */ React17.createElement(RHFProvider, { ...props.methods }, /* @__PURE__ */ React17.createElement(
1581
+ return /* @__PURE__ */ React18.createElement(RHFProvider, { ...props.methods }, /* @__PURE__ */ React18.createElement(
1250
1582
  "form",
1251
1583
  {
1252
1584
  className: props.className,
@@ -1259,7 +1591,7 @@ function FormProvider(props) {
1259
1591
  }
1260
1592
 
1261
1593
  // src/submit/SubmitButton.tsx
1262
- import React18 from "react";
1594
+ import React19 from "react";
1263
1595
  function SubmitButton(props) {
1264
1596
  const ctx = useFormContext5();
1265
1597
  const loading = props.isLoading ?? ctx.formState.isSubmitting;
@@ -1269,10 +1601,10 @@ function SubmitButton(props) {
1269
1601
  const defaults = useHeroHookFormDefaults();
1270
1602
  const getButtonContent = () => {
1271
1603
  if (enhancedState?.isSuccess) {
1272
- return /* @__PURE__ */ React18.createElement("span", { className: "inline-flex items-center gap-2" }, "\u2705", props.successText || "Success!");
1604
+ return /* @__PURE__ */ React19.createElement("span", { className: "inline-flex items-center gap-2" }, "\u2705", props.successText || "Success!");
1273
1605
  }
1274
1606
  if (loading) {
1275
- return /* @__PURE__ */ React18.createElement("span", { className: "inline-flex items-center gap-2" }, "\u23F3", props.loadingText || "Submitting...");
1607
+ return /* @__PURE__ */ React19.createElement("span", { className: "inline-flex items-center gap-2" }, "\u23F3", props.loadingText || "Submitting...");
1276
1608
  }
1277
1609
  return props.children;
1278
1610
  };
@@ -1285,7 +1617,7 @@ function SubmitButton(props) {
1285
1617
  }
1286
1618
  return props.buttonProps?.color || defaults.submitButton.color;
1287
1619
  };
1288
- return /* @__PURE__ */ React18.createElement(
1620
+ return /* @__PURE__ */ React19.createElement(
1289
1621
  Button,
1290
1622
  {
1291
1623
  type: "submit",
@@ -1434,14 +1766,6 @@ var createPasswordSchema = (minLength = 8) => z.string().min(minLength, `Passwor
1434
1766
  /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/,
1435
1767
  "Password must contain at least one uppercase letter, one lowercase letter, and one number"
1436
1768
  );
1437
- var createConfirmPasswordSchema = (passwordField) => z.string().refine(
1438
- (val) => {
1439
- return true;
1440
- },
1441
- {
1442
- message: "Passwords do not match"
1443
- }
1444
- );
1445
1769
  var createNumberRangeSchema = (min, max, fieldName) => z.number().min(min, `${fieldName} must be at least ${min}`).max(max, `${fieldName} must be no more than ${max}`);
1446
1770
  var createDateSchema = (fieldName) => z.date({ message: `${fieldName} is required` });
1447
1771
  var createFutureDateSchema = (fieldName) => z.date({ message: `${fieldName} is required` }).refine((date) => date > /* @__PURE__ */ new Date(), {
@@ -1460,44 +1784,24 @@ var createFileSchema = (maxSizeInMB = 5, allowedTypes = ["image/jpeg", "image/pn
1460
1784
  var createRequiredCheckboxSchema = (fieldName) => z.boolean().refine((val) => val === true, {
1461
1785
  message: `You must agree to ${fieldName}`
1462
1786
  });
1463
- var createConditionalSchema = (condition, schema, errorMessage = "This field is required") => z.any().refine(
1464
- (val) => {
1465
- return true;
1466
- },
1467
- {
1468
- message: errorMessage
1469
- }
1470
- );
1471
- var commonValidations = {
1472
- conditional: (condition, schema, errorMessage) => createConditionalSchema(condition, schema, errorMessage),
1473
- confirmPassword: (passwordField) => createConfirmPasswordSchema(passwordField),
1474
- date: (fieldName) => createDateSchema(fieldName),
1475
- email: createEmailSchema(),
1476
- file: (maxSizeInMB, allowedTypes) => createFileSchema(maxSizeInMB, allowedTypes),
1477
- futureDate: (fieldName) => createFutureDateSchema(fieldName),
1478
- maxLength: (max, fieldName) => createMaxLengthSchema(max, fieldName),
1479
- minLength: (min, fieldName) => createMinLengthSchema(min, fieldName),
1480
- numberRange: (min, max, fieldName) => createNumberRangeSchema(min, max, fieldName),
1481
- password: (minLength) => createPasswordSchema(minLength),
1482
- pastDate: (fieldName) => createPastDateSchema(fieldName),
1483
- phone: createPhoneSchema(),
1484
- required: (fieldName) => createRequiredSchema(fieldName),
1485
- requiredCheckbox: (fieldName) => createRequiredCheckboxSchema(fieldName),
1486
- url: createUrlSchema()
1487
- };
1488
1787
  var crossFieldValidation = {
1489
1788
  /**
1490
- * Password confirmation validation
1789
+ * Conditional required field validation
1491
1790
  */
1492
- passwordConfirmation: (passwordField, confirmField) => {
1791
+ conditionalRequired: (field2, conditionField, conditionValue) => {
1493
1792
  return z.object({
1494
- [passwordField]: z.string(),
1495
- [confirmField]: z.string()
1793
+ [conditionField]: z.any(),
1794
+ [field2]: z.string()
1496
1795
  }).refine(
1497
- (data) => data[passwordField] === data[confirmField],
1796
+ (data) => {
1797
+ if (data[conditionField] === conditionValue) {
1798
+ return data[field2] && data[field2].trim().length > 0;
1799
+ }
1800
+ return true;
1801
+ },
1498
1802
  {
1499
- message: "Passwords do not match",
1500
- path: [confirmField]
1803
+ message: "This field is required",
1804
+ path: [field2]
1501
1805
  }
1502
1806
  );
1503
1807
  },
@@ -1506,8 +1810,8 @@ var crossFieldValidation = {
1506
1810
  */
1507
1811
  dateRange: (startField, endField) => {
1508
1812
  return z.object({
1509
- [startField]: z.string(),
1510
- [endField]: z.string()
1813
+ [endField]: z.string(),
1814
+ [startField]: z.string()
1511
1815
  }).refine(
1512
1816
  (data) => {
1513
1817
  const startDate = new Date(data[startField]);
@@ -1521,39 +1825,47 @@ var crossFieldValidation = {
1521
1825
  );
1522
1826
  },
1523
1827
  /**
1524
- * Conditional required field validation
1828
+ * Password confirmation validation
1525
1829
  */
1526
- conditionalRequired: (field2, conditionField, conditionValue) => {
1830
+ passwordConfirmation: (passwordField, confirmField) => {
1527
1831
  return z.object({
1528
- [field2]: z.string(),
1529
- [conditionField]: z.any()
1530
- }).refine(
1531
- (data) => {
1532
- if (data[conditionField] === conditionValue) {
1533
- return data[field2] && data[field2].trim().length > 0;
1534
- }
1535
- return true;
1536
- },
1537
- {
1538
- message: "This field is required",
1539
- path: [field2]
1540
- }
1541
- );
1832
+ [confirmField]: z.string(),
1833
+ [passwordField]: z.string()
1834
+ }).refine((data) => data[passwordField] === data[confirmField], {
1835
+ message: "Passwords do not match",
1836
+ path: [confirmField]
1837
+ });
1542
1838
  }
1543
1839
  };
1840
+ var commonValidations = {
1841
+ confirmPassword: (passwordField, confirmField) => crossFieldValidation.passwordConfirmation(passwordField, confirmField),
1842
+ date: (fieldName) => createDateSchema(fieldName),
1843
+ email: createEmailSchema(),
1844
+ file: (maxSizeInMB, allowedTypes) => createFileSchema(maxSizeInMB, allowedTypes),
1845
+ futureDate: (fieldName) => createFutureDateSchema(fieldName),
1846
+ maxLength: (max, fieldName) => createMaxLengthSchema(max, fieldName),
1847
+ minLength: (min, fieldName) => createMinLengthSchema(min, fieldName),
1848
+ numberRange: (min, max, fieldName) => createNumberRangeSchema(min, max, fieldName),
1849
+ password: (minLength) => createPasswordSchema(minLength),
1850
+ pastDate: (fieldName) => createPastDateSchema(fieldName),
1851
+ phone: createPhoneSchema(),
1852
+ required: (fieldName) => createRequiredSchema(fieldName),
1853
+ requiredCheckbox: (fieldName) => createRequiredCheckboxSchema(fieldName),
1854
+ url: createUrlSchema()
1855
+ };
1544
1856
 
1545
1857
  // src/index.ts
1546
1858
  import { useFormContext as useFormContext5 } from "react-hook-form";
1547
1859
 
1548
1860
  // src/components/ZodForm.tsx
1549
- import React20 from "react";
1861
+ import React21 from "react";
1550
1862
  import { Button as Button5 } from "@heroui/react";
1551
1863
 
1552
1864
  // src/zod-integration.ts
1553
1865
  import { useForm as useForm2 } from "react-hook-form";
1554
1866
  import { z as z2 } from "zod";
1555
1867
  function createZodResolver(schema) {
1556
- return async (values, context) => {
1868
+ return async (values) => {
1557
1869
  try {
1558
1870
  const result = await schema.parseAsync(values);
1559
1871
  return {
@@ -1584,9 +1896,11 @@ function useZodForm(config) {
1584
1896
  }
1585
1897
  function createZodFormConfig(schema, fields, defaultValues) {
1586
1898
  return {
1587
- schema,
1588
1899
  fields,
1589
- ...defaultValues && { defaultValues }
1900
+ schema,
1901
+ ...defaultValues && {
1902
+ defaultValues
1903
+ }
1590
1904
  };
1591
1905
  }
1592
1906
 
@@ -1594,18 +1908,20 @@ function createZodFormConfig(schema, fields, defaultValues) {
1594
1908
  import { useCallback, useEffect, useState as useState2 } from "react";
1595
1909
  function useEnhancedFormState(form, options = {}) {
1596
1910
  const {
1597
- onSuccess,
1598
- onError,
1599
- successMessage = "Form submitted successfully!",
1600
- errorMessage = "An error occurred. Please try again.",
1601
1911
  autoReset = true,
1602
- resetDelay = 3e3
1912
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1913
+ errorMessage: _errorMessage = "An error occurred. Please try again.",
1914
+ onError,
1915
+ onSuccess,
1916
+ resetDelay = 3e3,
1917
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1918
+ successMessage: _successMessage = "Form submitted successfully!"
1603
1919
  } = options;
1604
1920
  const [status, setStatus] = useState2("idle");
1605
1921
  const [error, setError] = useState2(void 0);
1606
1922
  const [submittedData, setSubmittedData] = useState2(void 0);
1607
- const { formState, getValues } = form;
1608
- const { errors, touchedFields, dirtyFields, isSubmitting } = formState;
1923
+ const { formState, getValues: _getValues } = form;
1924
+ const { dirtyFields, errors, isSubmitting, touchedFields } = formState;
1609
1925
  useEffect(() => {
1610
1926
  if (isSubmitting) {
1611
1927
  setStatus("submitting");
@@ -1621,92 +1937,123 @@ function useEnhancedFormState(form, options = {}) {
1621
1937
  return () => clearTimeout(timer);
1622
1938
  }
1623
1939
  }, [status, autoReset, resetDelay]);
1624
- const handleSuccess = useCallback((data) => {
1625
- setStatus("success");
1626
- setSubmittedData(data);
1627
- setError(void 0);
1628
- onSuccess?.(data);
1629
- }, [onSuccess]);
1630
- const handleError = useCallback((errorMessage2) => {
1631
- setStatus("error");
1632
- setError(errorMessage2);
1633
- setSubmittedData(void 0);
1634
- onError?.(errorMessage2);
1635
- }, [onError]);
1940
+ const handleSuccess = useCallback(
1941
+ (data) => {
1942
+ setStatus("success");
1943
+ setSubmittedData(data);
1944
+ setError(void 0);
1945
+ onSuccess?.(data);
1946
+ },
1947
+ [onSuccess]
1948
+ );
1949
+ const handleError = useCallback(
1950
+ (errorMessage) => {
1951
+ setStatus("error");
1952
+ setError(errorMessage);
1953
+ setSubmittedData(void 0);
1954
+ onError?.(errorMessage);
1955
+ },
1956
+ [onError]
1957
+ );
1636
1958
  const reset = useCallback(() => {
1637
1959
  setStatus("idle");
1638
1960
  setError(void 0);
1639
1961
  setSubmittedData(void 0);
1640
1962
  }, []);
1641
1963
  return {
1642
- status,
1643
- isSubmitting,
1644
- isSuccess: status === "success",
1645
- isError: status === "error",
1646
- error,
1647
- submittedData,
1648
- touchedFields: new Set(Object.keys(touchedFields)),
1649
1964
  dirtyFields: new Set(Object.keys(dirtyFields)),
1650
- hasErrors: Object.keys(errors).length > 0,
1965
+ error,
1651
1966
  errorCount: Object.keys(errors).length,
1652
- handleSuccess,
1653
1967
  handleError,
1654
- reset
1968
+ handleSuccess,
1969
+ hasErrors: Object.keys(errors).length > 0,
1970
+ isError: status === "error",
1971
+ isSubmitting,
1972
+ isSuccess: status === "success",
1973
+ reset,
1974
+ status,
1975
+ submittedData,
1976
+ touchedFields: new Set(Object.keys(touchedFields))
1655
1977
  };
1656
1978
  }
1657
1979
 
1658
1980
  // src/components/FormStatus.tsx
1659
- import React19 from "react";
1981
+ import React20 from "react";
1660
1982
  import { Button as Button4 } from "@heroui/react";
1661
1983
  function FormStatus({
1662
- state,
1663
- onDismiss,
1664
1984
  className = "",
1665
- showDetails = false
1985
+ onDismiss,
1986
+ showDetails = false,
1987
+ state
1666
1988
  }) {
1667
- const { status, isSubmitting, isSuccess, isError, error, submittedData } = state;
1989
+ const { error, isError, isSubmitting, isSuccess, status, submittedData } = state;
1668
1990
  if (status === "idle") {
1669
1991
  return null;
1670
1992
  }
1671
1993
  if (isSubmitting) {
1672
- return /* @__PURE__ */ React19.createElement("div", { className: `flex items-center gap-3 p-4 bg-blue-50 border border-blue-200 rounded-lg ${className}` }, /* @__PURE__ */ React19.createElement("span", { className: "text-blue-600" }, "\u23F3"), /* @__PURE__ */ React19.createElement("div", null, /* @__PURE__ */ React19.createElement("p", { className: "text-sm font-medium text-blue-900" }, "Submitting form..."), showDetails && /* @__PURE__ */ React19.createElement("p", { className: "text-xs text-blue-700" }, "Please wait while we process your request.")));
1994
+ return /* @__PURE__ */ React20.createElement(
1995
+ "div",
1996
+ {
1997
+ className: `flex items-center gap-3 p-4 bg-blue-50 border border-blue-200 rounded-lg ${className}`
1998
+ },
1999
+ /* @__PURE__ */ React20.createElement("span", { className: "text-blue-600" }, "\u23F3"),
2000
+ /* @__PURE__ */ React20.createElement("div", null, /* @__PURE__ */ React20.createElement("p", { className: "text-sm font-medium text-blue-900" }, "Submitting form..."), showDetails && /* @__PURE__ */ React20.createElement("p", { className: "text-xs text-blue-700" }, "Please wait while we process your request."))
2001
+ );
1673
2002
  }
1674
2003
  if (isSuccess) {
1675
- return /* @__PURE__ */ React19.createElement("div", { className: `flex items-center gap-3 p-4 bg-green-50 border border-green-200 rounded-lg ${className}`, "data-testid": "success-message" }, /* @__PURE__ */ React19.createElement("span", { className: "text-green-600" }, "\u2705"), /* @__PURE__ */ React19.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React19.createElement("p", { className: "text-sm font-medium text-green-900" }, "Form submitted successfully!"), showDetails && submittedData && /* @__PURE__ */ React19.createElement("p", { className: "text-xs text-green-700" }, "Your data has been saved. Thank you for your submission.")), onDismiss && /* @__PURE__ */ React19.createElement(
1676
- Button4,
2004
+ return /* @__PURE__ */ React20.createElement(
2005
+ "div",
1677
2006
  {
1678
- size: "sm",
1679
- variant: "light",
1680
- isIconOnly: true,
1681
- onPress: onDismiss,
1682
- "aria-label": "Dismiss success message"
2007
+ className: `flex items-center gap-3 p-4 bg-green-50 border border-green-200 rounded-lg ${className}`,
2008
+ "data-testid": "success-message"
1683
2009
  },
1684
- "\u2715"
1685
- ));
2010
+ /* @__PURE__ */ React20.createElement("span", { className: "text-green-600" }, "\u2705"),
2011
+ /* @__PURE__ */ React20.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React20.createElement("p", { className: "text-sm font-medium text-green-900" }, "Form submitted successfully!"), showDetails && submittedData && /* @__PURE__ */ React20.createElement("p", { className: "text-xs text-green-700" }, "Your data has been saved. Thank you for your submission.")),
2012
+ onDismiss && /* @__PURE__ */ React20.createElement(
2013
+ Button4,
2014
+ {
2015
+ size: "sm",
2016
+ variant: "light",
2017
+ isIconOnly: true,
2018
+ onPress: onDismiss,
2019
+ "aria-label": "Dismiss success message"
2020
+ },
2021
+ "\u2715"
2022
+ )
2023
+ );
1686
2024
  }
1687
2025
  if (isError && error) {
1688
- return /* @__PURE__ */ React19.createElement("div", { className: `flex items-center gap-3 p-4 bg-red-50 border border-red-200 rounded-lg ${className}`, "data-testid": "error-message" }, /* @__PURE__ */ React19.createElement("span", { className: "text-red-600" }, "\u26A0\uFE0F"), /* @__PURE__ */ React19.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React19.createElement("p", { className: "text-sm font-medium text-red-900" }, "Error submitting form"), /* @__PURE__ */ React19.createElement("p", { className: "text-xs text-red-700" }, error)), onDismiss && /* @__PURE__ */ React19.createElement(
1689
- Button4,
2026
+ return /* @__PURE__ */ React20.createElement(
2027
+ "div",
1690
2028
  {
1691
- size: "sm",
1692
- variant: "light",
1693
- isIconOnly: true,
1694
- onPress: onDismiss,
1695
- "aria-label": "Dismiss error message"
2029
+ className: `flex items-center gap-3 p-4 bg-red-50 border border-red-200 rounded-lg ${className}`,
2030
+ "data-testid": "error-message"
1696
2031
  },
1697
- "\u2715"
1698
- ));
2032
+ /* @__PURE__ */ React20.createElement("span", { className: "text-red-600" }, "\u26A0\uFE0F"),
2033
+ /* @__PURE__ */ React20.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React20.createElement("p", { className: "text-sm font-medium text-red-900" }, "Error submitting form"), /* @__PURE__ */ React20.createElement("p", { className: "text-xs text-red-700" }, error)),
2034
+ onDismiss && /* @__PURE__ */ React20.createElement(
2035
+ Button4,
2036
+ {
2037
+ size: "sm",
2038
+ variant: "light",
2039
+ isIconOnly: true,
2040
+ onPress: onDismiss,
2041
+ "aria-label": "Dismiss error message"
2042
+ },
2043
+ "\u2715"
2044
+ )
2045
+ );
1699
2046
  }
1700
2047
  return null;
1701
2048
  }
1702
2049
  function FormToast({
1703
- state,
2050
+ duration = 5e3,
1704
2051
  onDismiss,
1705
2052
  position = "top-right",
1706
- duration = 5e3
2053
+ state
1707
2054
  }) {
1708
- const [isVisible, setIsVisible] = React19.useState(false);
1709
- React19.useEffect(() => {
2055
+ const [isVisible, setIsVisible] = React20.useState(false);
2056
+ React20.useEffect(() => {
1710
2057
  if (state.isSuccess || state.isError) {
1711
2058
  setIsVisible(true);
1712
2059
  if (duration > 0) {
@@ -1722,12 +2069,12 @@ function FormToast({
1722
2069
  return null;
1723
2070
  }
1724
2071
  const positionClasses = {
1725
- "top-right": "top-4 right-4",
1726
- "top-left": "top-4 left-4",
2072
+ "bottom-left": "bottom-4 left-4",
1727
2073
  "bottom-right": "bottom-4 right-4",
1728
- "bottom-left": "bottom-4 left-4"
2074
+ "top-left": "top-4 left-4",
2075
+ "top-right": "top-4 right-4"
1729
2076
  };
1730
- return /* @__PURE__ */ React19.createElement("div", { className: `fixed z-50 ${positionClasses[position]}` }, /* @__PURE__ */ React19.createElement(FormStatus, { state, onDismiss }));
2077
+ return /* @__PURE__ */ React20.createElement("div", { className: `fixed z-50 ${positionClasses[position]}` }, /* @__PURE__ */ React20.createElement(FormStatus, { state, onDismiss }));
1731
2078
  }
1732
2079
 
1733
2080
  // src/components/ZodForm.tsx
@@ -1735,7 +2082,6 @@ function ZodForm({
1735
2082
  className,
1736
2083
  columns = 1,
1737
2084
  config,
1738
- errorDisplay = "inline",
1739
2085
  layout = "vertical",
1740
2086
  onError,
1741
2087
  onSubmit,
@@ -1751,9 +2097,9 @@ function ZodForm({
1751
2097
  }) {
1752
2098
  const form = useZodForm(config);
1753
2099
  const enhancedState = useEnhancedFormState(form, {
1754
- onSuccess,
1755
- onError: (error) => onError?.({ message: error, field: "form" }),
1756
2100
  autoReset: true,
2101
+ onError: (error) => onError?.({ field: "form", message: error }),
2102
+ onSuccess,
1757
2103
  resetDelay: 3e3
1758
2104
  });
1759
2105
  const handleSubmit = async () => {
@@ -1763,7 +2109,8 @@ function ZodForm({
1763
2109
  await onSubmit(formData);
1764
2110
  enhancedState.handleSuccess(formData);
1765
2111
  },
1766
- (errors) => {
2112
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2113
+ (_errors) => {
1767
2114
  enhancedState.handleError("Please fix the validation errors above");
1768
2115
  }
1769
2116
  )();
@@ -1778,54 +2125,54 @@ function ZodForm({
1778
2125
  };
1779
2126
  const renderFields = () => {
1780
2127
  if (layout === "grid") {
1781
- return /* @__PURE__ */ React20.createElement(
2128
+ return /* @__PURE__ */ React21.createElement(
1782
2129
  "div",
1783
2130
  {
1784
2131
  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"}`
1785
2132
  },
1786
- config.fields.map((field2) => /* @__PURE__ */ React20.createElement(
2133
+ config.fields.map((field2) => /* @__PURE__ */ React21.createElement(
1787
2134
  FormField,
1788
2135
  {
1789
2136
  key: field2.name,
1790
2137
  config: field2,
1791
2138
  form,
1792
2139
  submissionState: {
1793
- isSubmitting: enhancedState.isSubmitting,
2140
+ error: enhancedState.error,
1794
2141
  isSubmitted: enhancedState.status !== "idle",
1795
- isSuccess: enhancedState.isSuccess,
1796
- error: enhancedState.error
2142
+ isSubmitting: enhancedState.isSubmitting,
2143
+ isSuccess: enhancedState.isSuccess
1797
2144
  }
1798
2145
  }
1799
2146
  ))
1800
2147
  );
1801
2148
  }
1802
2149
  if (layout === "horizontal") {
1803
- return /* @__PURE__ */ React20.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, config.fields.map((field2) => /* @__PURE__ */ React20.createElement(
2150
+ return /* @__PURE__ */ React21.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, config.fields.map((field2) => /* @__PURE__ */ React21.createElement(
1804
2151
  FormField,
1805
2152
  {
1806
2153
  key: field2.name,
1807
2154
  config: field2,
1808
2155
  form,
1809
2156
  submissionState: {
1810
- isSubmitting: enhancedState.isSubmitting,
2157
+ error: enhancedState.error,
1811
2158
  isSubmitted: enhancedState.status !== "idle",
1812
- isSuccess: enhancedState.isSuccess,
1813
- error: enhancedState.error
2159
+ isSubmitting: enhancedState.isSubmitting,
2160
+ isSuccess: enhancedState.isSuccess
1814
2161
  }
1815
2162
  }
1816
2163
  )));
1817
2164
  }
1818
- return /* @__PURE__ */ React20.createElement("div", { className: `space-y-${spacing}` }, config.fields.map((field2) => /* @__PURE__ */ React20.createElement(
2165
+ return /* @__PURE__ */ React21.createElement("div", { className: `space-y-${spacing}` }, config.fields.map((field2) => /* @__PURE__ */ React21.createElement(
1819
2166
  FormField,
1820
2167
  {
1821
2168
  key: field2.name,
1822
2169
  config: field2,
1823
2170
  form,
1824
2171
  submissionState: {
1825
- isSubmitting: enhancedState.isSubmitting,
2172
+ error: enhancedState.error,
1826
2173
  isSubmitted: enhancedState.status !== "idle",
1827
- isSuccess: enhancedState.isSuccess,
1828
- error: enhancedState.error
2174
+ isSubmitting: enhancedState.isSubmitting,
2175
+ isSuccess: enhancedState.isSuccess
1829
2176
  }
1830
2177
  }
1831
2178
  )));
@@ -1834,7 +2181,7 @@ function ZodForm({
1834
2181
  e.preventDefault();
1835
2182
  void handleSubmit();
1836
2183
  };
1837
- React20.useEffect(() => {
2184
+ React21.useEffect(() => {
1838
2185
  if (config.onError && Object.keys(form.formState.errors).length > 0) {
1839
2186
  config.onError(form.formState.errors);
1840
2187
  }
@@ -1849,14 +2196,14 @@ function ZodForm({
1849
2196
  values: form.getValues()
1850
2197
  });
1851
2198
  }
1852
- 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)), /* @__PURE__ */ React20.createElement(
2199
+ return /* @__PURE__ */ React21.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, 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)), /* @__PURE__ */ React21.createElement(
1853
2200
  FormStatus,
1854
2201
  {
1855
2202
  state: enhancedState,
1856
2203
  onDismiss: () => enhancedState.reset(),
1857
2204
  showDetails: true
1858
2205
  }
1859
- ), renderFields(), /* @__PURE__ */ React20.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React20.createElement(
2206
+ ), renderFields(), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React21.createElement(
1860
2207
  Button5,
1861
2208
  {
1862
2209
  color: "primary",
@@ -1866,7 +2213,7 @@ function ZodForm({
1866
2213
  ...submitButtonProps
1867
2214
  },
1868
2215
  enhancedState.isSuccess ? "Success!" : submitButtonText
1869
- ), showResetButton && /* @__PURE__ */ React20.createElement(
2216
+ ), showResetButton && /* @__PURE__ */ React21.createElement(
1870
2217
  Button5,
1871
2218
  {
1872
2219
  isDisabled: enhancedState.isSubmitting,
@@ -1888,10 +2235,10 @@ var BasicFormBuilder = class {
1888
2235
  */
1889
2236
  input(name, label, type = "text") {
1890
2237
  this.fields.push({
1891
- name,
2238
+ inputProps: { type },
1892
2239
  label,
1893
- type: "input",
1894
- inputProps: { type }
2240
+ name,
2241
+ type: "input"
1895
2242
  });
1896
2243
  return this;
1897
2244
  }
@@ -1900,10 +2247,10 @@ var BasicFormBuilder = class {
1900
2247
  */
1901
2248
  textarea(name, label, placeholder) {
1902
2249
  this.fields.push({
1903
- name,
1904
2250
  label,
1905
- type: "textarea",
1906
- textareaProps: { placeholder }
2251
+ name,
2252
+ textareaProps: { placeholder },
2253
+ type: "textarea"
1907
2254
  });
1908
2255
  return this;
1909
2256
  }
@@ -1912,10 +2259,10 @@ var BasicFormBuilder = class {
1912
2259
  */
1913
2260
  select(name, label, options) {
1914
2261
  this.fields.push({
1915
- name,
1916
2262
  label,
1917
- type: "select",
1918
- options
2263
+ name,
2264
+ options,
2265
+ type: "select"
1919
2266
  });
1920
2267
  return this;
1921
2268
  }
@@ -1924,8 +2271,8 @@ var BasicFormBuilder = class {
1924
2271
  */
1925
2272
  checkbox(name, label) {
1926
2273
  this.fields.push({
1927
- name,
1928
2274
  label,
2275
+ name,
1929
2276
  type: "checkbox"
1930
2277
  });
1931
2278
  return this;
@@ -1935,8 +2282,8 @@ var BasicFormBuilder = class {
1935
2282
  */
1936
2283
  switch(name, label) {
1937
2284
  this.fields.push({
1938
- name,
1939
2285
  label,
2286
+ name,
1940
2287
  type: "switch"
1941
2288
  });
1942
2289
  return this;
@@ -1953,59 +2300,50 @@ function createBasicFormBuilder() {
1953
2300
  }
1954
2301
  var FormFieldHelpers = {
1955
2302
  /**
1956
- * Create an input field
2303
+ * Create a checkbox field
1957
2304
  */
1958
- input: (name, label, type = "text") => ({
1959
- name,
2305
+ checkbox: (name, label) => ({
1960
2306
  label,
1961
- type: "input",
1962
- inputProps: { type }
2307
+ name,
2308
+ type: "checkbox"
1963
2309
  }),
1964
2310
  /**
1965
- * Create a textarea field
2311
+ * Create an input field
1966
2312
  */
1967
- textarea: (name, label, placeholder) => ({
1968
- name,
2313
+ input: (name, label, type = "text") => ({
2314
+ inputProps: { type },
1969
2315
  label,
1970
- type: "textarea",
1971
- textareaProps: { placeholder }
2316
+ name,
2317
+ type: "input"
1972
2318
  }),
1973
2319
  /**
1974
2320
  * Create a select field
1975
2321
  */
1976
2322
  select: (name, label, options) => ({
1977
- name,
1978
2323
  label,
1979
- type: "select",
1980
- options
1981
- }),
1982
- /**
1983
- * Create a checkbox field
1984
- */
1985
- checkbox: (name, label) => ({
1986
2324
  name,
1987
- label,
1988
- type: "checkbox"
2325
+ options,
2326
+ type: "select"
1989
2327
  }),
1990
2328
  /**
1991
2329
  * Create a switch field
1992
2330
  */
1993
2331
  switch: (name, label) => ({
1994
- name,
1995
2332
  label,
2333
+ name,
1996
2334
  type: "switch"
2335
+ }),
2336
+ /**
2337
+ * Create a textarea field
2338
+ */
2339
+ textarea: (name, label, placeholder) => ({
2340
+ label,
2341
+ name,
2342
+ textareaProps: { placeholder },
2343
+ type: "textarea"
1997
2344
  })
1998
2345
  };
1999
2346
  var CommonFields = {
2000
- /**
2001
- * Personal information fields
2002
- */
2003
- personal: () => [
2004
- FormFieldHelpers.input("firstName", "First Name"),
2005
- FormFieldHelpers.input("lastName", "Last Name"),
2006
- FormFieldHelpers.input("email", "Email", "email"),
2007
- FormFieldHelpers.input("phone", "Phone", "tel")
2008
- ],
2009
2347
  /**
2010
2348
  * Address fields
2011
2349
  */
@@ -2014,107 +2352,121 @@ var CommonFields = {
2014
2352
  FormFieldHelpers.input("city", "City"),
2015
2353
  FormFieldHelpers.input("state", "State/Province"),
2016
2354
  FormFieldHelpers.input("zipCode", "ZIP/Postal Code"),
2017
- FormFieldHelpers.select(
2018
- "country",
2019
- "Country",
2020
- [
2021
- { label: "Select a country", value: "" },
2022
- { label: "United States", value: "us" },
2023
- { label: "Canada", value: "ca" },
2024
- { label: "United Kingdom", value: "uk" },
2025
- { label: "Australia", value: "au" },
2026
- { label: "Germany", value: "de" },
2027
- { label: "France", value: "fr" }
2028
- ]
2029
- )
2355
+ FormFieldHelpers.select("country", "Country", [
2356
+ { label: "Select a country", value: "" },
2357
+ { label: "United States", value: "us" },
2358
+ { label: "Canada", value: "ca" },
2359
+ { label: "United Kingdom", value: "uk" },
2360
+ { label: "Australia", value: "au" },
2361
+ { label: "Germany", value: "de" },
2362
+ { label: "France", value: "fr" }
2363
+ ])
2364
+ ],
2365
+ /**
2366
+ * Personal information fields
2367
+ */
2368
+ personal: () => [
2369
+ FormFieldHelpers.input("firstName", "First Name"),
2370
+ FormFieldHelpers.input("lastName", "Last Name"),
2371
+ FormFieldHelpers.input("email", "Email", "email"),
2372
+ FormFieldHelpers.input("phone", "Phone", "tel")
2030
2373
  ],
2031
2374
  /**
2032
2375
  * Terms and conditions fields
2033
2376
  */
2034
2377
  terms: () => [
2035
- FormFieldHelpers.checkbox("terms", "I agree to the terms and conditions"),
2036
- FormFieldHelpers.checkbox("privacy", "I agree to the privacy policy"),
2037
- FormFieldHelpers.checkbox("newsletter", "Subscribe to newsletter")
2378
+ FormFieldHelpers.checkbox(
2379
+ "terms",
2380
+ "I agree to the terms and conditions"
2381
+ ),
2382
+ FormFieldHelpers.checkbox(
2383
+ "privacy",
2384
+ "I agree to the privacy policy"
2385
+ ),
2386
+ FormFieldHelpers.checkbox(
2387
+ "newsletter",
2388
+ "Subscribe to newsletter"
2389
+ )
2038
2390
  ]
2039
2391
  };
2040
2392
 
2041
2393
  // src/builders/AdvancedFormBuilder.ts
2042
2394
  function inputField(name, label, props) {
2043
2395
  return {
2044
- name,
2045
2396
  label,
2397
+ name,
2046
2398
  type: "input",
2047
2399
  ...props && {
2048
2400
  inputProps: {
2049
- type: props.type || "text",
2050
- placeholder: props.placeholder,
2401
+ className: props.className,
2051
2402
  description: props.description,
2052
2403
  disabled: props.isDisabled,
2053
- className: props.className
2404
+ placeholder: props.placeholder,
2405
+ type: props.type || "text"
2054
2406
  }
2055
2407
  }
2056
2408
  };
2057
2409
  }
2058
2410
  function textareaField(name, label, props) {
2059
2411
  return {
2060
- name,
2061
2412
  label,
2413
+ name,
2062
2414
  type: "textarea",
2063
2415
  ...props && {
2064
2416
  textareaProps: {
2065
- placeholder: props.placeholder,
2417
+ className: props.className,
2066
2418
  description: props.description,
2067
2419
  disabled: props.isDisabled,
2068
- className: props.className,
2420
+ placeholder: props.placeholder,
2069
2421
  rows: props.rows
2070
2422
  }
2071
2423
  }
2072
2424
  };
2073
2425
  }
2074
- function selectField(name, label, options, props) {
2426
+ function selectField(name, label, options) {
2075
2427
  return {
2076
- name,
2077
2428
  label,
2078
- type: "select",
2079
- options
2429
+ name,
2430
+ options,
2431
+ type: "select"
2080
2432
  };
2081
2433
  }
2082
2434
  function checkboxField(name, label, props) {
2083
2435
  return {
2084
- name,
2085
2436
  label,
2437
+ name,
2086
2438
  type: "checkbox",
2087
2439
  ...props && {
2088
2440
  checkboxProps: {
2089
- disabled: props.isDisabled,
2090
- className: props.className
2441
+ className: props.className,
2442
+ disabled: props.isDisabled
2091
2443
  }
2092
2444
  }
2093
2445
  };
2094
2446
  }
2095
2447
  function switchField(name, label, props) {
2096
2448
  return {
2097
- name,
2098
2449
  label,
2450
+ name,
2099
2451
  type: "switch",
2100
2452
  ...props && {
2101
2453
  switchProps: {
2102
- disabled: props.isDisabled,
2103
- className: props.className
2454
+ className: props.className,
2455
+ disabled: props.isDisabled
2104
2456
  }
2105
2457
  }
2106
2458
  };
2107
2459
  }
2108
2460
  function radioField(name, label, options, props) {
2109
2461
  return {
2110
- name,
2111
2462
  label,
2112
- type: "radio",
2463
+ name,
2113
2464
  radioOptions: options,
2465
+ type: "radio",
2114
2466
  ...props && {
2115
2467
  radioProps: {
2116
- isDisabled: props.isDisabled,
2117
2468
  className: props.className,
2469
+ isDisabled: props.isDisabled,
2118
2470
  orientation: props.orientation
2119
2471
  }
2120
2472
  }
@@ -2122,58 +2474,58 @@ function radioField(name, label, options, props) {
2122
2474
  }
2123
2475
  function sliderField(name, label, props) {
2124
2476
  return {
2125
- name,
2126
2477
  label,
2478
+ name,
2127
2479
  type: "slider",
2128
2480
  ...props && {
2129
2481
  sliderProps: {
2130
- min: props.min || 0,
2131
- max: props.max || 100,
2132
- step: props.step || 1,
2482
+ className: props.className || "",
2133
2483
  disabled: props.isDisabled || false,
2134
- className: props.className || ""
2484
+ max: props.max || 100,
2485
+ min: props.min || 0,
2486
+ step: props.step || 1
2135
2487
  }
2136
2488
  }
2137
2489
  };
2138
2490
  }
2139
2491
  function dateField(name, label, props) {
2140
2492
  return {
2141
- name,
2142
2493
  label,
2494
+ name,
2143
2495
  type: "date",
2144
2496
  ...props && {
2145
2497
  dateProps: {
2146
- placeholder: props.placeholder || "",
2498
+ className: props.className || "",
2147
2499
  disabled: props.isDisabled || false,
2148
- className: props.className || ""
2500
+ placeholder: props.placeholder || ""
2149
2501
  }
2150
2502
  }
2151
2503
  };
2152
2504
  }
2153
2505
  function fileField(name, label, props) {
2154
2506
  return {
2155
- name,
2156
2507
  label,
2508
+ name,
2157
2509
  type: "file",
2158
2510
  ...props && {
2159
2511
  fileProps: {
2160
2512
  accept: props.accept || "",
2161
- multiple: props.multiple || false,
2513
+ className: props.className || "",
2162
2514
  disabled: props.isDisabled || false,
2163
- className: props.className || ""
2515
+ multiple: props.multiple || false
2164
2516
  }
2165
2517
  }
2166
2518
  };
2167
2519
  }
2168
2520
  function fontPickerField(name, label, props) {
2169
2521
  return {
2170
- name,
2171
2522
  label,
2523
+ name,
2172
2524
  type: "fontPicker",
2173
2525
  ...props && {
2174
2526
  fontPickerProps: {
2175
- disabled: props.isDisabled || false,
2176
- className: props.className || ""
2527
+ className: props.className || "",
2528
+ disabled: props.isDisabled || false
2177
2529
  }
2178
2530
  }
2179
2531
  };
@@ -2185,7 +2537,7 @@ function createField(type, name, label, optionsOrProps, props) {
2185
2537
  case "textarea":
2186
2538
  return textareaField(name, label, optionsOrProps);
2187
2539
  case "select":
2188
- return selectField(name, label, optionsOrProps, props);
2540
+ return selectField(name, label, optionsOrProps);
2189
2541
  case "checkbox":
2190
2542
  return checkboxField(name, label, optionsOrProps);
2191
2543
  case "switch":
@@ -2217,10 +2569,10 @@ var AdvancedFieldBuilder = class {
2217
2569
  */
2218
2570
  conditionalField(name, condition, field2) {
2219
2571
  this.fields.push({
2220
- name,
2221
- type: "conditional",
2222
2572
  condition,
2223
- field: field2
2573
+ field: field2,
2574
+ name,
2575
+ type: "conditional"
2224
2576
  });
2225
2577
  return this;
2226
2578
  }
@@ -2229,14 +2581,14 @@ var AdvancedFieldBuilder = class {
2229
2581
  */
2230
2582
  fieldArray(name, label, fields, options) {
2231
2583
  this.fields.push({
2232
- name,
2233
- label,
2234
- type: "fieldArray",
2584
+ addButtonText: options?.addButtonText,
2235
2585
  fields,
2236
- min: options?.min,
2586
+ label,
2237
2587
  max: options?.max,
2238
- addButtonText: options?.addButtonText,
2239
- removeButtonText: options?.removeButtonText
2588
+ min: options?.min,
2589
+ name,
2590
+ removeButtonText: options?.removeButtonText,
2591
+ type: "fieldArray"
2240
2592
  });
2241
2593
  return this;
2242
2594
  }
@@ -2245,12 +2597,12 @@ var AdvancedFieldBuilder = class {
2245
2597
  */
2246
2598
  dynamicSection(name, condition, fields, options) {
2247
2599
  this.fields.push({
2248
- name,
2249
- type: "dynamicSection",
2250
2600
  condition,
2601
+ description: options?.description,
2251
2602
  fields,
2603
+ name,
2252
2604
  title: options?.title,
2253
- description: options?.description
2605
+ type: "dynamicSection"
2254
2606
  });
2255
2607
  return this;
2256
2608
  }
@@ -2286,7 +2638,13 @@ var FieldArrayBuilder = class {
2286
2638
  }
2287
2639
  field(type, name, label, optionsOrProps, props) {
2288
2640
  const fullPath = `${this.arrayName}.${name}`;
2289
- const fieldConfig = createField(type, fullPath, label, optionsOrProps, props);
2641
+ const fieldConfig = createField(
2642
+ type,
2643
+ fullPath,
2644
+ label,
2645
+ optionsOrProps,
2646
+ props
2647
+ );
2290
2648
  this.fields.push(fieldConfig);
2291
2649
  return this;
2292
2650
  }
@@ -2312,17 +2670,29 @@ var TypeInferredBuilder = class {
2312
2670
  * Add a text field
2313
2671
  */
2314
2672
  text(name, label, options) {
2315
- const { minLength, maxLength, pattern, ...fieldOptions } = options || {};
2673
+ const { maxLength, minLength, pattern, ...fieldOptions } = options || {};
2316
2674
  let zodType = z3.string();
2317
- if (minLength) zodType = zodType.min(minLength, `${label} must be at least ${minLength} characters`);
2318
- if (maxLength) zodType = zodType.max(maxLength, `${label} must be no more than ${maxLength} characters`);
2319
- if (pattern) zodType = zodType.regex(new RegExp(pattern), `${label} format is invalid`);
2675
+ if (minLength)
2676
+ zodType = zodType.min(
2677
+ minLength,
2678
+ `${label} must be at least ${minLength} characters`
2679
+ );
2680
+ if (maxLength)
2681
+ zodType = zodType.max(
2682
+ maxLength,
2683
+ `${label} must be no more than ${maxLength} characters`
2684
+ );
2685
+ if (pattern)
2686
+ zodType = zodType.regex(
2687
+ new RegExp(pattern),
2688
+ `${label} format is invalid`
2689
+ );
2320
2690
  this.schemaFields[name] = zodType;
2321
2691
  this.formFields.push({
2322
- name,
2692
+ inputProps: { type: "text", ...fieldOptions },
2323
2693
  label,
2324
- type: "input",
2325
- inputProps: { type: "text", ...fieldOptions }
2694
+ name,
2695
+ type: "input"
2326
2696
  });
2327
2697
  return this;
2328
2698
  }
@@ -2332,10 +2702,10 @@ var TypeInferredBuilder = class {
2332
2702
  email(name, label, options) {
2333
2703
  this.schemaFields[name] = z3.string().email(`Please enter a valid email address`);
2334
2704
  this.formFields.push({
2335
- name,
2705
+ inputProps: { type: "email", ...options },
2336
2706
  label,
2337
- type: "input",
2338
- inputProps: { type: "email", ...options }
2707
+ name,
2708
+ type: "input"
2339
2709
  });
2340
2710
  return this;
2341
2711
  }
@@ -2343,16 +2713,18 @@ var TypeInferredBuilder = class {
2343
2713
  * Add a number field
2344
2714
  */
2345
2715
  number(name, label, options) {
2346
- const { min, max, step, ...fieldOptions } = options || {};
2716
+ const { max, min, step, ...fieldOptions } = options || {};
2347
2717
  let zodType = z3.number();
2348
- if (min !== void 0) zodType = zodType.min(min, `${label} must be at least ${min}`);
2349
- if (max !== void 0) zodType = zodType.max(max, `${label} must be no more than ${max}`);
2718
+ if (min !== void 0)
2719
+ zodType = zodType.min(min, `${label} must be at least ${min}`);
2720
+ if (max !== void 0)
2721
+ zodType = zodType.max(max, `${label} must be no more than ${max}`);
2350
2722
  this.schemaFields[name] = zodType;
2351
2723
  this.formFields.push({
2352
- name,
2724
+ inputProps: { max, min, step, type: "number", ...fieldOptions },
2353
2725
  label,
2354
- type: "input",
2355
- inputProps: { type: "number", min, max, step, ...fieldOptions }
2726
+ name,
2727
+ type: "input"
2356
2728
  });
2357
2729
  return this;
2358
2730
  }
@@ -2362,26 +2734,30 @@ var TypeInferredBuilder = class {
2362
2734
  textarea(name, label, options) {
2363
2735
  const { minLength, ...fieldOptions } = options || {};
2364
2736
  let zodType = z3.string();
2365
- if (minLength) zodType = zodType.min(minLength, `${label} must be at least ${minLength} characters`);
2737
+ if (minLength)
2738
+ zodType = zodType.min(
2739
+ minLength,
2740
+ `${label} must be at least ${minLength} characters`
2741
+ );
2366
2742
  this.schemaFields[name] = zodType;
2367
2743
  this.formFields.push({
2368
- name,
2369
2744
  label,
2370
- type: "textarea",
2371
- textareaProps: fieldOptions
2745
+ name,
2746
+ textareaProps: fieldOptions,
2747
+ type: "textarea"
2372
2748
  });
2373
2749
  return this;
2374
2750
  }
2375
2751
  /**
2376
2752
  * Add a select field
2377
2753
  */
2378
- select(name, label, options, fieldOptions) {
2754
+ select(name, label, options) {
2379
2755
  this.schemaFields[name] = z3.string().min(1, `Please select a ${label.toLowerCase()}`);
2380
2756
  this.formFields.push({
2381
- name,
2382
2757
  label,
2383
- type: "select",
2384
- options
2758
+ name,
2759
+ options,
2760
+ type: "select"
2385
2761
  });
2386
2762
  return this;
2387
2763
  }
@@ -2392,14 +2768,17 @@ var TypeInferredBuilder = class {
2392
2768
  const { required = false, ...fieldOptions } = options || {};
2393
2769
  let zodType = z3.boolean();
2394
2770
  if (required) {
2395
- zodType = zodType.refine((val) => val === true, `You must agree to ${label.toLowerCase()}`);
2771
+ zodType = zodType.refine(
2772
+ (val) => val === true,
2773
+ `You must agree to ${label.toLowerCase()}`
2774
+ );
2396
2775
  }
2397
2776
  this.schemaFields[name] = zodType;
2398
2777
  this.formFields.push({
2399
- name,
2778
+ checkboxProps: fieldOptions,
2400
2779
  label,
2401
- type: "checkbox",
2402
- checkboxProps: fieldOptions
2780
+ name,
2781
+ type: "checkbox"
2403
2782
  });
2404
2783
  return this;
2405
2784
  }
@@ -2409,10 +2788,10 @@ var TypeInferredBuilder = class {
2409
2788
  switch(name, label, options) {
2410
2789
  this.schemaFields[name] = z3.boolean().optional();
2411
2790
  this.formFields.push({
2412
- name,
2413
2791
  label,
2414
- type: "switch",
2415
- switchProps: options
2792
+ name,
2793
+ switchProps: options,
2794
+ type: "switch"
2416
2795
  });
2417
2796
  return this;
2418
2797
  }
@@ -2422,11 +2801,11 @@ var TypeInferredBuilder = class {
2422
2801
  radio(name, label, options, fieldOptions) {
2423
2802
  this.schemaFields[name] = z3.string().min(1, `Please select a ${label.toLowerCase()}`);
2424
2803
  this.formFields.push({
2425
- name,
2426
2804
  label,
2427
- type: "radio",
2805
+ name,
2428
2806
  radioOptions: options,
2429
- radioProps: fieldOptions
2807
+ radioProps: fieldOptions,
2808
+ type: "radio"
2430
2809
  });
2431
2810
  return this;
2432
2811
  }
@@ -2434,16 +2813,18 @@ var TypeInferredBuilder = class {
2434
2813
  * Add a slider field
2435
2814
  */
2436
2815
  slider(name, label, options) {
2437
- const { min = 0, max = 100, step = 1, ...fieldOptions } = options || {};
2816
+ const { max = 100, min = 0, step = 1, ...fieldOptions } = options || {};
2438
2817
  let zodType = z3.number();
2439
- if (min !== void 0) zodType = zodType.min(min, `${label} must be at least ${min}`);
2440
- if (max !== void 0) zodType = zodType.max(max, `${label} must be no more than ${max}`);
2818
+ if (min !== void 0)
2819
+ zodType = zodType.min(min, `${label} must be at least ${min}`);
2820
+ if (max !== void 0)
2821
+ zodType = zodType.max(max, `${label} must be no more than ${max}`);
2441
2822
  this.schemaFields[name] = zodType;
2442
2823
  this.formFields.push({
2443
- name,
2444
2824
  label,
2445
- type: "slider",
2446
- sliderProps: { min, max, step, ...fieldOptions }
2825
+ name,
2826
+ sliderProps: { max, min, step, ...fieldOptions },
2827
+ type: "slider"
2447
2828
  });
2448
2829
  return this;
2449
2830
  }
@@ -2453,10 +2834,10 @@ var TypeInferredBuilder = class {
2453
2834
  date(name, label, options) {
2454
2835
  this.schemaFields[name] = z3.string().min(1, `${label} is required`);
2455
2836
  this.formFields.push({
2456
- name,
2837
+ dateProps: options,
2457
2838
  label,
2458
- type: "date",
2459
- dateProps: options
2839
+ name,
2840
+ type: "date"
2460
2841
  });
2461
2842
  return this;
2462
2843
  }
@@ -2466,10 +2847,10 @@ var TypeInferredBuilder = class {
2466
2847
  file(name, label, options) {
2467
2848
  this.schemaFields[name] = z3.any().optional();
2468
2849
  this.formFields.push({
2469
- name,
2850
+ fileProps: options,
2470
2851
  label,
2471
- type: "file",
2472
- fileProps: options
2852
+ name,
2853
+ type: "file"
2473
2854
  });
2474
2855
  return this;
2475
2856
  }
@@ -2478,8 +2859,8 @@ var TypeInferredBuilder = class {
2478
2859
  */
2479
2860
  build() {
2480
2861
  return {
2481
- schema: z3.object(this.schemaFields),
2482
- fields: this.formFields
2862
+ fields: this.formFields,
2863
+ schema: z3.object(this.schemaFields)
2483
2864
  };
2484
2865
  }
2485
2866
  };
@@ -2492,49 +2873,49 @@ function defineInferredForm(fieldDefinitions) {
2492
2873
  return builder.build();
2493
2874
  }
2494
2875
  var field = {
2495
- text: (name, label, options) => {
2876
+ checkbox: (name, label, options) => {
2496
2877
  const builder = new TypeInferredBuilder();
2497
- return builder.text(name, label, options);
2878
+ return builder.checkbox(name, label, options);
2879
+ },
2880
+ date: (name, label, options) => {
2881
+ const builder = new TypeInferredBuilder();
2882
+ return builder.date(name, label, options);
2498
2883
  },
2499
2884
  email: (name, label, options) => {
2500
2885
  const builder = new TypeInferredBuilder();
2501
2886
  return builder.email(name, label, options);
2502
2887
  },
2888
+ file: (name, label, options) => {
2889
+ const builder = new TypeInferredBuilder();
2890
+ return builder.file(name, label, options);
2891
+ },
2503
2892
  number: (name, label, options) => {
2504
2893
  const builder = new TypeInferredBuilder();
2505
2894
  return builder.number(name, label, options);
2506
2895
  },
2507
- textarea: (name, label, options) => {
2896
+ radio: (name, label, options, fieldOptions) => {
2508
2897
  const builder = new TypeInferredBuilder();
2509
- return builder.textarea(name, label, options);
2898
+ return builder.radio(name, label, options, fieldOptions);
2510
2899
  },
2511
- select: (name, label, options, fieldOptions) => {
2900
+ select: (name, label, options) => {
2512
2901
  const builder = new TypeInferredBuilder();
2513
- return builder.select(name, label, options, fieldOptions);
2902
+ return builder.select(name, label, options);
2514
2903
  },
2515
- checkbox: (name, label, options) => {
2904
+ slider: (name, label, options) => {
2516
2905
  const builder = new TypeInferredBuilder();
2517
- return builder.checkbox(name, label, options);
2906
+ return builder.slider(name, label, options);
2518
2907
  },
2519
2908
  switch: (name, label, options) => {
2520
2909
  const builder = new TypeInferredBuilder();
2521
2910
  return builder.switch(name, label, options);
2522
2911
  },
2523
- radio: (name, label, options, fieldOptions) => {
2524
- const builder = new TypeInferredBuilder();
2525
- return builder.radio(name, label, options, fieldOptions);
2526
- },
2527
- slider: (name, label, options) => {
2528
- const builder = new TypeInferredBuilder();
2529
- return builder.slider(name, label, options);
2530
- },
2531
- date: (name, label, options) => {
2912
+ text: (name, label, options) => {
2532
2913
  const builder = new TypeInferredBuilder();
2533
- return builder.date(name, label, options);
2914
+ return builder.text(name, label, options);
2534
2915
  },
2535
- file: (name, label, options) => {
2916
+ textarea: (name, label, options) => {
2536
2917
  const builder = new TypeInferredBuilder();
2537
- return builder.file(name, label, options);
2918
+ return builder.textarea(name, label, options);
2538
2919
  }
2539
2920
  };
2540
2921
 
@@ -2563,8 +2944,8 @@ var NestedPathBuilder = class {
2563
2944
  */
2564
2945
  field(name, label, type = "input", props) {
2565
2946
  this.fields.push({
2566
- name,
2567
2947
  label,
2948
+ name,
2568
2949
  type,
2569
2950
  ...props
2570
2951
  });
@@ -2577,8 +2958,8 @@ var NestedPathBuilder = class {
2577
2958
  fieldPath(path, label, type = "input", props) {
2578
2959
  const name = path.join(".");
2579
2960
  this.fields.push({
2580
- name,
2581
2961
  label,
2962
+ name,
2582
2963
  type,
2583
2964
  ...props
2584
2965
  });
@@ -2588,7 +2969,7 @@ var NestedPathBuilder = class {
2588
2969
  * Add a field with template literal path
2589
2970
  * Usage: builder.field`user.profile.name`("Full Name")
2590
2971
  */
2591
- fieldTemplate(path, ...args) {
2972
+ fieldTemplate(path) {
2592
2973
  const pathString = path[0];
2593
2974
  return new FieldTemplateBuilder(this, pathString);
2594
2975
  }
@@ -2613,8 +2994,8 @@ var NestedObjectBuilder = class _NestedObjectBuilder {
2613
2994
  field(fieldName, label, type = "input", props) {
2614
2995
  const fullPath = `${this.path}.${fieldName}`;
2615
2996
  this.parent.fields.push({
2616
- name: fullPath,
2617
2997
  label,
2998
+ name: fullPath,
2618
2999
  type,
2619
3000
  ...props
2620
3001
  });
@@ -2624,7 +3005,10 @@ var NestedObjectBuilder = class _NestedObjectBuilder {
2624
3005
  * Nest deeper into the object
2625
3006
  */
2626
3007
  nest(subPath) {
2627
- return new _NestedObjectBuilder(this.parent, `${this.path}.${subPath}`);
3008
+ return new _NestedObjectBuilder(
3009
+ this.parent,
3010
+ `${this.path}.${subPath}`
3011
+ );
2628
3012
  }
2629
3013
  /**
2630
3014
  * Return to the parent builder
@@ -2644,8 +3028,8 @@ var SectionBuilder = class {
2644
3028
  field(fieldName, label, type = "input", props) {
2645
3029
  const fullPath = `${this.path}.${fieldName}`;
2646
3030
  this.parent.fields.push({
2647
- name: fullPath,
2648
3031
  label,
3032
+ name: fullPath,
2649
3033
  type,
2650
3034
  ...props
2651
3035
  });
@@ -2664,7 +3048,10 @@ var SectionBuilder = class {
2664
3048
  * Nest deeper into the section
2665
3049
  */
2666
3050
  nest(subPath) {
2667
- return new NestedObjectBuilder(this.parent, `${this.path}.${subPath}`);
3051
+ return new NestedObjectBuilder(
3052
+ this.parent,
3053
+ `${this.path}.${subPath}`
3054
+ );
2668
3055
  }
2669
3056
  /**
2670
3057
  * Return to the parent builder
@@ -2683,8 +3070,8 @@ var FieldTemplateBuilder = class {
2683
3070
  */
2684
3071
  complete(label, type = "input", props) {
2685
3072
  this.parent.fields.push({
2686
- name: this.path,
2687
3073
  label,
3074
+ name: this.path,
2688
3075
  type,
2689
3076
  ...props
2690
3077
  });
@@ -2698,8 +3085,10 @@ function createNestedPathBuilder() {
2698
3085
  // src/hooks/useDebouncedValidation.ts
2699
3086
  import { useCallback as useCallback2, useEffect as useEffect2, useRef } from "react";
2700
3087
  function useDebouncedValidation(form, options = {}) {
2701
- const { delay = 300, fields, enabled = true } = options;
2702
- const timeoutRef = useRef(void 0);
3088
+ const { delay = 300, enabled = true, fields } = options;
3089
+ const timeoutRef = useRef(
3090
+ void 0
3091
+ );
2703
3092
  const lastValuesRef = useRef({});
2704
3093
  const debouncedTrigger = useCallback2(() => {
2705
3094
  if (!enabled) return;
@@ -2710,7 +3099,9 @@ function useDebouncedValidation(form, options = {}) {
2710
3099
  timeoutRef.current = setTimeout(async () => {
2711
3100
  const currentValues = form.getValues();
2712
3101
  const lastValues = lastValuesRef.current;
2713
- const hasChanges = fields ? fields.some((field2) => currentValues[field2] !== lastValues[field2]) : Object.keys(currentValues).some((key) => currentValues[key] !== lastValues[key]);
3102
+ const hasChanges = fields ? fields.some((field2) => currentValues[field2] !== lastValues[field2]) : Object.keys(currentValues).some(
3103
+ (key) => currentValues[key] !== lastValues[key]
3104
+ );
2714
3105
  if (hasChanges) {
2715
3106
  lastValuesRef.current = { ...currentValues };
2716
3107
  if (fields && fields.length > 0) {
@@ -2741,7 +3132,9 @@ function useDebouncedValidation(form, options = {}) {
2741
3132
  }
2742
3133
  function useDebouncedFieldValidation(form, fieldName, options = {}) {
2743
3134
  const { delay = 300, enabled = true } = options;
2744
- const timeoutRef = useRef(void 0);
3135
+ const timeoutRef = useRef(
3136
+ void 0
3137
+ );
2745
3138
  const debouncedFieldTrigger = useCallback2(() => {
2746
3139
  if (!enabled) return;
2747
3140
  if (timeoutRef.current) {
@@ -2775,20 +3168,20 @@ try {
2775
3168
  function useInferredForm(schema, fields, options = {}) {
2776
3169
  const {
2777
3170
  defaultValues,
3171
+ delayError = 0,
2778
3172
  mode = "onChange",
2779
3173
  reValidateMode = "onChange",
2780
3174
  shouldFocusError = true,
2781
- shouldUnregister = false,
2782
- delayError = 0
3175
+ shouldUnregister = false
2783
3176
  } = options;
2784
3177
  return useForm3({
2785
- resolver: zodResolver ? zodResolver(schema) : void 0,
2786
3178
  defaultValues,
3179
+ delayError,
2787
3180
  mode,
3181
+ resolver: zodResolver ? zodResolver(schema) : void 0,
2788
3182
  reValidateMode,
2789
3183
  shouldFocusError,
2790
- shouldUnregister,
2791
- delayError
3184
+ shouldUnregister
2792
3185
  });
2793
3186
  }
2794
3187
  function useTypeInferredForm(formConfig, options = {}) {
@@ -2881,7 +3274,7 @@ function usePerformanceMonitor(componentName, enabled = false) {
2881
3274
  };
2882
3275
  }
2883
3276
  function createOptimizedFieldHandler(onChange, options = {}) {
2884
- const { debounce: debounceMs, throttle: throttleMs, validate = false } = options;
3277
+ const { debounce: debounceMs, throttle: throttleMs } = options;
2885
3278
  let handler = onChange;
2886
3279
  if (throttleMs) {
2887
3280
  handler = throttle(handler, throttleMs);
@@ -2894,70 +3287,51 @@ function createOptimizedFieldHandler(onChange, options = {}) {
2894
3287
  function useMemoizedFieldProps(props, deps) {
2895
3288
  return useMemo2(() => props, deps);
2896
3289
  }
2897
- function useBatchedFieldUpdates(form, fields) {
2898
- const batchRef = useRef2({});
2899
- const timeoutRef = useRef2(void 0);
2900
- const batchUpdate = useCallback3((fieldName, value) => {
2901
- batchRef.current[fieldName] = value;
2902
- if (timeoutRef.current) {
2903
- clearTimeout(timeoutRef.current);
2904
- }
2905
- timeoutRef.current = setTimeout(() => {
2906
- Object.entries(batchRef.current).forEach(([key, val]) => {
2907
- form.setValue(key, val);
2908
- });
2909
- batchRef.current = {};
2910
- }, 16);
2911
- }, [form]);
2912
- return { batchUpdate };
2913
- }
2914
3290
 
2915
3291
  // src/builders/validation-helpers.ts
2916
3292
  import { z as z4 } from "zod";
2917
3293
  var validationPatterns = {
2918
- // Email validation
2919
- email: z4.string().email("Please enter a valid email address"),
2920
- // Phone number validation (US format)
2921
- phoneUS: z4.string().regex(
2922
- /^\(\d{3}\) \d{3}-\d{4}$/,
2923
- "Please enter a valid phone number (XXX) XXX-XXXX"
2924
- ),
2925
- // Phone number validation (international)
2926
- phoneInternational: z4.string().regex(
2927
- /^\+?[\d\s\-\(\)]+$/,
2928
- "Please enter a valid phone number"
2929
- ),
2930
- // URL validation
2931
- url: z4.string().url("Please enter a valid URL"),
2932
- // Password validation
2933
- password: z4.string().min(8, "Password must be at least 8 characters").regex(/[A-Z]/, "Password must contain at least one uppercase letter").regex(/[a-z]/, "Password must contain at least one lowercase letter").regex(/[0-9]/, "Password must contain at least one number").regex(/[^A-Za-z0-9]/, "Password must contain at least one special character"),
2934
- // Strong password validation
2935
- strongPassword: z4.string().min(12, "Password must be at least 12 characters").regex(/[A-Z]/, "Password must contain at least one uppercase letter").regex(/[a-z]/, "Password must contain at least one lowercase letter").regex(/[0-9]/, "Password must contain at least one number").regex(/[^A-Za-z0-9]/, "Password must contain at least one special character"),
2936
3294
  // Credit card validation
2937
3295
  creditCard: z4.string().regex(
3296
+ // eslint-disable-next-line no-useless-escape
2938
3297
  /^[0-9]{4}[\s\-]?[0-9]{4}[\s\-]?[0-9]{4}[\s\-]?[0-9]{4}$/,
2939
3298
  "Please enter a valid credit card number"
2940
3299
  ),
2941
- // SSN validation
2942
- ssn: z4.string().regex(
2943
- /^\d{3}-\d{2}-\d{4}$/,
2944
- "Please enter a valid SSN (XXX-XX-XXXX)"
2945
- ),
2946
- // ZIP code validation
2947
- zipCode: z4.string().regex(
2948
- /^\d{5}(-\d{4})?$/,
2949
- "Please enter a valid ZIP code"
2950
- ),
2951
3300
  // Date validation (MM/DD/YYYY)
2952
3301
  date: z4.string().regex(
2953
3302
  /^(0[1-9]|1[0-2])\/(0[1-9]|[12][0-9]|3[01])\/\d{4}$/,
2954
3303
  "Please enter a valid date (MM/DD/YYYY)"
2955
3304
  ),
3305
+ // Email validation
3306
+ email: z4.string().email("Please enter a valid email address"),
3307
+ // Password validation
3308
+ password: z4.string().min(8, "Password must be at least 8 characters").regex(/[A-Z]/, "Password must contain at least one uppercase letter").regex(/[a-z]/, "Password must contain at least one lowercase letter").regex(/[0-9]/, "Password must contain at least one number").regex(
3309
+ /[^A-Za-z0-9]/,
3310
+ "Password must contain at least one special character"
3311
+ ),
3312
+ // Phone number validation (international)
3313
+ phoneInternational: z4.string().regex(/^\+?[\d\s\-\(\)]+$/, "Please enter a valid phone number"),
3314
+ // Phone number validation (US format)
3315
+ phoneUS: z4.string().regex(
3316
+ /^\(\d{3}\) \d{3}-\d{4}$/,
3317
+ "Please enter a valid phone number (XXX) XXX-XXXX"
3318
+ ),
3319
+ // SSN validation
3320
+ ssn: z4.string().regex(/^\d{3}-\d{2}-\d{4}$/, "Please enter a valid SSN (XXX-XX-XXXX)"),
3321
+ // Strong password validation
3322
+ strongPassword: z4.string().min(12, "Password must be at least 12 characters").regex(/[A-Z]/, "Password must contain at least one uppercase letter").regex(/[a-z]/, "Password must contain at least one lowercase letter").regex(/[0-9]/, "Password must contain at least one number").regex(
3323
+ /[^A-Za-z0-9]/,
3324
+ "Password must contain at least one special character"
3325
+ ),
2956
3326
  // Time validation (HH:MM AM/PM)
2957
3327
  time: z4.string().regex(
2958
3328
  /^(0[1-9]|1[0-2]):[0-5][0-9] (AM|PM)$/i,
2959
3329
  "Please enter a valid time (HH:MM AM/PM)"
2960
- )
3330
+ ),
3331
+ // URL validation
3332
+ url: z4.string().url("Please enter a valid URL"),
3333
+ // ZIP code validation
3334
+ zipCode: z4.string().regex(/^\d{5}(-\d{4})?$/, "Please enter a valid ZIP code")
2961
3335
  };
2962
3336
  var asyncValidation = {
2963
3337
  /**
@@ -2984,17 +3358,17 @@ var asyncValidation = {
2984
3358
  }
2985
3359
  };
2986
3360
  var errorMessages = {
2987
- required: (fieldName) => `${fieldName} is required`,
2988
- minLength: (fieldName, min) => `${fieldName} must be at least ${min} characters`,
3361
+ date: () => "Please enter a valid date",
3362
+ email: () => "Please enter a valid email address",
3363
+ max: (fieldName, max) => `${fieldName} must be no more than ${max}`,
2989
3364
  maxLength: (fieldName, max) => `${fieldName} must be no more than ${max} characters`,
2990
3365
  min: (fieldName, min) => `${fieldName} must be at least ${min}`,
2991
- max: (fieldName, max) => `${fieldName} must be no more than ${max}`,
3366
+ minLength: (fieldName, min) => `${fieldName} must be at least ${min} characters`,
2992
3367
  pattern: (fieldName) => `${fieldName} format is invalid`,
2993
- email: () => "Please enter a valid email address",
2994
- url: () => "Please enter a valid URL",
2995
3368
  phone: () => "Please enter a valid phone number",
2996
- date: () => "Please enter a valid date",
2997
- time: () => "Please enter a valid time"
3369
+ required: (fieldName) => `${fieldName} is required`,
3370
+ time: () => "Please enter a valid time",
3371
+ url: () => "Please enter a valid URL"
2998
3372
  };
2999
3373
  var serverValidation = {
3000
3374
  /**
@@ -3003,8 +3377,8 @@ var serverValidation = {
3003
3377
  applyServerErrors: (errors, setError) => {
3004
3378
  Object.entries(errors).forEach(([field2, messages]) => {
3005
3379
  setError(field2, {
3006
- type: "server",
3007
- message: messages[0]
3380
+ message: messages[0],
3381
+ type: "server"
3008
3382
  // Use first error message
3009
3383
  });
3010
3384
  });
@@ -3029,13 +3403,25 @@ var validationUtils = {
3029
3403
  timeoutId = setTimeout(() => fn(...args), delay);
3030
3404
  };
3031
3405
  },
3406
+ /**
3407
+ * Get field error message
3408
+ */
3409
+ getFieldError: (errors, field2) => {
3410
+ return errors[field2];
3411
+ },
3412
+ /**
3413
+ * Check if field has error
3414
+ */
3415
+ hasFieldError: (errors, field2) => {
3416
+ return !!errors[field2];
3417
+ },
3032
3418
  /**
3033
3419
  * Validate form data against schema
3034
3420
  */
3035
3421
  validateForm: async (data, schema) => {
3036
3422
  try {
3037
3423
  await schema.parseAsync(data);
3038
- return { success: true, errors: {} };
3424
+ return { errors: {}, success: true };
3039
3425
  } catch (error) {
3040
3426
  if (error instanceof z4.ZodError) {
3041
3427
  const errors = {};
@@ -3043,22 +3429,10 @@ var validationUtils = {
3043
3429
  const path = err.path.join(".");
3044
3430
  errors[path] = err.message;
3045
3431
  });
3046
- return { success: false, errors };
3432
+ return { errors, success: false };
3047
3433
  }
3048
3434
  throw error;
3049
3435
  }
3050
- },
3051
- /**
3052
- * Get field error message
3053
- */
3054
- getFieldError: (errors, field2) => {
3055
- return errors[field2];
3056
- },
3057
- /**
3058
- * Check if field has error
3059
- */
3060
- hasFieldError: (errors, field2) => {
3061
- return !!errors[field2];
3062
3436
  }
3063
3437
  };
3064
3438
  export {
@@ -3084,6 +3458,7 @@ export {
3084
3458
  InputField,
3085
3459
  RadioGroupField,
3086
3460
  SelectField,
3461
+ ServerActionForm,
3087
3462
  SliderField,
3088
3463
  SubmitButton,
3089
3464
  SwitchField,
@@ -3095,8 +3470,6 @@ export {
3095
3470
  commonValidations,
3096
3471
  createAdvancedBuilder,
3097
3472
  createBasicFormBuilder,
3098
- createConditionalSchema,
3099
- createConfirmPasswordSchema,
3100
3473
  createDateSchema,
3101
3474
  createEmailSchema,
3102
3475
  createField,
@@ -3135,7 +3508,6 @@ export {
3135
3508
  simulateFieldInput,
3136
3509
  simulateFormSubmission,
3137
3510
  throttle,
3138
- useBatchedFieldUpdates,
3139
3511
  useDebouncedFieldValidation,
3140
3512
  useDebouncedValidation,
3141
3513
  useEnhancedFormState,