@rachelallyson/hero-hook-form 2.0.0 → 2.1.0

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