@mehdashti/forms 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { useForm, Controller, useFieldArray } from 'react-hook-form';
1
+ import { useForm, Controller, useFormContext, useFieldArray } from 'react-hook-form';
2
2
  import { zodResolver } from '@hookform/resolvers/zod';
3
3
  import { jsx, jsxs } from 'react/jsx-runtime';
4
- import * as React2 from 'react';
4
+ import * as React4 from 'react';
5
5
  import { z } from 'zod';
6
6
  export { z } from 'zod';
7
7
 
@@ -273,7 +273,7 @@ function FormFileUpload({
273
273
  showPreview = true,
274
274
  onFileChange
275
275
  }) {
276
- const [previews, setPreviews] = React2.useState([]);
276
+ const [previews, setPreviews] = React4.useState([]);
277
277
  const handleFileChange = (files, onChange) => {
278
278
  if (!files || files.length === 0) {
279
279
  setPreviews([]);
@@ -455,7 +455,6 @@ function FormDatePicker({
455
455
  {
456
456
  name,
457
457
  label,
458
- placeholder,
459
458
  required,
460
459
  helpText,
461
460
  disabled,
@@ -603,7 +602,7 @@ function FormMultiSelect({
603
602
  field.onChange(newValues);
604
603
  };
605
604
  const isSelected = (optionValue) => selectedValues.includes(optionValue);
606
- const isMaxReached = maxSelection && selectedValues.length >= maxSelection;
605
+ const isMaxReached = maxSelection !== void 0 && selectedValues.length >= maxSelection;
607
606
  return /* @__PURE__ */ jsxs("div", { className: `space-y-3 ${className || ""}`, children: [
608
607
  /* @__PURE__ */ jsxs("label", { className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children: [
609
608
  label,
@@ -656,6 +655,425 @@ function FormMultiSelect({
656
655
  }
657
656
  );
658
657
  }
658
+ function FormRadioGroup({
659
+ name,
660
+ label,
661
+ options,
662
+ orientation = "vertical",
663
+ helperText,
664
+ required,
665
+ disabled,
666
+ className
667
+ }) {
668
+ const {
669
+ register,
670
+ formState: { errors }
671
+ } = useFormContext();
672
+ const error = errors[name]?.message;
673
+ const fieldId = `field-${name}`;
674
+ return /* @__PURE__ */ jsxs("div", { className, children: [
675
+ label && /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: [
676
+ label,
677
+ required && /* @__PURE__ */ jsx("span", { className: "text-red-500 ml-1", children: "*" })
678
+ ] }) }),
679
+ /* @__PURE__ */ jsx(
680
+ "div",
681
+ {
682
+ role: "radiogroup",
683
+ "aria-labelledby": label ? fieldId : void 0,
684
+ className: orientation === "horizontal" ? "flex flex-wrap gap-4" : "space-y-3",
685
+ children: options.map((option) => {
686
+ const optionId = `${fieldId}-${option.value}`;
687
+ const isDisabled = disabled || option.disabled;
688
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start", children: [
689
+ /* @__PURE__ */ jsx("div", { className: "flex items-center h-5", children: /* @__PURE__ */ jsx(
690
+ "input",
691
+ {
692
+ ...register(name),
693
+ type: "radio",
694
+ id: optionId,
695
+ value: option.value,
696
+ disabled: isDisabled,
697
+ className: `
698
+ h-4 w-4 border-gray-300 text-blue-600
699
+ focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
700
+ disabled:opacity-50 disabled:cursor-not-allowed
701
+ dark:border-gray-600 dark:bg-gray-800 dark:focus:ring-offset-gray-900
702
+ `
703
+ }
704
+ ) }),
705
+ /* @__PURE__ */ jsxs("div", { className: "ml-3", children: [
706
+ /* @__PURE__ */ jsx(
707
+ "label",
708
+ {
709
+ htmlFor: optionId,
710
+ className: `
711
+ text-sm font-medium
712
+ ${isDisabled ? "text-gray-400 cursor-not-allowed" : "text-gray-700 dark:text-gray-300 cursor-pointer"}
713
+ `,
714
+ children: option.label
715
+ }
716
+ ),
717
+ option.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: option.description })
718
+ ] })
719
+ ] }, option.value);
720
+ })
721
+ }
722
+ ),
723
+ helperText && !error && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
724
+ error && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-red-600 dark:text-red-400", role: "alert", children: error })
725
+ ] });
726
+ }
727
+ function FormSwitch({
728
+ name,
729
+ label,
730
+ description,
731
+ helperText,
732
+ required,
733
+ disabled,
734
+ className,
735
+ onChange
736
+ }) {
737
+ const {
738
+ register,
739
+ watch,
740
+ setValue,
741
+ formState: { errors }
742
+ } = useFormContext();
743
+ const value = watch(name);
744
+ const checked = Boolean(value);
745
+ const error = errors[name]?.message;
746
+ const fieldId = `field-${name}`;
747
+ const handleChange = (e) => {
748
+ const newValue = e.target.checked;
749
+ setValue(name, newValue, { shouldValidate: true, shouldDirty: true });
750
+ onChange?.(newValue);
751
+ };
752
+ return /* @__PURE__ */ jsxs("div", { className, children: [
753
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start", children: [
754
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center h-5", children: [
755
+ /* @__PURE__ */ jsxs(
756
+ "button",
757
+ {
758
+ type: "button",
759
+ role: "switch",
760
+ "aria-checked": checked,
761
+ "aria-labelledby": label ? `${fieldId}-label` : void 0,
762
+ "aria-describedby": description ? `${fieldId}-description` : void 0,
763
+ disabled,
764
+ onClick: () => {
765
+ if (!disabled) {
766
+ const newValue = !checked;
767
+ setValue(name, newValue, { shouldValidate: true, shouldDirty: true });
768
+ onChange?.(newValue);
769
+ }
770
+ },
771
+ className: `
772
+ relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent
773
+ transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
774
+ disabled:opacity-50 disabled:cursor-not-allowed
775
+ dark:focus:ring-offset-gray-900
776
+ ${checked ? "bg-blue-600" : "bg-gray-200 dark:bg-gray-700"}
777
+ `,
778
+ children: [
779
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: label }),
780
+ /* @__PURE__ */ jsx(
781
+ "span",
782
+ {
783
+ className: `
784
+ pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0
785
+ transition duration-200 ease-in-out
786
+ ${checked ? "translate-x-5" : "translate-x-0"}
787
+ `
788
+ }
789
+ )
790
+ ]
791
+ }
792
+ ),
793
+ /* @__PURE__ */ jsx(
794
+ "input",
795
+ {
796
+ ...register(name),
797
+ type: "checkbox",
798
+ id: fieldId,
799
+ checked,
800
+ onChange: handleChange,
801
+ className: "sr-only",
802
+ disabled
803
+ }
804
+ )
805
+ ] }),
806
+ (label || description) && /* @__PURE__ */ jsxs("div", { className: "ml-3", children: [
807
+ label && /* @__PURE__ */ jsxs(
808
+ "label",
809
+ {
810
+ id: `${fieldId}-label`,
811
+ htmlFor: fieldId,
812
+ className: `
813
+ text-sm font-medium
814
+ ${disabled ? "text-gray-400" : "text-gray-700 dark:text-gray-300"}
815
+ `,
816
+ children: [
817
+ label,
818
+ required && /* @__PURE__ */ jsx("span", { className: "text-red-500 ml-1", children: "*" })
819
+ ]
820
+ }
821
+ ),
822
+ description && /* @__PURE__ */ jsx(
823
+ "p",
824
+ {
825
+ id: `${fieldId}-description`,
826
+ className: "text-xs text-gray-500 dark:text-gray-400",
827
+ children: description
828
+ }
829
+ )
830
+ ] })
831
+ ] }),
832
+ helperText && !error && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
833
+ error && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-red-600 dark:text-red-400", role: "alert", children: error })
834
+ ] });
835
+ }
836
+ function FormTagInput({
837
+ name,
838
+ label,
839
+ placeholder = "Type and press Enter...",
840
+ helperText,
841
+ required,
842
+ disabled,
843
+ maxTags,
844
+ separators = ["Enter", ","],
845
+ validateTag,
846
+ className
847
+ }) {
848
+ const {
849
+ watch,
850
+ setValue,
851
+ formState: { errors }
852
+ } = useFormContext();
853
+ const [inputValue, setInputValue] = React4.useState("");
854
+ const [tagError, setTagError] = React4.useState("");
855
+ const tags = watch(name) || [];
856
+ const error = errors[name]?.message;
857
+ const fieldId = `field-${name}`;
858
+ const addTag = (tag) => {
859
+ const trimmed = tag.trim();
860
+ if (!trimmed) return;
861
+ if (tags.includes(trimmed)) {
862
+ setTagError("Tag already exists");
863
+ return;
864
+ }
865
+ if (maxTags && tags.length >= maxTags) {
866
+ setTagError(`Maximum ${maxTags} tags allowed`);
867
+ return;
868
+ }
869
+ if (validateTag) {
870
+ const validation = validateTag(trimmed);
871
+ if (validation === false) {
872
+ setTagError("Invalid tag");
873
+ return;
874
+ }
875
+ if (typeof validation === "string") {
876
+ setTagError(validation);
877
+ return;
878
+ }
879
+ }
880
+ setValue(name, [...tags, trimmed], {
881
+ shouldValidate: true,
882
+ shouldDirty: true
883
+ });
884
+ setInputValue("");
885
+ setTagError("");
886
+ };
887
+ const removeTag = (index) => {
888
+ const newTags = tags.filter((_, i) => i !== index);
889
+ setValue(name, newTags, {
890
+ shouldValidate: true,
891
+ shouldDirty: true
892
+ });
893
+ };
894
+ const handleKeyDown = (e) => {
895
+ if (separators.includes(e.key)) {
896
+ e.preventDefault();
897
+ addTag(inputValue);
898
+ } else if (e.key === "Backspace" && !inputValue && tags.length > 0) {
899
+ removeTag(tags.length - 1);
900
+ }
901
+ };
902
+ const handleBlur = () => {
903
+ if (inputValue.trim()) {
904
+ addTag(inputValue);
905
+ }
906
+ };
907
+ return /* @__PURE__ */ jsxs("div", { className, children: [
908
+ label && /* @__PURE__ */ jsxs(
909
+ "label",
910
+ {
911
+ htmlFor: fieldId,
912
+ className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1",
913
+ children: [
914
+ label,
915
+ required && /* @__PURE__ */ jsx("span", { className: "text-red-500 ml-1", children: "*" })
916
+ ]
917
+ }
918
+ ),
919
+ /* @__PURE__ */ jsxs(
920
+ "div",
921
+ {
922
+ className: `
923
+ flex flex-wrap gap-2 p-2 border rounded-md min-h-[42px]
924
+ ${disabled ? "bg-gray-50 dark:bg-gray-900 cursor-not-allowed" : "bg-white dark:bg-gray-800"}
925
+ ${error || tagError ? "border-red-300 dark:border-red-700" : "border-gray-300 dark:border-gray-600"}
926
+ focus-within:ring-2 focus-within:ring-blue-500 focus-within:border-blue-500
927
+ dark:focus-within:ring-blue-400 dark:focus-within:border-blue-400
928
+ `,
929
+ children: [
930
+ tags.map((tag, index) => /* @__PURE__ */ jsxs(
931
+ "span",
932
+ {
933
+ className: "inline-flex items-center gap-1 px-2 py-1 text-sm bg-blue-100 text-blue-800 rounded dark:bg-blue-900 dark:text-blue-200",
934
+ children: [
935
+ tag,
936
+ !disabled && /* @__PURE__ */ jsx(
937
+ "button",
938
+ {
939
+ type: "button",
940
+ onClick: () => removeTag(index),
941
+ className: "ml-1 hover:text-blue-600 dark:hover:text-blue-300",
942
+ "aria-label": `Remove ${tag}`,
943
+ children: "\xD7"
944
+ }
945
+ )
946
+ ]
947
+ },
948
+ index
949
+ )),
950
+ /* @__PURE__ */ jsx(
951
+ "input",
952
+ {
953
+ id: fieldId,
954
+ type: "text",
955
+ value: inputValue,
956
+ onChange: (e) => {
957
+ setInputValue(e.target.value);
958
+ setTagError("");
959
+ },
960
+ onKeyDown: handleKeyDown,
961
+ onBlur: handleBlur,
962
+ placeholder: tags.length === 0 ? placeholder : "",
963
+ disabled: disabled || maxTags !== void 0 && tags.length >= maxTags,
964
+ className: "flex-1 min-w-[120px] outline-none bg-transparent text-sm text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 disabled:cursor-not-allowed"
965
+ }
966
+ )
967
+ ]
968
+ }
969
+ ),
970
+ helperText && !error && !tagError && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
971
+ (error || tagError) && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", role: "alert", children: error || tagError }),
972
+ maxTags && /* @__PURE__ */ jsxs("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: [
973
+ tags.length,
974
+ " / ",
975
+ maxTags,
976
+ " tags"
977
+ ] })
978
+ ] });
979
+ }
980
+ function FormErrorSummary({
981
+ title = "Please fix the following errors:",
982
+ fieldLabels = {},
983
+ show,
984
+ className,
985
+ onErrorClick
986
+ }) {
987
+ const {
988
+ formState: { errors }
989
+ } = useFormContext();
990
+ const errorList = React4.useMemo(() => {
991
+ return flattenErrors(errors, fieldLabels);
992
+ }, [errors, fieldLabels]);
993
+ const shouldShow = show !== void 0 ? show : errorList.length > 0;
994
+ if (!shouldShow) {
995
+ return null;
996
+ }
997
+ const handleErrorClick = (fieldName) => {
998
+ const field = document.getElementById(`field-${fieldName}`) || document.querySelector(`[name="${fieldName}"]`);
999
+ if (field) {
1000
+ field.focus();
1001
+ field.scrollIntoView({ behavior: "smooth", block: "center" });
1002
+ }
1003
+ onErrorClick?.(fieldName);
1004
+ };
1005
+ return /* @__PURE__ */ jsx(
1006
+ "div",
1007
+ {
1008
+ role: "alert",
1009
+ "aria-live": "polite",
1010
+ className: `
1011
+ rounded-md bg-red-50 dark:bg-red-900/20 p-4 border border-red-200 dark:border-red-800
1012
+ ${className}
1013
+ `,
1014
+ children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
1015
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(
1016
+ "svg",
1017
+ {
1018
+ className: "h-5 w-5 text-red-400 dark:text-red-600",
1019
+ xmlns: "http://www.w3.org/2000/svg",
1020
+ viewBox: "0 0 20 20",
1021
+ fill: "currentColor",
1022
+ "aria-hidden": "true",
1023
+ children: /* @__PURE__ */ jsx(
1024
+ "path",
1025
+ {
1026
+ fillRule: "evenodd",
1027
+ d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z",
1028
+ clipRule: "evenodd"
1029
+ }
1030
+ )
1031
+ }
1032
+ ) }),
1033
+ /* @__PURE__ */ jsxs("div", { className: "ml-3 flex-1", children: [
1034
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-red-800 dark:text-red-300", children: title }),
1035
+ /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-red-700 dark:text-red-400", children: /* @__PURE__ */ jsx("ul", { className: "list-disc space-y-1 pl-5", children: errorList.map(({ fieldName, fieldLabel, message }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
1036
+ "button",
1037
+ {
1038
+ type: "button",
1039
+ onClick: () => handleErrorClick(fieldName),
1040
+ className: "hover:underline focus:outline-none focus:underline text-left",
1041
+ children: [
1042
+ /* @__PURE__ */ jsxs("strong", { children: [
1043
+ fieldLabel,
1044
+ ":"
1045
+ ] }),
1046
+ " ",
1047
+ message
1048
+ ]
1049
+ }
1050
+ ) }, fieldName)) }) })
1051
+ ] })
1052
+ ] })
1053
+ }
1054
+ );
1055
+ }
1056
+ function flattenErrors(errors, fieldLabels, prefix = "") {
1057
+ const result = [];
1058
+ for (const [key, value] of Object.entries(errors)) {
1059
+ const fieldName = prefix ? `${prefix}.${key}` : key;
1060
+ if (value && typeof value === "object") {
1061
+ if ("message" in value && typeof value.message === "string") {
1062
+ result.push({
1063
+ fieldName,
1064
+ fieldLabel: fieldLabels[fieldName] || formatFieldName(fieldName),
1065
+ message: value.message
1066
+ });
1067
+ } else {
1068
+ result.push(...flattenErrors(value, fieldLabels, fieldName));
1069
+ }
1070
+ }
1071
+ }
1072
+ return result;
1073
+ }
1074
+ function formatFieldName(name) {
1075
+ return name.split(".").pop().replace(/([A-Z])/g, " $1").replace(/_/g, " ").replace(/^\w/, (c) => c.toUpperCase()).trim();
1076
+ }
659
1077
  var spacingClasses = {
660
1078
  sm: "gap-3",
661
1079
  md: "gap-4",
@@ -767,9 +1185,9 @@ function FormWizard({
767
1185
  className,
768
1186
  showStepNumbers = true
769
1187
  }) {
770
- const [currentStep, setCurrentStep] = React2.useState(0);
771
- const [isValidating, setIsValidating] = React2.useState(false);
772
- const [isCompleting, setIsCompleting] = React2.useState(false);
1188
+ const [currentStep, setCurrentStep] = React4.useState(0);
1189
+ const [isValidating, setIsValidating] = React4.useState(false);
1190
+ const [isCompleting, setIsCompleting] = React4.useState(false);
773
1191
  const isFirstStep = currentStep === 0;
774
1192
  const isLastStep = currentStep === steps.length - 1;
775
1193
  const handleNext = async () => {
@@ -929,6 +1347,47 @@ function useSmartFieldArray({
929
1347
  append
930
1348
  };
931
1349
  }
1350
+ function useUnsavedChanges(options = {}) {
1351
+ const {
1352
+ message = "You have unsaved changes. Are you sure you want to leave?",
1353
+ enabled = true,
1354
+ onBeforeUnload
1355
+ } = options;
1356
+ const {
1357
+ formState: { isDirty, isSubmitting, isSubmitSuccessful }
1358
+ } = useFormContext();
1359
+ const hasUnsavedChanges = isDirty && !isSubmitting && !isSubmitSuccessful;
1360
+ React4.useEffect(() => {
1361
+ if (!enabled) return;
1362
+ const handleBeforeUnload = (event) => {
1363
+ if (hasUnsavedChanges) {
1364
+ event.preventDefault();
1365
+ event.returnValue = message;
1366
+ onBeforeUnload?.(hasUnsavedChanges);
1367
+ return message;
1368
+ }
1369
+ };
1370
+ window.addEventListener("beforeunload", handleBeforeUnload);
1371
+ return () => {
1372
+ window.removeEventListener("beforeunload", handleBeforeUnload);
1373
+ };
1374
+ }, [hasUnsavedChanges, message, enabled, onBeforeUnload]);
1375
+ return {
1376
+ hasUnsavedChanges,
1377
+ isDirty
1378
+ };
1379
+ }
1380
+ function useUnsavedChangesBlocker() {
1381
+ const {
1382
+ formState: { isDirty, isSubmitting, isSubmitSuccessful }
1383
+ } = useFormContext();
1384
+ const hasUnsavedChanges = isDirty && !isSubmitting && !isSubmitSuccessful;
1385
+ return {
1386
+ hasUnsavedChanges,
1387
+ isDirty,
1388
+ shouldBlock: hasUnsavedChanges
1389
+ };
1390
+ }
932
1391
  var emailSchema = z.string().min(1, "Email is required").email("Invalid email address");
933
1392
  var passwordSchema = z.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");
934
1393
  var strongPasswordSchema = z.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");
@@ -1002,7 +1461,7 @@ function getAllErrors(errors) {
1002
1461
  });
1003
1462
  return messages;
1004
1463
  }
1005
- function conditionalSchema(dependentField, condition, schema) {
1464
+ function conditionalSchema(_dependentField, _condition, schema) {
1006
1465
  return z.any().superRefine((value, ctx) => {
1007
1466
  const parent = ctx.path[ctx.path.length - 2];
1008
1467
  if (!parent) return;
@@ -1099,6 +1558,6 @@ function formatValidationError(error) {
1099
1558
  return formatted;
1100
1559
  }
1101
1560
 
1102
- export { FormCheckbox, FormDatePicker, FormField, FormFileUpload, FormGrid, FormGridItem, FormLayout, FormMultiSelect, FormSection, FormSelect, FormTextarea, FormWizard, conditionalSchema, createConfirmPasswordSchema, createFileSizeSchema, createFileTypeSchema, dateStringSchema, emailSchema, formatValidationError, futureDateSchema, getAllErrors, getErrorMessage, hasError, imageFileSchema, invalidFormatMessage, lengthMessage, optionalEmailSchema, optionalUrlSchema, passwordSchema, pastDateSchema, percentageSchema, phoneSchema, positiveIntegerSchema, positiveNumberSchema, priceSchema, requiredMessage, sanitizeString, slugSchema, strongPasswordSchema, urlSchema, useSmartFieldArray, useSmartForm, usernameSchema, validateCreditCard, validateFileExtension, validateIBAN, validatePasswordStrength };
1561
+ export { FormCheckbox, FormDatePicker, FormErrorSummary, FormField, FormFileUpload, FormGrid, FormGridItem, FormLayout, FormMultiSelect, FormRadioGroup, FormSection, FormSelect, FormSwitch, FormTagInput, FormTextarea, FormWizard, conditionalSchema, createConfirmPasswordSchema, createFileSizeSchema, createFileTypeSchema, dateStringSchema, emailSchema, formatValidationError, futureDateSchema, getAllErrors, getErrorMessage, hasError, imageFileSchema, invalidFormatMessage, lengthMessage, optionalEmailSchema, optionalUrlSchema, passwordSchema, pastDateSchema, percentageSchema, phoneSchema, positiveIntegerSchema, positiveNumberSchema, priceSchema, requiredMessage, sanitizeString, slugSchema, strongPasswordSchema, urlSchema, useSmartFieldArray, useSmartForm, useUnsavedChanges, useUnsavedChangesBlocker, usernameSchema, validateCreditCard, validateFileExtension, validateIBAN, validatePasswordStrength };
1103
1562
  //# sourceMappingURL=index.js.map
1104
1563
  //# sourceMappingURL=index.js.map