@rachelallyson/hero-hook-form 2.0.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,326 @@ function ConfigurableForm({
1224
1236
  )));
1225
1237
  }
1226
1238
 
1239
+ // src/components/ServerActionForm.tsx
1240
+ import React17 from "react";
1241
+ import { useActionState } from "react";
1242
+ function ServerActionForm({
1243
+ action,
1244
+ className,
1245
+ clientValidationSchema,
1246
+ columns = 1,
1247
+ defaultValues,
1248
+ fields,
1249
+ initialState,
1250
+ layout = "vertical",
1251
+ onError,
1252
+ onSuccess,
1253
+ resetButtonText = "Reset",
1254
+ showResetButton = false,
1255
+ spacing = "4",
1256
+ submitButtonProps = {},
1257
+ submitButtonText = "Submit",
1258
+ subtitle,
1259
+ title
1260
+ }) {
1261
+ const [state, formAction, pending] = useActionState(
1262
+ action,
1263
+ initialState ?? { errors: void 0, message: void 0, success: false }
1264
+ );
1265
+ const formRef = React17.useRef(null);
1266
+ const [clientErrors, setClientErrors] = React17.useState({});
1267
+ const lastSubmittedFormData = React17.useRef(null);
1268
+ React17.useEffect(() => {
1269
+ if (state && (state.errors || state.message && !state.success)) {
1270
+ onError?.({
1271
+ errors: state.errors,
1272
+ message: state.message
1273
+ });
1274
+ }
1275
+ }, [state, onError]);
1276
+ React17.useEffect(() => {
1277
+ if (state?.success && lastSubmittedFormData.current) {
1278
+ onSuccess?.(lastSubmittedFormData.current);
1279
+ }
1280
+ }, [state?.success, onSuccess]);
1281
+ const handleReset = () => {
1282
+ formRef.current?.reset();
1283
+ setClientErrors({});
1284
+ };
1285
+ const handleSubmit = async (e) => {
1286
+ e.preventDefault();
1287
+ if (clientValidationSchema) {
1288
+ const formData2 = new FormData(e.currentTarget);
1289
+ const values = {};
1290
+ formData2.forEach((val, key) => {
1291
+ if (val === "on") {
1292
+ values[key] = true;
1293
+ } else if (val === "") {
1294
+ if (!values[key]) {
1295
+ values[key] = false;
1296
+ }
1297
+ } else {
1298
+ values[key] = val;
1299
+ }
1300
+ });
1301
+ const result = clientValidationSchema.safeParse(values);
1302
+ if (!result.success) {
1303
+ const errors = {};
1304
+ result.error.issues.forEach((issue) => {
1305
+ const path = issue.path.join(".");
1306
+ errors[path] = issue.message;
1307
+ });
1308
+ setClientErrors((prev) => ({ ...prev, ...errors }));
1309
+ return;
1310
+ }
1311
+ setClientErrors({});
1312
+ }
1313
+ const formData = new FormData(e.currentTarget);
1314
+ lastSubmittedFormData.current = formData;
1315
+ formAction(formData);
1316
+ };
1317
+ const renderFields = () => {
1318
+ if (layout === "grid") {
1319
+ return /* @__PURE__ */ React17.createElement(
1320
+ "div",
1321
+ {
1322
+ 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"}`
1323
+ },
1324
+ fields.map((field2) => /* @__PURE__ */ React17.createElement(
1325
+ ServerActionField,
1326
+ {
1327
+ key: field2.name,
1328
+ clientErrors,
1329
+ defaultValues,
1330
+ errors: state?.errors,
1331
+ field: field2
1332
+ }
1333
+ ))
1334
+ );
1335
+ }
1336
+ if (layout === "horizontal") {
1337
+ return /* @__PURE__ */ React17.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, fields.map((field2) => /* @__PURE__ */ React17.createElement(
1338
+ ServerActionField,
1339
+ {
1340
+ key: field2.name,
1341
+ clientErrors,
1342
+ defaultValues,
1343
+ errors: state?.errors,
1344
+ field: field2
1345
+ }
1346
+ )));
1347
+ }
1348
+ return /* @__PURE__ */ React17.createElement("div", { className: `space-y-${spacing}` }, fields.map((field2) => /* @__PURE__ */ React17.createElement(
1349
+ ServerActionField,
1350
+ {
1351
+ key: field2.name,
1352
+ clientErrors,
1353
+ defaultValues,
1354
+ errors: state?.errors,
1355
+ field: field2
1356
+ }
1357
+ )));
1358
+ };
1359
+ return /* @__PURE__ */ React17.createElement(
1360
+ "form",
1361
+ {
1362
+ ref: formRef,
1363
+ className,
1364
+ role: "form",
1365
+ onSubmit: handleSubmit
1366
+ },
1367
+ 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)),
1368
+ state?.success && !pending && /* @__PURE__ */ React17.createElement(
1369
+ "div",
1370
+ {
1371
+ className: "mb-6 p-4 bg-success-50 border border-success-200 rounded-lg",
1372
+ "data-testid": "success-message"
1373
+ },
1374
+ /* @__PURE__ */ React17.createElement("p", { className: "text-success-800 font-medium" }, "Success!"),
1375
+ state.message && /* @__PURE__ */ React17.createElement("p", { className: "text-success-700 text-sm mt-1" }, state.message)
1376
+ ),
1377
+ state?.message && !state.success && /* @__PURE__ */ React17.createElement(
1378
+ "div",
1379
+ {
1380
+ className: "mb-6 p-4 bg-danger-50 border border-danger-200 rounded-lg",
1381
+ "data-testid": "error-message"
1382
+ },
1383
+ /* @__PURE__ */ React17.createElement("p", { className: "text-danger-800 font-medium" }, "Error"),
1384
+ /* @__PURE__ */ React17.createElement("p", { className: "text-danger-700 text-sm mt-1" }, state.message)
1385
+ ),
1386
+ renderFields(),
1387
+ /* @__PURE__ */ React17.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React17.createElement(
1388
+ Button,
1389
+ {
1390
+ color: "primary",
1391
+ isDisabled: pending,
1392
+ isLoading: pending,
1393
+ type: "submit",
1394
+ ...submitButtonProps
1395
+ },
1396
+ submitButtonText
1397
+ ), showResetButton && /* @__PURE__ */ React17.createElement(
1398
+ Button,
1399
+ {
1400
+ isDisabled: pending,
1401
+ type: "button",
1402
+ variant: "bordered",
1403
+ onPress: handleReset
1404
+ },
1405
+ resetButtonText
1406
+ ))
1407
+ );
1408
+ }
1409
+ function ServerActionField({
1410
+ clientErrors,
1411
+ defaultValues,
1412
+ errors,
1413
+ field: field2
1414
+ }) {
1415
+ const fieldName = field2.name;
1416
+ const fieldErrors = errors?.[fieldName];
1417
+ const clientError = clientErrors?.[fieldName];
1418
+ const errorMessage = clientError || (fieldErrors && fieldErrors.length > 0 ? fieldErrors[0] : void 0);
1419
+ const getDefaultValue = () => {
1420
+ const fromProps = defaultValues?.[fieldName];
1421
+ const fromField = field2.defaultValue;
1422
+ if (fromProps !== void 0 && fromProps !== null) {
1423
+ return typeof fromProps === "string" ? fromProps : String(fromProps);
1424
+ }
1425
+ if (fromField !== void 0 && fromField !== null) {
1426
+ return typeof fromField === "string" ? fromField : String(fromField);
1427
+ }
1428
+ return "";
1429
+ };
1430
+ const getDefaultChecked = () => {
1431
+ const fromProps = defaultValues?.[fieldName];
1432
+ const fromField = field2.defaultValue;
1433
+ if (fromProps !== void 0 && fromProps !== null) {
1434
+ return typeof fromProps === "boolean" ? fromProps : false;
1435
+ }
1436
+ if (fromField !== void 0 && fromField !== null) {
1437
+ return typeof fromField === "boolean" ? fromField : false;
1438
+ }
1439
+ return false;
1440
+ };
1441
+ const [value, setValue] = React17.useState(getDefaultValue);
1442
+ const [checked, setChecked] = React17.useState(getDefaultChecked);
1443
+ React17.useEffect(() => {
1444
+ const newDefaultValue = defaultValues?.[fieldName];
1445
+ if (newDefaultValue !== void 0 && newDefaultValue !== null) {
1446
+ if (field2.type === "checkbox") {
1447
+ setChecked(
1448
+ typeof newDefaultValue === "boolean" ? newDefaultValue : false
1449
+ );
1450
+ } else {
1451
+ setValue(
1452
+ typeof newDefaultValue === "string" ? newDefaultValue : String(newDefaultValue)
1453
+ );
1454
+ }
1455
+ }
1456
+ }, [defaultValues, fieldName, field2.type]);
1457
+ React17.useEffect(() => {
1458
+ const hiddenInput = document.querySelector(
1459
+ `input[type="hidden"][name="${fieldName}"]`
1460
+ );
1461
+ if (hiddenInput) {
1462
+ if (field2.type === "checkbox") {
1463
+ hiddenInput.value = checked ? "on" : "";
1464
+ } else {
1465
+ hiddenInput.value = value;
1466
+ }
1467
+ }
1468
+ }, [value, checked, fieldName, field2.type]);
1469
+ switch (field2.type) {
1470
+ case "input": {
1471
+ const inputType = field2.inputProps?.type || "text";
1472
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
1473
+ Input,
1474
+ {
1475
+ ...field2.inputProps,
1476
+ "data-field-name": fieldName,
1477
+ type: inputType,
1478
+ label: field2.label,
1479
+ description: field2.description,
1480
+ isDisabled: field2.isDisabled,
1481
+ isInvalid: Boolean(errorMessage),
1482
+ errorMessage,
1483
+ value,
1484
+ onValueChange: setValue
1485
+ }
1486
+ ));
1487
+ }
1488
+ case "textarea": {
1489
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
1490
+ Textarea,
1491
+ {
1492
+ ...field2.textareaProps,
1493
+ "data-field-name": fieldName,
1494
+ label: field2.label,
1495
+ description: field2.description,
1496
+ isDisabled: field2.isDisabled,
1497
+ isInvalid: Boolean(errorMessage),
1498
+ errorMessage,
1499
+ value,
1500
+ onValueChange: setValue
1501
+ }
1502
+ ));
1503
+ }
1504
+ case "checkbox": {
1505
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value: checked ? "on" : "" }), /* @__PURE__ */ React17.createElement(
1506
+ Checkbox,
1507
+ {
1508
+ ...field2.checkboxProps,
1509
+ "data-field-name": fieldName,
1510
+ isDisabled: field2.isDisabled,
1511
+ isSelected: checked,
1512
+ onValueChange: setChecked,
1513
+ isInvalid: Boolean(errorMessage),
1514
+ errorMessage
1515
+ },
1516
+ field2.label
1517
+ ));
1518
+ }
1519
+ case "select": {
1520
+ const options = field2.options || [];
1521
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
1522
+ Select,
1523
+ {
1524
+ ...field2.selectProps,
1525
+ "data-field-name": fieldName,
1526
+ label: field2.label,
1527
+ description: field2.description,
1528
+ isDisabled: field2.isDisabled,
1529
+ isInvalid: Boolean(errorMessage),
1530
+ errorMessage,
1531
+ selectedKeys: value ? [value] : [],
1532
+ onSelectionChange: (keys) => {
1533
+ const selectedValue = Array.from(keys)[0];
1534
+ setValue(selectedValue || "");
1535
+ }
1536
+ },
1537
+ options.map(
1538
+ (option) => /* @__PURE__ */ React17.createElement(SelectItem, { key: String(option.value) }, option.label)
1539
+ )
1540
+ ));
1541
+ }
1542
+ default:
1543
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("input", { type: "hidden", name: fieldName, value }), /* @__PURE__ */ React17.createElement(
1544
+ Input,
1545
+ {
1546
+ "data-field-name": fieldName,
1547
+ label: field2.label,
1548
+ description: field2.description,
1549
+ isDisabled: field2.isDisabled,
1550
+ isInvalid: Boolean(errorMessage),
1551
+ errorMessage,
1552
+ value,
1553
+ onValueChange: setValue
1554
+ }
1555
+ ));
1556
+ }
1557
+ }
1558
+
1227
1559
  // src/hooks/useHeroForm.ts
1228
1560
  import { useFormContext as useFormContext4 } from "react-hook-form";
1229
1561
  function useHeroForm() {
@@ -1238,10 +1570,10 @@ function useHeroForm() {
1238
1570
  }
1239
1571
 
1240
1572
  // src/providers/FormProvider.tsx
1241
- import React17 from "react";
1573
+ import React18 from "react";
1242
1574
  import { FormProvider as RHFProvider } from "react-hook-form";
1243
1575
  function FormProvider(props) {
1244
- return /* @__PURE__ */ React17.createElement(RHFProvider, { ...props.methods }, /* @__PURE__ */ React17.createElement(
1576
+ return /* @__PURE__ */ React18.createElement(RHFProvider, { ...props.methods }, /* @__PURE__ */ React18.createElement(
1245
1577
  "form",
1246
1578
  {
1247
1579
  className: props.className,
@@ -1254,7 +1586,7 @@ function FormProvider(props) {
1254
1586
  }
1255
1587
 
1256
1588
  // src/submit/SubmitButton.tsx
1257
- import React18 from "react";
1589
+ import React19 from "react";
1258
1590
  function SubmitButton(props) {
1259
1591
  const ctx = useFormContext5();
1260
1592
  const loading = props.isLoading ?? ctx.formState.isSubmitting;
@@ -1264,10 +1596,10 @@ function SubmitButton(props) {
1264
1596
  const defaults = useHeroHookFormDefaults();
1265
1597
  const getButtonContent = () => {
1266
1598
  if (enhancedState?.isSuccess) {
1267
- return /* @__PURE__ */ React18.createElement("span", { className: "inline-flex items-center gap-2" }, "\u2705", props.successText || "Success!");
1599
+ return /* @__PURE__ */ React19.createElement("span", { className: "inline-flex items-center gap-2" }, "\u2705", props.successText || "Success!");
1268
1600
  }
1269
1601
  if (loading) {
1270
- return /* @__PURE__ */ React18.createElement("span", { className: "inline-flex items-center gap-2" }, "\u23F3", props.loadingText || "Submitting...");
1602
+ return /* @__PURE__ */ React19.createElement("span", { className: "inline-flex items-center gap-2" }, "\u23F3", props.loadingText || "Submitting...");
1271
1603
  }
1272
1604
  return props.children;
1273
1605
  };
@@ -1280,7 +1612,7 @@ function SubmitButton(props) {
1280
1612
  }
1281
1613
  return props.buttonProps?.color || defaults.submitButton.color;
1282
1614
  };
1283
- return /* @__PURE__ */ React18.createElement(
1615
+ return /* @__PURE__ */ React19.createElement(
1284
1616
  Button,
1285
1617
  {
1286
1618
  type: "submit",
@@ -1429,14 +1761,6 @@ var createPasswordSchema = (minLength = 8) => z.string().min(minLength, `Passwor
1429
1761
  /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/,
1430
1762
  "Password must contain at least one uppercase letter, one lowercase letter, and one number"
1431
1763
  );
1432
- var createConfirmPasswordSchema = (passwordField) => z.string().refine(
1433
- (val) => {
1434
- return true;
1435
- },
1436
- {
1437
- message: "Passwords do not match"
1438
- }
1439
- );
1440
1764
  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
1765
  var createDateSchema = (fieldName) => z.date({ message: `${fieldName} is required` });
1442
1766
  var createFutureDateSchema = (fieldName) => z.date({ message: `${fieldName} is required` }).refine((date) => date > /* @__PURE__ */ new Date(), {
@@ -1455,44 +1779,24 @@ var createFileSchema = (maxSizeInMB = 5, allowedTypes = ["image/jpeg", "image/pn
1455
1779
  var createRequiredCheckboxSchema = (fieldName) => z.boolean().refine((val) => val === true, {
1456
1780
  message: `You must agree to ${fieldName}`
1457
1781
  });
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
1782
  var crossFieldValidation = {
1484
1783
  /**
1485
- * Password confirmation validation
1784
+ * Conditional required field validation
1486
1785
  */
1487
- passwordConfirmation: (passwordField, confirmField) => {
1786
+ conditionalRequired: (field2, conditionField, conditionValue) => {
1488
1787
  return z.object({
1489
- [passwordField]: z.string(),
1490
- [confirmField]: z.string()
1788
+ [conditionField]: z.any(),
1789
+ [field2]: z.string()
1491
1790
  }).refine(
1492
- (data) => data[passwordField] === data[confirmField],
1791
+ (data) => {
1792
+ if (data[conditionField] === conditionValue) {
1793
+ return data[field2] && data[field2].trim().length > 0;
1794
+ }
1795
+ return true;
1796
+ },
1493
1797
  {
1494
- message: "Passwords do not match",
1495
- path: [confirmField]
1798
+ message: "This field is required",
1799
+ path: [field2]
1496
1800
  }
1497
1801
  );
1498
1802
  },
@@ -1501,8 +1805,8 @@ var crossFieldValidation = {
1501
1805
  */
1502
1806
  dateRange: (startField, endField) => {
1503
1807
  return z.object({
1504
- [startField]: z.string(),
1505
- [endField]: z.string()
1808
+ [endField]: z.string(),
1809
+ [startField]: z.string()
1506
1810
  }).refine(
1507
1811
  (data) => {
1508
1812
  const startDate = new Date(data[startField]);
@@ -1516,39 +1820,47 @@ var crossFieldValidation = {
1516
1820
  );
1517
1821
  },
1518
1822
  /**
1519
- * Conditional required field validation
1823
+ * Password confirmation validation
1520
1824
  */
1521
- conditionalRequired: (field2, conditionField, conditionValue) => {
1825
+ passwordConfirmation: (passwordField, confirmField) => {
1522
1826
  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
- );
1827
+ [confirmField]: z.string(),
1828
+ [passwordField]: z.string()
1829
+ }).refine((data) => data[passwordField] === data[confirmField], {
1830
+ message: "Passwords do not match",
1831
+ path: [confirmField]
1832
+ });
1537
1833
  }
1538
1834
  };
1835
+ var commonValidations = {
1836
+ confirmPassword: (passwordField, confirmField) => crossFieldValidation.passwordConfirmation(passwordField, confirmField),
1837
+ date: (fieldName) => createDateSchema(fieldName),
1838
+ email: createEmailSchema(),
1839
+ file: (maxSizeInMB, allowedTypes) => createFileSchema(maxSizeInMB, allowedTypes),
1840
+ futureDate: (fieldName) => createFutureDateSchema(fieldName),
1841
+ maxLength: (max, fieldName) => createMaxLengthSchema(max, fieldName),
1842
+ minLength: (min, fieldName) => createMinLengthSchema(min, fieldName),
1843
+ numberRange: (min, max, fieldName) => createNumberRangeSchema(min, max, fieldName),
1844
+ password: (minLength) => createPasswordSchema(minLength),
1845
+ pastDate: (fieldName) => createPastDateSchema(fieldName),
1846
+ phone: createPhoneSchema(),
1847
+ required: (fieldName) => createRequiredSchema(fieldName),
1848
+ requiredCheckbox: (fieldName) => createRequiredCheckboxSchema(fieldName),
1849
+ url: createUrlSchema()
1850
+ };
1539
1851
 
1540
1852
  // src/index.ts
1541
1853
  import { useFormContext as useFormContext5 } from "react-hook-form";
1542
1854
 
1543
1855
  // src/components/ZodForm.tsx
1544
- import React20 from "react";
1856
+ import React21 from "react";
1545
1857
  import { Button as Button5 } from "@heroui/react";
1546
1858
 
1547
1859
  // src/zod-integration.ts
1548
1860
  import { useForm as useForm2 } from "react-hook-form";
1549
1861
  import { z as z2 } from "zod";
1550
1862
  function createZodResolver(schema) {
1551
- return async (values, context) => {
1863
+ return async (values) => {
1552
1864
  try {
1553
1865
  const result = await schema.parseAsync(values);
1554
1866
  return {
@@ -1579,9 +1891,11 @@ function useZodForm(config) {
1579
1891
  }
1580
1892
  function createZodFormConfig(schema, fields, defaultValues) {
1581
1893
  return {
1582
- schema,
1583
1894
  fields,
1584
- ...defaultValues && { defaultValues }
1895
+ schema,
1896
+ ...defaultValues && {
1897
+ defaultValues
1898
+ }
1585
1899
  };
1586
1900
  }
1587
1901
 
@@ -1589,18 +1903,20 @@ function createZodFormConfig(schema, fields, defaultValues) {
1589
1903
  import { useCallback, useEffect, useState as useState2 } from "react";
1590
1904
  function useEnhancedFormState(form, options = {}) {
1591
1905
  const {
1592
- onSuccess,
1593
- onError,
1594
- successMessage = "Form submitted successfully!",
1595
- errorMessage = "An error occurred. Please try again.",
1596
1906
  autoReset = true,
1597
- resetDelay = 3e3
1907
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1908
+ errorMessage: _errorMessage = "An error occurred. Please try again.",
1909
+ onError,
1910
+ onSuccess,
1911
+ resetDelay = 3e3,
1912
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1913
+ successMessage: _successMessage = "Form submitted successfully!"
1598
1914
  } = options;
1599
1915
  const [status, setStatus] = useState2("idle");
1600
1916
  const [error, setError] = useState2(void 0);
1601
1917
  const [submittedData, setSubmittedData] = useState2(void 0);
1602
- const { formState, getValues } = form;
1603
- const { errors, touchedFields, dirtyFields, isSubmitting } = formState;
1918
+ const { formState, getValues: _getValues } = form;
1919
+ const { dirtyFields, errors, isSubmitting, touchedFields } = formState;
1604
1920
  useEffect(() => {
1605
1921
  if (isSubmitting) {
1606
1922
  setStatus("submitting");
@@ -1616,92 +1932,123 @@ function useEnhancedFormState(form, options = {}) {
1616
1932
  return () => clearTimeout(timer);
1617
1933
  }
1618
1934
  }, [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]);
1935
+ const handleSuccess = useCallback(
1936
+ (data) => {
1937
+ setStatus("success");
1938
+ setSubmittedData(data);
1939
+ setError(void 0);
1940
+ onSuccess?.(data);
1941
+ },
1942
+ [onSuccess]
1943
+ );
1944
+ const handleError = useCallback(
1945
+ (errorMessage) => {
1946
+ setStatus("error");
1947
+ setError(errorMessage);
1948
+ setSubmittedData(void 0);
1949
+ onError?.(errorMessage);
1950
+ },
1951
+ [onError]
1952
+ );
1631
1953
  const reset = useCallback(() => {
1632
1954
  setStatus("idle");
1633
1955
  setError(void 0);
1634
1956
  setSubmittedData(void 0);
1635
1957
  }, []);
1636
1958
  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
1959
  dirtyFields: new Set(Object.keys(dirtyFields)),
1645
- hasErrors: Object.keys(errors).length > 0,
1960
+ error,
1646
1961
  errorCount: Object.keys(errors).length,
1647
- handleSuccess,
1648
1962
  handleError,
1649
- reset
1963
+ handleSuccess,
1964
+ hasErrors: Object.keys(errors).length > 0,
1965
+ isError: status === "error",
1966
+ isSubmitting,
1967
+ isSuccess: status === "success",
1968
+ reset,
1969
+ status,
1970
+ submittedData,
1971
+ touchedFields: new Set(Object.keys(touchedFields))
1650
1972
  };
1651
1973
  }
1652
1974
 
1653
1975
  // src/components/FormStatus.tsx
1654
- import React19 from "react";
1976
+ import React20 from "react";
1655
1977
  import { Button as Button4 } from "@heroui/react";
1656
1978
  function FormStatus({
1657
- state,
1658
- onDismiss,
1659
1979
  className = "",
1660
- showDetails = false
1980
+ onDismiss,
1981
+ showDetails = false,
1982
+ state
1661
1983
  }) {
1662
- const { status, isSubmitting, isSuccess, isError, error, submittedData } = state;
1984
+ const { error, isError, isSubmitting, isSuccess, status, submittedData } = state;
1663
1985
  if (status === "idle") {
1664
1986
  return null;
1665
1987
  }
1666
1988
  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.")));
1989
+ return /* @__PURE__ */ React20.createElement(
1990
+ "div",
1991
+ {
1992
+ className: `flex items-center gap-3 p-4 bg-blue-50 border border-blue-200 rounded-lg ${className}`
1993
+ },
1994
+ /* @__PURE__ */ React20.createElement("span", { className: "text-blue-600" }, "\u23F3"),
1995
+ /* @__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."))
1996
+ );
1668
1997
  }
1669
1998
  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,
1999
+ return /* @__PURE__ */ React20.createElement(
2000
+ "div",
1672
2001
  {
1673
- size: "sm",
1674
- variant: "light",
1675
- isIconOnly: true,
1676
- onPress: onDismiss,
1677
- "aria-label": "Dismiss success message"
2002
+ className: `flex items-center gap-3 p-4 bg-green-50 border border-green-200 rounded-lg ${className}`,
2003
+ "data-testid": "success-message"
1678
2004
  },
1679
- "\u2715"
1680
- ));
2005
+ /* @__PURE__ */ React20.createElement("span", { className: "text-green-600" }, "\u2705"),
2006
+ /* @__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.")),
2007
+ onDismiss && /* @__PURE__ */ React20.createElement(
2008
+ Button4,
2009
+ {
2010
+ size: "sm",
2011
+ variant: "light",
2012
+ isIconOnly: true,
2013
+ onPress: onDismiss,
2014
+ "aria-label": "Dismiss success message"
2015
+ },
2016
+ "\u2715"
2017
+ )
2018
+ );
1681
2019
  }
1682
2020
  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,
2021
+ return /* @__PURE__ */ React20.createElement(
2022
+ "div",
1685
2023
  {
1686
- size: "sm",
1687
- variant: "light",
1688
- isIconOnly: true,
1689
- onPress: onDismiss,
1690
- "aria-label": "Dismiss error message"
2024
+ className: `flex items-center gap-3 p-4 bg-red-50 border border-red-200 rounded-lg ${className}`,
2025
+ "data-testid": "error-message"
1691
2026
  },
1692
- "\u2715"
1693
- ));
2027
+ /* @__PURE__ */ React20.createElement("span", { className: "text-red-600" }, "\u26A0\uFE0F"),
2028
+ /* @__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)),
2029
+ onDismiss && /* @__PURE__ */ React20.createElement(
2030
+ Button4,
2031
+ {
2032
+ size: "sm",
2033
+ variant: "light",
2034
+ isIconOnly: true,
2035
+ onPress: onDismiss,
2036
+ "aria-label": "Dismiss error message"
2037
+ },
2038
+ "\u2715"
2039
+ )
2040
+ );
1694
2041
  }
1695
2042
  return null;
1696
2043
  }
1697
2044
  function FormToast({
1698
- state,
2045
+ duration = 5e3,
1699
2046
  onDismiss,
1700
2047
  position = "top-right",
1701
- duration = 5e3
2048
+ state
1702
2049
  }) {
1703
- const [isVisible, setIsVisible] = React19.useState(false);
1704
- React19.useEffect(() => {
2050
+ const [isVisible, setIsVisible] = React20.useState(false);
2051
+ React20.useEffect(() => {
1705
2052
  if (state.isSuccess || state.isError) {
1706
2053
  setIsVisible(true);
1707
2054
  if (duration > 0) {
@@ -1717,12 +2064,12 @@ function FormToast({
1717
2064
  return null;
1718
2065
  }
1719
2066
  const positionClasses = {
1720
- "top-right": "top-4 right-4",
1721
- "top-left": "top-4 left-4",
2067
+ "bottom-left": "bottom-4 left-4",
1722
2068
  "bottom-right": "bottom-4 right-4",
1723
- "bottom-left": "bottom-4 left-4"
2069
+ "top-left": "top-4 left-4",
2070
+ "top-right": "top-4 right-4"
1724
2071
  };
1725
- return /* @__PURE__ */ React19.createElement("div", { className: `fixed z-50 ${positionClasses[position]}` }, /* @__PURE__ */ React19.createElement(FormStatus, { state, onDismiss }));
2072
+ return /* @__PURE__ */ React20.createElement("div", { className: `fixed z-50 ${positionClasses[position]}` }, /* @__PURE__ */ React20.createElement(FormStatus, { state, onDismiss }));
1726
2073
  }
1727
2074
 
1728
2075
  // src/components/ZodForm.tsx
@@ -1730,7 +2077,6 @@ function ZodForm({
1730
2077
  className,
1731
2078
  columns = 1,
1732
2079
  config,
1733
- errorDisplay = "inline",
1734
2080
  layout = "vertical",
1735
2081
  onError,
1736
2082
  onSubmit,
@@ -1746,9 +2092,9 @@ function ZodForm({
1746
2092
  }) {
1747
2093
  const form = useZodForm(config);
1748
2094
  const enhancedState = useEnhancedFormState(form, {
1749
- onSuccess,
1750
- onError: (error) => onError?.({ message: error, field: "form" }),
1751
2095
  autoReset: true,
2096
+ onError: (error) => onError?.({ field: "form", message: error }),
2097
+ onSuccess,
1752
2098
  resetDelay: 3e3
1753
2099
  });
1754
2100
  const handleSubmit = async () => {
@@ -1758,7 +2104,8 @@ function ZodForm({
1758
2104
  await onSubmit(formData);
1759
2105
  enhancedState.handleSuccess(formData);
1760
2106
  },
1761
- (errors) => {
2107
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2108
+ (_errors) => {
1762
2109
  enhancedState.handleError("Please fix the validation errors above");
1763
2110
  }
1764
2111
  )();
@@ -1773,54 +2120,54 @@ function ZodForm({
1773
2120
  };
1774
2121
  const renderFields = () => {
1775
2122
  if (layout === "grid") {
1776
- return /* @__PURE__ */ React20.createElement(
2123
+ return /* @__PURE__ */ React21.createElement(
1777
2124
  "div",
1778
2125
  {
1779
2126
  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
2127
  },
1781
- config.fields.map((field2) => /* @__PURE__ */ React20.createElement(
2128
+ config.fields.map((field2) => /* @__PURE__ */ React21.createElement(
1782
2129
  FormField,
1783
2130
  {
1784
2131
  key: field2.name,
1785
2132
  config: field2,
1786
2133
  form,
1787
2134
  submissionState: {
1788
- isSubmitting: enhancedState.isSubmitting,
2135
+ error: enhancedState.error,
1789
2136
  isSubmitted: enhancedState.status !== "idle",
1790
- isSuccess: enhancedState.isSuccess,
1791
- error: enhancedState.error
2137
+ isSubmitting: enhancedState.isSubmitting,
2138
+ isSuccess: enhancedState.isSuccess
1792
2139
  }
1793
2140
  }
1794
2141
  ))
1795
2142
  );
1796
2143
  }
1797
2144
  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(
2145
+ return /* @__PURE__ */ React21.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, config.fields.map((field2) => /* @__PURE__ */ React21.createElement(
1799
2146
  FormField,
1800
2147
  {
1801
2148
  key: field2.name,
1802
2149
  config: field2,
1803
2150
  form,
1804
2151
  submissionState: {
1805
- isSubmitting: enhancedState.isSubmitting,
2152
+ error: enhancedState.error,
1806
2153
  isSubmitted: enhancedState.status !== "idle",
1807
- isSuccess: enhancedState.isSuccess,
1808
- error: enhancedState.error
2154
+ isSubmitting: enhancedState.isSubmitting,
2155
+ isSuccess: enhancedState.isSuccess
1809
2156
  }
1810
2157
  }
1811
2158
  )));
1812
2159
  }
1813
- return /* @__PURE__ */ React20.createElement("div", { className: `space-y-${spacing}` }, config.fields.map((field2) => /* @__PURE__ */ React20.createElement(
2160
+ return /* @__PURE__ */ React21.createElement("div", { className: `space-y-${spacing}` }, config.fields.map((field2) => /* @__PURE__ */ React21.createElement(
1814
2161
  FormField,
1815
2162
  {
1816
2163
  key: field2.name,
1817
2164
  config: field2,
1818
2165
  form,
1819
2166
  submissionState: {
1820
- isSubmitting: enhancedState.isSubmitting,
2167
+ error: enhancedState.error,
1821
2168
  isSubmitted: enhancedState.status !== "idle",
1822
- isSuccess: enhancedState.isSuccess,
1823
- error: enhancedState.error
2169
+ isSubmitting: enhancedState.isSubmitting,
2170
+ isSuccess: enhancedState.isSuccess
1824
2171
  }
1825
2172
  }
1826
2173
  )));
@@ -1829,7 +2176,7 @@ function ZodForm({
1829
2176
  e.preventDefault();
1830
2177
  void handleSubmit();
1831
2178
  };
1832
- React20.useEffect(() => {
2179
+ React21.useEffect(() => {
1833
2180
  if (config.onError && Object.keys(form.formState.errors).length > 0) {
1834
2181
  config.onError(form.formState.errors);
1835
2182
  }
@@ -1844,14 +2191,14 @@ function ZodForm({
1844
2191
  values: form.getValues()
1845
2192
  });
1846
2193
  }
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(
2194
+ 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
2195
  FormStatus,
1849
2196
  {
1850
2197
  state: enhancedState,
1851
2198
  onDismiss: () => enhancedState.reset(),
1852
2199
  showDetails: true
1853
2200
  }
1854
- ), renderFields(), /* @__PURE__ */ React20.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React20.createElement(
2201
+ ), renderFields(), /* @__PURE__ */ React21.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ React21.createElement(
1855
2202
  Button5,
1856
2203
  {
1857
2204
  color: "primary",
@@ -1861,7 +2208,7 @@ function ZodForm({
1861
2208
  ...submitButtonProps
1862
2209
  },
1863
2210
  enhancedState.isSuccess ? "Success!" : submitButtonText
1864
- ), showResetButton && /* @__PURE__ */ React20.createElement(
2211
+ ), showResetButton && /* @__PURE__ */ React21.createElement(
1865
2212
  Button5,
1866
2213
  {
1867
2214
  isDisabled: enhancedState.isSubmitting,
@@ -1883,10 +2230,10 @@ var BasicFormBuilder = class {
1883
2230
  */
1884
2231
  input(name, label, type = "text") {
1885
2232
  this.fields.push({
1886
- name,
2233
+ inputProps: { type },
1887
2234
  label,
1888
- type: "input",
1889
- inputProps: { type }
2235
+ name,
2236
+ type: "input"
1890
2237
  });
1891
2238
  return this;
1892
2239
  }
@@ -1895,10 +2242,10 @@ var BasicFormBuilder = class {
1895
2242
  */
1896
2243
  textarea(name, label, placeholder) {
1897
2244
  this.fields.push({
1898
- name,
1899
2245
  label,
1900
- type: "textarea",
1901
- textareaProps: { placeholder }
2246
+ name,
2247
+ textareaProps: { placeholder },
2248
+ type: "textarea"
1902
2249
  });
1903
2250
  return this;
1904
2251
  }
@@ -1907,10 +2254,10 @@ var BasicFormBuilder = class {
1907
2254
  */
1908
2255
  select(name, label, options) {
1909
2256
  this.fields.push({
1910
- name,
1911
2257
  label,
1912
- type: "select",
1913
- options
2258
+ name,
2259
+ options,
2260
+ type: "select"
1914
2261
  });
1915
2262
  return this;
1916
2263
  }
@@ -1919,8 +2266,8 @@ var BasicFormBuilder = class {
1919
2266
  */
1920
2267
  checkbox(name, label) {
1921
2268
  this.fields.push({
1922
- name,
1923
2269
  label,
2270
+ name,
1924
2271
  type: "checkbox"
1925
2272
  });
1926
2273
  return this;
@@ -1930,8 +2277,8 @@ var BasicFormBuilder = class {
1930
2277
  */
1931
2278
  switch(name, label) {
1932
2279
  this.fields.push({
1933
- name,
1934
2280
  label,
2281
+ name,
1935
2282
  type: "switch"
1936
2283
  });
1937
2284
  return this;
@@ -1948,59 +2295,50 @@ function createBasicFormBuilder() {
1948
2295
  }
1949
2296
  var FormFieldHelpers = {
1950
2297
  /**
1951
- * Create an input field
2298
+ * Create a checkbox field
1952
2299
  */
1953
- input: (name, label, type = "text") => ({
1954
- name,
2300
+ checkbox: (name, label) => ({
1955
2301
  label,
1956
- type: "input",
1957
- inputProps: { type }
2302
+ name,
2303
+ type: "checkbox"
1958
2304
  }),
1959
2305
  /**
1960
- * Create a textarea field
2306
+ * Create an input field
1961
2307
  */
1962
- textarea: (name, label, placeholder) => ({
1963
- name,
2308
+ input: (name, label, type = "text") => ({
2309
+ inputProps: { type },
1964
2310
  label,
1965
- type: "textarea",
1966
- textareaProps: { placeholder }
2311
+ name,
2312
+ type: "input"
1967
2313
  }),
1968
2314
  /**
1969
2315
  * Create a select field
1970
2316
  */
1971
2317
  select: (name, label, options) => ({
1972
- name,
1973
2318
  label,
1974
- type: "select",
1975
- options
1976
- }),
1977
- /**
1978
- * Create a checkbox field
1979
- */
1980
- checkbox: (name, label) => ({
1981
2319
  name,
1982
- label,
1983
- type: "checkbox"
2320
+ options,
2321
+ type: "select"
1984
2322
  }),
1985
2323
  /**
1986
2324
  * Create a switch field
1987
2325
  */
1988
2326
  switch: (name, label) => ({
1989
- name,
1990
2327
  label,
2328
+ name,
1991
2329
  type: "switch"
2330
+ }),
2331
+ /**
2332
+ * Create a textarea field
2333
+ */
2334
+ textarea: (name, label, placeholder) => ({
2335
+ label,
2336
+ name,
2337
+ textareaProps: { placeholder },
2338
+ type: "textarea"
1992
2339
  })
1993
2340
  };
1994
2341
  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
2342
  /**
2005
2343
  * Address fields
2006
2344
  */
@@ -2009,107 +2347,121 @@ var CommonFields = {
2009
2347
  FormFieldHelpers.input("city", "City"),
2010
2348
  FormFieldHelpers.input("state", "State/Province"),
2011
2349
  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
- )
2350
+ FormFieldHelpers.select("country", "Country", [
2351
+ { label: "Select a country", value: "" },
2352
+ { label: "United States", value: "us" },
2353
+ { label: "Canada", value: "ca" },
2354
+ { label: "United Kingdom", value: "uk" },
2355
+ { label: "Australia", value: "au" },
2356
+ { label: "Germany", value: "de" },
2357
+ { label: "France", value: "fr" }
2358
+ ])
2359
+ ],
2360
+ /**
2361
+ * Personal information fields
2362
+ */
2363
+ personal: () => [
2364
+ FormFieldHelpers.input("firstName", "First Name"),
2365
+ FormFieldHelpers.input("lastName", "Last Name"),
2366
+ FormFieldHelpers.input("email", "Email", "email"),
2367
+ FormFieldHelpers.input("phone", "Phone", "tel")
2025
2368
  ],
2026
2369
  /**
2027
2370
  * Terms and conditions fields
2028
2371
  */
2029
2372
  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")
2373
+ FormFieldHelpers.checkbox(
2374
+ "terms",
2375
+ "I agree to the terms and conditions"
2376
+ ),
2377
+ FormFieldHelpers.checkbox(
2378
+ "privacy",
2379
+ "I agree to the privacy policy"
2380
+ ),
2381
+ FormFieldHelpers.checkbox(
2382
+ "newsletter",
2383
+ "Subscribe to newsletter"
2384
+ )
2033
2385
  ]
2034
2386
  };
2035
2387
 
2036
2388
  // src/builders/AdvancedFormBuilder.ts
2037
2389
  function inputField(name, label, props) {
2038
2390
  return {
2039
- name,
2040
2391
  label,
2392
+ name,
2041
2393
  type: "input",
2042
2394
  ...props && {
2043
2395
  inputProps: {
2044
- type: props.type || "text",
2045
- placeholder: props.placeholder,
2396
+ className: props.className,
2046
2397
  description: props.description,
2047
2398
  disabled: props.isDisabled,
2048
- className: props.className
2399
+ placeholder: props.placeholder,
2400
+ type: props.type || "text"
2049
2401
  }
2050
2402
  }
2051
2403
  };
2052
2404
  }
2053
2405
  function textareaField(name, label, props) {
2054
2406
  return {
2055
- name,
2056
2407
  label,
2408
+ name,
2057
2409
  type: "textarea",
2058
2410
  ...props && {
2059
2411
  textareaProps: {
2060
- placeholder: props.placeholder,
2412
+ className: props.className,
2061
2413
  description: props.description,
2062
2414
  disabled: props.isDisabled,
2063
- className: props.className,
2415
+ placeholder: props.placeholder,
2064
2416
  rows: props.rows
2065
2417
  }
2066
2418
  }
2067
2419
  };
2068
2420
  }
2069
- function selectField(name, label, options, props) {
2421
+ function selectField(name, label, options) {
2070
2422
  return {
2071
- name,
2072
2423
  label,
2073
- type: "select",
2074
- options
2424
+ name,
2425
+ options,
2426
+ type: "select"
2075
2427
  };
2076
2428
  }
2077
2429
  function checkboxField(name, label, props) {
2078
2430
  return {
2079
- name,
2080
2431
  label,
2432
+ name,
2081
2433
  type: "checkbox",
2082
2434
  ...props && {
2083
2435
  checkboxProps: {
2084
- disabled: props.isDisabled,
2085
- className: props.className
2436
+ className: props.className,
2437
+ disabled: props.isDisabled
2086
2438
  }
2087
2439
  }
2088
2440
  };
2089
2441
  }
2090
2442
  function switchField(name, label, props) {
2091
2443
  return {
2092
- name,
2093
2444
  label,
2445
+ name,
2094
2446
  type: "switch",
2095
2447
  ...props && {
2096
2448
  switchProps: {
2097
- disabled: props.isDisabled,
2098
- className: props.className
2449
+ className: props.className,
2450
+ disabled: props.isDisabled
2099
2451
  }
2100
2452
  }
2101
2453
  };
2102
2454
  }
2103
2455
  function radioField(name, label, options, props) {
2104
2456
  return {
2105
- name,
2106
2457
  label,
2107
- type: "radio",
2458
+ name,
2108
2459
  radioOptions: options,
2460
+ type: "radio",
2109
2461
  ...props && {
2110
2462
  radioProps: {
2111
- isDisabled: props.isDisabled,
2112
2463
  className: props.className,
2464
+ isDisabled: props.isDisabled,
2113
2465
  orientation: props.orientation
2114
2466
  }
2115
2467
  }
@@ -2117,58 +2469,58 @@ function radioField(name, label, options, props) {
2117
2469
  }
2118
2470
  function sliderField(name, label, props) {
2119
2471
  return {
2120
- name,
2121
2472
  label,
2473
+ name,
2122
2474
  type: "slider",
2123
2475
  ...props && {
2124
2476
  sliderProps: {
2125
- min: props.min || 0,
2126
- max: props.max || 100,
2127
- step: props.step || 1,
2477
+ className: props.className || "",
2128
2478
  disabled: props.isDisabled || false,
2129
- className: props.className || ""
2479
+ max: props.max || 100,
2480
+ min: props.min || 0,
2481
+ step: props.step || 1
2130
2482
  }
2131
2483
  }
2132
2484
  };
2133
2485
  }
2134
2486
  function dateField(name, label, props) {
2135
2487
  return {
2136
- name,
2137
2488
  label,
2489
+ name,
2138
2490
  type: "date",
2139
2491
  ...props && {
2140
2492
  dateProps: {
2141
- placeholder: props.placeholder || "",
2493
+ className: props.className || "",
2142
2494
  disabled: props.isDisabled || false,
2143
- className: props.className || ""
2495
+ placeholder: props.placeholder || ""
2144
2496
  }
2145
2497
  }
2146
2498
  };
2147
2499
  }
2148
2500
  function fileField(name, label, props) {
2149
2501
  return {
2150
- name,
2151
2502
  label,
2503
+ name,
2152
2504
  type: "file",
2153
2505
  ...props && {
2154
2506
  fileProps: {
2155
2507
  accept: props.accept || "",
2156
- multiple: props.multiple || false,
2508
+ className: props.className || "",
2157
2509
  disabled: props.isDisabled || false,
2158
- className: props.className || ""
2510
+ multiple: props.multiple || false
2159
2511
  }
2160
2512
  }
2161
2513
  };
2162
2514
  }
2163
2515
  function fontPickerField(name, label, props) {
2164
2516
  return {
2165
- name,
2166
2517
  label,
2518
+ name,
2167
2519
  type: "fontPicker",
2168
2520
  ...props && {
2169
2521
  fontPickerProps: {
2170
- disabled: props.isDisabled || false,
2171
- className: props.className || ""
2522
+ className: props.className || "",
2523
+ disabled: props.isDisabled || false
2172
2524
  }
2173
2525
  }
2174
2526
  };
@@ -2180,7 +2532,7 @@ function createField(type, name, label, optionsOrProps, props) {
2180
2532
  case "textarea":
2181
2533
  return textareaField(name, label, optionsOrProps);
2182
2534
  case "select":
2183
- return selectField(name, label, optionsOrProps, props);
2535
+ return selectField(name, label, optionsOrProps);
2184
2536
  case "checkbox":
2185
2537
  return checkboxField(name, label, optionsOrProps);
2186
2538
  case "switch":
@@ -2212,10 +2564,10 @@ var AdvancedFieldBuilder = class {
2212
2564
  */
2213
2565
  conditionalField(name, condition, field2) {
2214
2566
  this.fields.push({
2215
- name,
2216
- type: "conditional",
2217
2567
  condition,
2218
- field: field2
2568
+ field: field2,
2569
+ name,
2570
+ type: "conditional"
2219
2571
  });
2220
2572
  return this;
2221
2573
  }
@@ -2224,14 +2576,14 @@ var AdvancedFieldBuilder = class {
2224
2576
  */
2225
2577
  fieldArray(name, label, fields, options) {
2226
2578
  this.fields.push({
2227
- name,
2228
- label,
2229
- type: "fieldArray",
2579
+ addButtonText: options?.addButtonText,
2230
2580
  fields,
2231
- min: options?.min,
2581
+ label,
2232
2582
  max: options?.max,
2233
- addButtonText: options?.addButtonText,
2234
- removeButtonText: options?.removeButtonText
2583
+ min: options?.min,
2584
+ name,
2585
+ removeButtonText: options?.removeButtonText,
2586
+ type: "fieldArray"
2235
2587
  });
2236
2588
  return this;
2237
2589
  }
@@ -2240,12 +2592,12 @@ var AdvancedFieldBuilder = class {
2240
2592
  */
2241
2593
  dynamicSection(name, condition, fields, options) {
2242
2594
  this.fields.push({
2243
- name,
2244
- type: "dynamicSection",
2245
2595
  condition,
2596
+ description: options?.description,
2246
2597
  fields,
2598
+ name,
2247
2599
  title: options?.title,
2248
- description: options?.description
2600
+ type: "dynamicSection"
2249
2601
  });
2250
2602
  return this;
2251
2603
  }
@@ -2281,7 +2633,13 @@ var FieldArrayBuilder = class {
2281
2633
  }
2282
2634
  field(type, name, label, optionsOrProps, props) {
2283
2635
  const fullPath = `${this.arrayName}.${name}`;
2284
- const fieldConfig = createField(type, fullPath, label, optionsOrProps, props);
2636
+ const fieldConfig = createField(
2637
+ type,
2638
+ fullPath,
2639
+ label,
2640
+ optionsOrProps,
2641
+ props
2642
+ );
2285
2643
  this.fields.push(fieldConfig);
2286
2644
  return this;
2287
2645
  }
@@ -2307,17 +2665,29 @@ var TypeInferredBuilder = class {
2307
2665
  * Add a text field
2308
2666
  */
2309
2667
  text(name, label, options) {
2310
- const { minLength, maxLength, pattern, ...fieldOptions } = options || {};
2668
+ const { maxLength, minLength, pattern, ...fieldOptions } = options || {};
2311
2669
  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`);
2670
+ if (minLength)
2671
+ zodType = zodType.min(
2672
+ minLength,
2673
+ `${label} must be at least ${minLength} characters`
2674
+ );
2675
+ if (maxLength)
2676
+ zodType = zodType.max(
2677
+ maxLength,
2678
+ `${label} must be no more than ${maxLength} characters`
2679
+ );
2680
+ if (pattern)
2681
+ zodType = zodType.regex(
2682
+ new RegExp(pattern),
2683
+ `${label} format is invalid`
2684
+ );
2315
2685
  this.schemaFields[name] = zodType;
2316
2686
  this.formFields.push({
2317
- name,
2687
+ inputProps: { type: "text", ...fieldOptions },
2318
2688
  label,
2319
- type: "input",
2320
- inputProps: { type: "text", ...fieldOptions }
2689
+ name,
2690
+ type: "input"
2321
2691
  });
2322
2692
  return this;
2323
2693
  }
@@ -2327,10 +2697,10 @@ var TypeInferredBuilder = class {
2327
2697
  email(name, label, options) {
2328
2698
  this.schemaFields[name] = z3.string().email(`Please enter a valid email address`);
2329
2699
  this.formFields.push({
2330
- name,
2700
+ inputProps: { type: "email", ...options },
2331
2701
  label,
2332
- type: "input",
2333
- inputProps: { type: "email", ...options }
2702
+ name,
2703
+ type: "input"
2334
2704
  });
2335
2705
  return this;
2336
2706
  }
@@ -2338,16 +2708,18 @@ var TypeInferredBuilder = class {
2338
2708
  * Add a number field
2339
2709
  */
2340
2710
  number(name, label, options) {
2341
- const { min, max, step, ...fieldOptions } = options || {};
2711
+ const { max, min, step, ...fieldOptions } = options || {};
2342
2712
  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}`);
2713
+ if (min !== void 0)
2714
+ zodType = zodType.min(min, `${label} must be at least ${min}`);
2715
+ if (max !== void 0)
2716
+ zodType = zodType.max(max, `${label} must be no more than ${max}`);
2345
2717
  this.schemaFields[name] = zodType;
2346
2718
  this.formFields.push({
2347
- name,
2719
+ inputProps: { max, min, step, type: "number", ...fieldOptions },
2348
2720
  label,
2349
- type: "input",
2350
- inputProps: { type: "number", min, max, step, ...fieldOptions }
2721
+ name,
2722
+ type: "input"
2351
2723
  });
2352
2724
  return this;
2353
2725
  }
@@ -2357,26 +2729,30 @@ var TypeInferredBuilder = class {
2357
2729
  textarea(name, label, options) {
2358
2730
  const { minLength, ...fieldOptions } = options || {};
2359
2731
  let zodType = z3.string();
2360
- if (minLength) zodType = zodType.min(minLength, `${label} must be at least ${minLength} characters`);
2732
+ if (minLength)
2733
+ zodType = zodType.min(
2734
+ minLength,
2735
+ `${label} must be at least ${minLength} characters`
2736
+ );
2361
2737
  this.schemaFields[name] = zodType;
2362
2738
  this.formFields.push({
2363
- name,
2364
2739
  label,
2365
- type: "textarea",
2366
- textareaProps: fieldOptions
2740
+ name,
2741
+ textareaProps: fieldOptions,
2742
+ type: "textarea"
2367
2743
  });
2368
2744
  return this;
2369
2745
  }
2370
2746
  /**
2371
2747
  * Add a select field
2372
2748
  */
2373
- select(name, label, options, fieldOptions) {
2749
+ select(name, label, options) {
2374
2750
  this.schemaFields[name] = z3.string().min(1, `Please select a ${label.toLowerCase()}`);
2375
2751
  this.formFields.push({
2376
- name,
2377
2752
  label,
2378
- type: "select",
2379
- options
2753
+ name,
2754
+ options,
2755
+ type: "select"
2380
2756
  });
2381
2757
  return this;
2382
2758
  }
@@ -2387,14 +2763,17 @@ var TypeInferredBuilder = class {
2387
2763
  const { required = false, ...fieldOptions } = options || {};
2388
2764
  let zodType = z3.boolean();
2389
2765
  if (required) {
2390
- zodType = zodType.refine((val) => val === true, `You must agree to ${label.toLowerCase()}`);
2766
+ zodType = zodType.refine(
2767
+ (val) => val === true,
2768
+ `You must agree to ${label.toLowerCase()}`
2769
+ );
2391
2770
  }
2392
2771
  this.schemaFields[name] = zodType;
2393
2772
  this.formFields.push({
2394
- name,
2773
+ checkboxProps: fieldOptions,
2395
2774
  label,
2396
- type: "checkbox",
2397
- checkboxProps: fieldOptions
2775
+ name,
2776
+ type: "checkbox"
2398
2777
  });
2399
2778
  return this;
2400
2779
  }
@@ -2404,10 +2783,10 @@ var TypeInferredBuilder = class {
2404
2783
  switch(name, label, options) {
2405
2784
  this.schemaFields[name] = z3.boolean().optional();
2406
2785
  this.formFields.push({
2407
- name,
2408
2786
  label,
2409
- type: "switch",
2410
- switchProps: options
2787
+ name,
2788
+ switchProps: options,
2789
+ type: "switch"
2411
2790
  });
2412
2791
  return this;
2413
2792
  }
@@ -2417,11 +2796,11 @@ var TypeInferredBuilder = class {
2417
2796
  radio(name, label, options, fieldOptions) {
2418
2797
  this.schemaFields[name] = z3.string().min(1, `Please select a ${label.toLowerCase()}`);
2419
2798
  this.formFields.push({
2420
- name,
2421
2799
  label,
2422
- type: "radio",
2800
+ name,
2423
2801
  radioOptions: options,
2424
- radioProps: fieldOptions
2802
+ radioProps: fieldOptions,
2803
+ type: "radio"
2425
2804
  });
2426
2805
  return this;
2427
2806
  }
@@ -2429,16 +2808,18 @@ var TypeInferredBuilder = class {
2429
2808
  * Add a slider field
2430
2809
  */
2431
2810
  slider(name, label, options) {
2432
- const { min = 0, max = 100, step = 1, ...fieldOptions } = options || {};
2811
+ const { max = 100, min = 0, step = 1, ...fieldOptions } = options || {};
2433
2812
  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}`);
2813
+ if (min !== void 0)
2814
+ zodType = zodType.min(min, `${label} must be at least ${min}`);
2815
+ if (max !== void 0)
2816
+ zodType = zodType.max(max, `${label} must be no more than ${max}`);
2436
2817
  this.schemaFields[name] = zodType;
2437
2818
  this.formFields.push({
2438
- name,
2439
2819
  label,
2440
- type: "slider",
2441
- sliderProps: { min, max, step, ...fieldOptions }
2820
+ name,
2821
+ sliderProps: { max, min, step, ...fieldOptions },
2822
+ type: "slider"
2442
2823
  });
2443
2824
  return this;
2444
2825
  }
@@ -2448,10 +2829,10 @@ var TypeInferredBuilder = class {
2448
2829
  date(name, label, options) {
2449
2830
  this.schemaFields[name] = z3.string().min(1, `${label} is required`);
2450
2831
  this.formFields.push({
2451
- name,
2832
+ dateProps: options,
2452
2833
  label,
2453
- type: "date",
2454
- dateProps: options
2834
+ name,
2835
+ type: "date"
2455
2836
  });
2456
2837
  return this;
2457
2838
  }
@@ -2461,10 +2842,10 @@ var TypeInferredBuilder = class {
2461
2842
  file(name, label, options) {
2462
2843
  this.schemaFields[name] = z3.any().optional();
2463
2844
  this.formFields.push({
2464
- name,
2845
+ fileProps: options,
2465
2846
  label,
2466
- type: "file",
2467
- fileProps: options
2847
+ name,
2848
+ type: "file"
2468
2849
  });
2469
2850
  return this;
2470
2851
  }
@@ -2473,8 +2854,8 @@ var TypeInferredBuilder = class {
2473
2854
  */
2474
2855
  build() {
2475
2856
  return {
2476
- schema: z3.object(this.schemaFields),
2477
- fields: this.formFields
2857
+ fields: this.formFields,
2858
+ schema: z3.object(this.schemaFields)
2478
2859
  };
2479
2860
  }
2480
2861
  };
@@ -2487,49 +2868,49 @@ function defineInferredForm(fieldDefinitions) {
2487
2868
  return builder.build();
2488
2869
  }
2489
2870
  var field = {
2490
- text: (name, label, options) => {
2871
+ checkbox: (name, label, options) => {
2491
2872
  const builder = new TypeInferredBuilder();
2492
- return builder.text(name, label, options);
2873
+ return builder.checkbox(name, label, options);
2874
+ },
2875
+ date: (name, label, options) => {
2876
+ const builder = new TypeInferredBuilder();
2877
+ return builder.date(name, label, options);
2493
2878
  },
2494
2879
  email: (name, label, options) => {
2495
2880
  const builder = new TypeInferredBuilder();
2496
2881
  return builder.email(name, label, options);
2497
2882
  },
2883
+ file: (name, label, options) => {
2884
+ const builder = new TypeInferredBuilder();
2885
+ return builder.file(name, label, options);
2886
+ },
2498
2887
  number: (name, label, options) => {
2499
2888
  const builder = new TypeInferredBuilder();
2500
2889
  return builder.number(name, label, options);
2501
2890
  },
2502
- textarea: (name, label, options) => {
2891
+ radio: (name, label, options, fieldOptions) => {
2503
2892
  const builder = new TypeInferredBuilder();
2504
- return builder.textarea(name, label, options);
2893
+ return builder.radio(name, label, options, fieldOptions);
2505
2894
  },
2506
- select: (name, label, options, fieldOptions) => {
2895
+ select: (name, label, options) => {
2507
2896
  const builder = new TypeInferredBuilder();
2508
- return builder.select(name, label, options, fieldOptions);
2897
+ return builder.select(name, label, options);
2509
2898
  },
2510
- checkbox: (name, label, options) => {
2899
+ slider: (name, label, options) => {
2511
2900
  const builder = new TypeInferredBuilder();
2512
- return builder.checkbox(name, label, options);
2901
+ return builder.slider(name, label, options);
2513
2902
  },
2514
2903
  switch: (name, label, options) => {
2515
2904
  const builder = new TypeInferredBuilder();
2516
2905
  return builder.switch(name, label, options);
2517
2906
  },
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) => {
2907
+ text: (name, label, options) => {
2527
2908
  const builder = new TypeInferredBuilder();
2528
- return builder.date(name, label, options);
2909
+ return builder.text(name, label, options);
2529
2910
  },
2530
- file: (name, label, options) => {
2911
+ textarea: (name, label, options) => {
2531
2912
  const builder = new TypeInferredBuilder();
2532
- return builder.file(name, label, options);
2913
+ return builder.textarea(name, label, options);
2533
2914
  }
2534
2915
  };
2535
2916
 
@@ -2558,8 +2939,8 @@ var NestedPathBuilder = class {
2558
2939
  */
2559
2940
  field(name, label, type = "input", props) {
2560
2941
  this.fields.push({
2561
- name,
2562
2942
  label,
2943
+ name,
2563
2944
  type,
2564
2945
  ...props
2565
2946
  });
@@ -2572,8 +2953,8 @@ var NestedPathBuilder = class {
2572
2953
  fieldPath(path, label, type = "input", props) {
2573
2954
  const name = path.join(".");
2574
2955
  this.fields.push({
2575
- name,
2576
2956
  label,
2957
+ name,
2577
2958
  type,
2578
2959
  ...props
2579
2960
  });
@@ -2583,7 +2964,7 @@ var NestedPathBuilder = class {
2583
2964
  * Add a field with template literal path
2584
2965
  * Usage: builder.field`user.profile.name`("Full Name")
2585
2966
  */
2586
- fieldTemplate(path, ...args) {
2967
+ fieldTemplate(path) {
2587
2968
  const pathString = path[0];
2588
2969
  return new FieldTemplateBuilder(this, pathString);
2589
2970
  }
@@ -2608,8 +2989,8 @@ var NestedObjectBuilder = class _NestedObjectBuilder {
2608
2989
  field(fieldName, label, type = "input", props) {
2609
2990
  const fullPath = `${this.path}.${fieldName}`;
2610
2991
  this.parent.fields.push({
2611
- name: fullPath,
2612
2992
  label,
2993
+ name: fullPath,
2613
2994
  type,
2614
2995
  ...props
2615
2996
  });
@@ -2619,7 +3000,10 @@ var NestedObjectBuilder = class _NestedObjectBuilder {
2619
3000
  * Nest deeper into the object
2620
3001
  */
2621
3002
  nest(subPath) {
2622
- return new _NestedObjectBuilder(this.parent, `${this.path}.${subPath}`);
3003
+ return new _NestedObjectBuilder(
3004
+ this.parent,
3005
+ `${this.path}.${subPath}`
3006
+ );
2623
3007
  }
2624
3008
  /**
2625
3009
  * Return to the parent builder
@@ -2639,8 +3023,8 @@ var SectionBuilder = class {
2639
3023
  field(fieldName, label, type = "input", props) {
2640
3024
  const fullPath = `${this.path}.${fieldName}`;
2641
3025
  this.parent.fields.push({
2642
- name: fullPath,
2643
3026
  label,
3027
+ name: fullPath,
2644
3028
  type,
2645
3029
  ...props
2646
3030
  });
@@ -2659,7 +3043,10 @@ var SectionBuilder = class {
2659
3043
  * Nest deeper into the section
2660
3044
  */
2661
3045
  nest(subPath) {
2662
- return new NestedObjectBuilder(this.parent, `${this.path}.${subPath}`);
3046
+ return new NestedObjectBuilder(
3047
+ this.parent,
3048
+ `${this.path}.${subPath}`
3049
+ );
2663
3050
  }
2664
3051
  /**
2665
3052
  * Return to the parent builder
@@ -2678,8 +3065,8 @@ var FieldTemplateBuilder = class {
2678
3065
  */
2679
3066
  complete(label, type = "input", props) {
2680
3067
  this.parent.fields.push({
2681
- name: this.path,
2682
3068
  label,
3069
+ name: this.path,
2683
3070
  type,
2684
3071
  ...props
2685
3072
  });
@@ -2693,8 +3080,10 @@ function createNestedPathBuilder() {
2693
3080
  // src/hooks/useDebouncedValidation.ts
2694
3081
  import { useCallback as useCallback2, useEffect as useEffect2, useRef } from "react";
2695
3082
  function useDebouncedValidation(form, options = {}) {
2696
- const { delay = 300, fields, enabled = true } = options;
2697
- const timeoutRef = useRef(void 0);
3083
+ const { delay = 300, enabled = true, fields } = options;
3084
+ const timeoutRef = useRef(
3085
+ void 0
3086
+ );
2698
3087
  const lastValuesRef = useRef({});
2699
3088
  const debouncedTrigger = useCallback2(() => {
2700
3089
  if (!enabled) return;
@@ -2705,7 +3094,9 @@ function useDebouncedValidation(form, options = {}) {
2705
3094
  timeoutRef.current = setTimeout(async () => {
2706
3095
  const currentValues = form.getValues();
2707
3096
  const lastValues = lastValuesRef.current;
2708
- const hasChanges = fields ? fields.some((field2) => currentValues[field2] !== lastValues[field2]) : Object.keys(currentValues).some((key) => currentValues[key] !== lastValues[key]);
3097
+ const hasChanges = fields ? fields.some((field2) => currentValues[field2] !== lastValues[field2]) : Object.keys(currentValues).some(
3098
+ (key) => currentValues[key] !== lastValues[key]
3099
+ );
2709
3100
  if (hasChanges) {
2710
3101
  lastValuesRef.current = { ...currentValues };
2711
3102
  if (fields && fields.length > 0) {
@@ -2736,7 +3127,9 @@ function useDebouncedValidation(form, options = {}) {
2736
3127
  }
2737
3128
  function useDebouncedFieldValidation(form, fieldName, options = {}) {
2738
3129
  const { delay = 300, enabled = true } = options;
2739
- const timeoutRef = useRef(void 0);
3130
+ const timeoutRef = useRef(
3131
+ void 0
3132
+ );
2740
3133
  const debouncedFieldTrigger = useCallback2(() => {
2741
3134
  if (!enabled) return;
2742
3135
  if (timeoutRef.current) {
@@ -2770,20 +3163,20 @@ try {
2770
3163
  function useInferredForm(schema, fields, options = {}) {
2771
3164
  const {
2772
3165
  defaultValues,
3166
+ delayError = 0,
2773
3167
  mode = "onChange",
2774
3168
  reValidateMode = "onChange",
2775
3169
  shouldFocusError = true,
2776
- shouldUnregister = false,
2777
- delayError = 0
3170
+ shouldUnregister = false
2778
3171
  } = options;
2779
3172
  return useForm3({
2780
- resolver: zodResolver ? zodResolver(schema) : void 0,
2781
3173
  defaultValues,
3174
+ delayError,
2782
3175
  mode,
3176
+ resolver: zodResolver ? zodResolver(schema) : void 0,
2783
3177
  reValidateMode,
2784
3178
  shouldFocusError,
2785
- shouldUnregister,
2786
- delayError
3179
+ shouldUnregister
2787
3180
  });
2788
3181
  }
2789
3182
  function useTypeInferredForm(formConfig, options = {}) {
@@ -2876,7 +3269,7 @@ function usePerformanceMonitor(componentName, enabled = process.env.NODE_ENV ===
2876
3269
  };
2877
3270
  }
2878
3271
  function createOptimizedFieldHandler(onChange, options = {}) {
2879
- const { debounce: debounceMs, throttle: throttleMs, validate = false } = options;
3272
+ const { debounce: debounceMs, throttle: throttleMs } = options;
2880
3273
  let handler = onChange;
2881
3274
  if (throttleMs) {
2882
3275
  handler = throttle(handler, throttleMs);
@@ -2889,70 +3282,51 @@ function createOptimizedFieldHandler(onChange, options = {}) {
2889
3282
  function useMemoizedFieldProps(props, deps) {
2890
3283
  return useMemo2(() => props, deps);
2891
3284
  }
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
3285
 
2910
3286
  // src/builders/validation-helpers.ts
2911
3287
  import { z as z4 } from "zod";
2912
3288
  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
3289
  // Credit card validation
2932
3290
  creditCard: z4.string().regex(
3291
+ // eslint-disable-next-line no-useless-escape
2933
3292
  /^[0-9]{4}[\s\-]?[0-9]{4}[\s\-]?[0-9]{4}[\s\-]?[0-9]{4}$/,
2934
3293
  "Please enter a valid credit card number"
2935
3294
  ),
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
3295
  // Date validation (MM/DD/YYYY)
2947
3296
  date: z4.string().regex(
2948
3297
  /^(0[1-9]|1[0-2])\/(0[1-9]|[12][0-9]|3[01])\/\d{4}$/,
2949
3298
  "Please enter a valid date (MM/DD/YYYY)"
2950
3299
  ),
3300
+ // Email validation
3301
+ email: z4.string().email("Please enter a valid email address"),
3302
+ // Password validation
3303
+ 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(
3304
+ /[^A-Za-z0-9]/,
3305
+ "Password must contain at least one special character"
3306
+ ),
3307
+ // Phone number validation (international)
3308
+ phoneInternational: z4.string().regex(/^\+?[\d\s\-\(\)]+$/, "Please enter a valid phone number"),
3309
+ // Phone number validation (US format)
3310
+ phoneUS: z4.string().regex(
3311
+ /^\(\d{3}\) \d{3}-\d{4}$/,
3312
+ "Please enter a valid phone number (XXX) XXX-XXXX"
3313
+ ),
3314
+ // SSN validation
3315
+ ssn: z4.string().regex(/^\d{3}-\d{2}-\d{4}$/, "Please enter a valid SSN (XXX-XX-XXXX)"),
3316
+ // Strong password validation
3317
+ 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(
3318
+ /[^A-Za-z0-9]/,
3319
+ "Password must contain at least one special character"
3320
+ ),
2951
3321
  // Time validation (HH:MM AM/PM)
2952
3322
  time: z4.string().regex(
2953
3323
  /^(0[1-9]|1[0-2]):[0-5][0-9] (AM|PM)$/i,
2954
3324
  "Please enter a valid time (HH:MM AM/PM)"
2955
- )
3325
+ ),
3326
+ // URL validation
3327
+ url: z4.string().url("Please enter a valid URL"),
3328
+ // ZIP code validation
3329
+ zipCode: z4.string().regex(/^\d{5}(-\d{4})?$/, "Please enter a valid ZIP code")
2956
3330
  };
2957
3331
  var asyncValidation = {
2958
3332
  /**
@@ -2979,17 +3353,17 @@ var asyncValidation = {
2979
3353
  }
2980
3354
  };
2981
3355
  var errorMessages = {
2982
- required: (fieldName) => `${fieldName} is required`,
2983
- minLength: (fieldName, min) => `${fieldName} must be at least ${min} characters`,
3356
+ date: () => "Please enter a valid date",
3357
+ email: () => "Please enter a valid email address",
3358
+ max: (fieldName, max) => `${fieldName} must be no more than ${max}`,
2984
3359
  maxLength: (fieldName, max) => `${fieldName} must be no more than ${max} characters`,
2985
3360
  min: (fieldName, min) => `${fieldName} must be at least ${min}`,
2986
- max: (fieldName, max) => `${fieldName} must be no more than ${max}`,
3361
+ minLength: (fieldName, min) => `${fieldName} must be at least ${min} characters`,
2987
3362
  pattern: (fieldName) => `${fieldName} format is invalid`,
2988
- email: () => "Please enter a valid email address",
2989
- url: () => "Please enter a valid URL",
2990
3363
  phone: () => "Please enter a valid phone number",
2991
- date: () => "Please enter a valid date",
2992
- time: () => "Please enter a valid time"
3364
+ required: (fieldName) => `${fieldName} is required`,
3365
+ time: () => "Please enter a valid time",
3366
+ url: () => "Please enter a valid URL"
2993
3367
  };
2994
3368
  var serverValidation = {
2995
3369
  /**
@@ -2998,8 +3372,8 @@ var serverValidation = {
2998
3372
  applyServerErrors: (errors, setError) => {
2999
3373
  Object.entries(errors).forEach(([field2, messages]) => {
3000
3374
  setError(field2, {
3001
- type: "server",
3002
- message: messages[0]
3375
+ message: messages[0],
3376
+ type: "server"
3003
3377
  // Use first error message
3004
3378
  });
3005
3379
  });
@@ -3024,13 +3398,25 @@ var validationUtils = {
3024
3398
  timeoutId = setTimeout(() => fn(...args), delay);
3025
3399
  };
3026
3400
  },
3401
+ /**
3402
+ * Get field error message
3403
+ */
3404
+ getFieldError: (errors, field2) => {
3405
+ return errors[field2];
3406
+ },
3407
+ /**
3408
+ * Check if field has error
3409
+ */
3410
+ hasFieldError: (errors, field2) => {
3411
+ return !!errors[field2];
3412
+ },
3027
3413
  /**
3028
3414
  * Validate form data against schema
3029
3415
  */
3030
3416
  validateForm: async (data, schema) => {
3031
3417
  try {
3032
3418
  await schema.parseAsync(data);
3033
- return { success: true, errors: {} };
3419
+ return { errors: {}, success: true };
3034
3420
  } catch (error) {
3035
3421
  if (error instanceof z4.ZodError) {
3036
3422
  const errors = {};
@@ -3038,22 +3424,10 @@ var validationUtils = {
3038
3424
  const path = err.path.join(".");
3039
3425
  errors[path] = err.message;
3040
3426
  });
3041
- return { success: false, errors };
3427
+ return { errors, success: false };
3042
3428
  }
3043
3429
  throw error;
3044
3430
  }
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
3431
  }
3058
3432
  };
3059
3433
  export {
@@ -3079,6 +3453,7 @@ export {
3079
3453
  InputField,
3080
3454
  RadioGroupField,
3081
3455
  SelectField,
3456
+ ServerActionForm,
3082
3457
  SliderField,
3083
3458
  SubmitButton,
3084
3459
  SwitchField,
@@ -3090,8 +3465,6 @@ export {
3090
3465
  commonValidations,
3091
3466
  createAdvancedBuilder,
3092
3467
  createBasicFormBuilder,
3093
- createConditionalSchema,
3094
- createConfirmPasswordSchema,
3095
3468
  createDateSchema,
3096
3469
  createEmailSchema,
3097
3470
  createField,
@@ -3130,7 +3503,6 @@ export {
3130
3503
  simulateFieldInput,
3131
3504
  simulateFormSubmission,
3132
3505
  throttle,
3133
- useBatchedFieldUpdates,
3134
3506
  useDebouncedFieldValidation,
3135
3507
  useDebouncedValidation,
3136
3508
  useEnhancedFormState,