react-hook-form 7.33.0 → 7.34.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/README.md +334 -336
- package/dist/__typetest__/__fixtures__/index.d.ts +5 -0
- package/dist/__typetest__/__fixtures__/index.d.ts.map +1 -0
- package/dist/__typetest__/__fixtures__/pathString.d.ts +4 -0
- package/dist/__typetest__/__fixtures__/pathString.d.ts.map +1 -0
- package/dist/__typetest__/__fixtures__/traversable.d.ts +14 -0
- package/dist/__typetest__/__fixtures__/traversable.d.ts.map +1 -0
- package/dist/__typetest__/__fixtures__/tuple.d.ts +15 -0
- package/dist/__typetest__/__fixtures__/tuple.d.ts.map +1 -0
- package/dist/__typetest__/__fixtures__/type.d.ts +12 -0
- package/dist/__typetest__/__fixtures__/type.d.ts.map +1 -0
- package/dist/__typetest__/errors.test-d.d.ts +2 -0
- package/dist/__typetest__/errors.test-d.d.ts.map +1 -0
- package/dist/__typetest__/form.test-d.d.ts +2 -0
- package/dist/__typetest__/form.test-d.d.ts.map +1 -0
- package/dist/__typetest__/path/common.test-d.d.ts +2 -0
- package/dist/__typetest__/path/common.test-d.d.ts.map +1 -0
- package/dist/__typetest__/path/eager.test-d.d.ts +2 -0
- package/dist/__typetest__/path/eager.test-d.d.ts.map +1 -0
- package/dist/__typetest__/util.test-d.d.ts +2 -0
- package/dist/__typetest__/util.test-d.d.ts.map +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +306 -267
- package/dist/index.esm.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/logic/schemaErrorLookup.d.ts +1 -1
- package/dist/logic/schemaErrorLookup.d.ts.map +1 -1
- package/dist/logic/updateFieldArrayRootError.d.ts +4 -0
- package/dist/logic/updateFieldArrayRootError.d.ts.map +1 -0
- package/dist/logic/validateField.d.ts +1 -1
- package/dist/logic/validateField.d.ts.map +1 -1
- package/dist/types/errors.d.ts +7 -2
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/fieldArray.d.ts +6 -4
- package/dist/types/fieldArray.d.ts.map +1 -1
- package/dist/types/fields.d.ts +1 -1
- package/dist/types/fields.d.ts.map +1 -1
- package/dist/types/utils.d.ts +1 -1
- package/dist/types/utils.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useForm.d.ts +2 -2
- package/dist/useForm.d.ts.map +1 -1
- package/dist/utils/unset.d.ts.map +1 -1
- package/package.json +8 -5
package/dist/index.esm.mjs
CHANGED
@@ -124,7 +124,7 @@ const useFormContext = () => React.useContext(HookFormContext);
|
|
124
124
|
*/
|
125
125
|
const FormProvider = (props) => {
|
126
126
|
const { children, ...data } = props;
|
127
|
-
return (React.createElement(HookFormContext.Provider, { value: data },
|
127
|
+
return (React.createElement(HookFormContext.Provider, { value: data }, children));
|
128
128
|
};
|
129
129
|
|
130
130
|
var getProxyFormState = (formState, _proxyFormState, localProxyFormState, isRoot = true) => {
|
@@ -555,6 +555,243 @@ var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
|
|
555
555
|
[..._names.watch].some((watchName) => name.startsWith(watchName) &&
|
556
556
|
/^\.\w+/.test(name.slice(watchName.length))));
|
557
557
|
|
558
|
+
var updateFieldArrayRootError = (errors, error, name) => {
|
559
|
+
const fieldArrayErrors = compact(get(errors, name));
|
560
|
+
set(fieldArrayErrors, 'root', error[name]);
|
561
|
+
set(errors, name, fieldArrayErrors);
|
562
|
+
return errors;
|
563
|
+
};
|
564
|
+
|
565
|
+
var isBoolean = (value) => typeof value === 'boolean';
|
566
|
+
|
567
|
+
var isFileInput = (element) => element.type === 'file';
|
568
|
+
|
569
|
+
var isMessage = (value) => isString(value) || React.isValidElement(value);
|
570
|
+
|
571
|
+
var isRadioInput = (element) => element.type === 'radio';
|
572
|
+
|
573
|
+
var isRegex = (value) => value instanceof RegExp;
|
574
|
+
|
575
|
+
const defaultResult = {
|
576
|
+
value: false,
|
577
|
+
isValid: false,
|
578
|
+
};
|
579
|
+
const validResult = { value: true, isValid: true };
|
580
|
+
var getCheckboxValue = (options) => {
|
581
|
+
if (Array.isArray(options)) {
|
582
|
+
if (options.length > 1) {
|
583
|
+
const values = options
|
584
|
+
.filter((option) => option && option.checked && !option.disabled)
|
585
|
+
.map((option) => option.value);
|
586
|
+
return { value: values, isValid: !!values.length };
|
587
|
+
}
|
588
|
+
return options[0].checked && !options[0].disabled
|
589
|
+
? // @ts-expect-error expected to work in the browser
|
590
|
+
options[0].attributes && !isUndefined(options[0].attributes.value)
|
591
|
+
? isUndefined(options[0].value) || options[0].value === ''
|
592
|
+
? validResult
|
593
|
+
: { value: options[0].value, isValid: true }
|
594
|
+
: validResult
|
595
|
+
: defaultResult;
|
596
|
+
}
|
597
|
+
return defaultResult;
|
598
|
+
};
|
599
|
+
|
600
|
+
const defaultReturn = {
|
601
|
+
isValid: false,
|
602
|
+
value: null,
|
603
|
+
};
|
604
|
+
var getRadioValue = (options) => Array.isArray(options)
|
605
|
+
? options.reduce((previous, option) => option && option.checked && !option.disabled
|
606
|
+
? {
|
607
|
+
isValid: true,
|
608
|
+
value: option.value,
|
609
|
+
}
|
610
|
+
: previous, defaultReturn)
|
611
|
+
: defaultReturn;
|
612
|
+
|
613
|
+
function getValidateError(result, ref, type = 'validate') {
|
614
|
+
if (isMessage(result) ||
|
615
|
+
(Array.isArray(result) && result.every(isMessage)) ||
|
616
|
+
(isBoolean(result) && !result)) {
|
617
|
+
return {
|
618
|
+
type,
|
619
|
+
message: isMessage(result) ? result : '',
|
620
|
+
ref,
|
621
|
+
};
|
622
|
+
}
|
623
|
+
}
|
624
|
+
|
625
|
+
var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData)
|
626
|
+
? validationData
|
627
|
+
: {
|
628
|
+
value: validationData,
|
629
|
+
message: '',
|
630
|
+
};
|
631
|
+
|
632
|
+
var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
|
633
|
+
const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount, disabled, } = field._f;
|
634
|
+
if (!mount || disabled) {
|
635
|
+
return {};
|
636
|
+
}
|
637
|
+
const inputRef = refs ? refs[0] : ref;
|
638
|
+
const setCustomValidity = (message) => {
|
639
|
+
if (shouldUseNativeValidation && inputRef.reportValidity) {
|
640
|
+
inputRef.setCustomValidity(isBoolean(message) ? '' : message || ' ');
|
641
|
+
inputRef.reportValidity();
|
642
|
+
}
|
643
|
+
};
|
644
|
+
const error = {};
|
645
|
+
const isRadio = isRadioInput(ref);
|
646
|
+
const isCheckBox = isCheckBoxInput(ref);
|
647
|
+
const isRadioOrCheckbox = isRadio || isCheckBox;
|
648
|
+
const isEmpty = ((valueAsNumber || isFileInput(ref)) && !ref.value) ||
|
649
|
+
inputValue === '' ||
|
650
|
+
(Array.isArray(inputValue) && !inputValue.length);
|
651
|
+
const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
|
652
|
+
const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
|
653
|
+
const message = exceedMax ? maxLengthMessage : minLengthMessage;
|
654
|
+
error[name] = {
|
655
|
+
type: exceedMax ? maxType : minType,
|
656
|
+
message,
|
657
|
+
ref,
|
658
|
+
...appendErrorsCurry(exceedMax ? maxType : minType, message),
|
659
|
+
};
|
660
|
+
};
|
661
|
+
if (isFieldArray
|
662
|
+
? !Array.isArray(inputValue) || !inputValue.length
|
663
|
+
: required &&
|
664
|
+
((!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue))) ||
|
665
|
+
(isBoolean(inputValue) && !inputValue) ||
|
666
|
+
(isCheckBox && !getCheckboxValue(refs).isValid) ||
|
667
|
+
(isRadio && !getRadioValue(refs).isValid))) {
|
668
|
+
const { value, message } = isMessage(required)
|
669
|
+
? { value: !!required, message: required }
|
670
|
+
: getValueAndMessage(required);
|
671
|
+
if (value) {
|
672
|
+
error[name] = {
|
673
|
+
type: INPUT_VALIDATION_RULES.required,
|
674
|
+
message,
|
675
|
+
ref: inputRef,
|
676
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message),
|
677
|
+
};
|
678
|
+
if (!validateAllFieldCriteria) {
|
679
|
+
setCustomValidity(message);
|
680
|
+
return error;
|
681
|
+
}
|
682
|
+
}
|
683
|
+
}
|
684
|
+
if (!isEmpty && (!isNullOrUndefined(min) || !isNullOrUndefined(max))) {
|
685
|
+
let exceedMax;
|
686
|
+
let exceedMin;
|
687
|
+
const maxOutput = getValueAndMessage(max);
|
688
|
+
const minOutput = getValueAndMessage(min);
|
689
|
+
if (!isNullOrUndefined(inputValue) && !isNaN(inputValue)) {
|
690
|
+
const valueNumber = ref.valueAsNumber || +inputValue;
|
691
|
+
if (!isNullOrUndefined(maxOutput.value)) {
|
692
|
+
exceedMax = valueNumber > maxOutput.value;
|
693
|
+
}
|
694
|
+
if (!isNullOrUndefined(minOutput.value)) {
|
695
|
+
exceedMin = valueNumber < minOutput.value;
|
696
|
+
}
|
697
|
+
}
|
698
|
+
else {
|
699
|
+
const valueDate = ref.valueAsDate || new Date(inputValue);
|
700
|
+
if (isString(maxOutput.value)) {
|
701
|
+
exceedMax = valueDate > new Date(maxOutput.value);
|
702
|
+
}
|
703
|
+
if (isString(minOutput.value)) {
|
704
|
+
exceedMin = valueDate < new Date(minOutput.value);
|
705
|
+
}
|
706
|
+
}
|
707
|
+
if (exceedMax || exceedMin) {
|
708
|
+
getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
|
709
|
+
if (!validateAllFieldCriteria) {
|
710
|
+
setCustomValidity(error[name].message);
|
711
|
+
return error;
|
712
|
+
}
|
713
|
+
}
|
714
|
+
}
|
715
|
+
if ((maxLength || minLength) &&
|
716
|
+
!isEmpty &&
|
717
|
+
(isString(inputValue) || (isFieldArray && Array.isArray(inputValue)))) {
|
718
|
+
const maxLengthOutput = getValueAndMessage(maxLength);
|
719
|
+
const minLengthOutput = getValueAndMessage(minLength);
|
720
|
+
const exceedMax = !isNullOrUndefined(maxLengthOutput.value) &&
|
721
|
+
inputValue.length > maxLengthOutput.value;
|
722
|
+
const exceedMin = !isNullOrUndefined(minLengthOutput.value) &&
|
723
|
+
inputValue.length < minLengthOutput.value;
|
724
|
+
if (exceedMax || exceedMin) {
|
725
|
+
getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
|
726
|
+
if (!validateAllFieldCriteria) {
|
727
|
+
setCustomValidity(error[name].message);
|
728
|
+
return error;
|
729
|
+
}
|
730
|
+
}
|
731
|
+
}
|
732
|
+
if (pattern && !isEmpty && isString(inputValue)) {
|
733
|
+
const { value: patternValue, message } = getValueAndMessage(pattern);
|
734
|
+
if (isRegex(patternValue) && !inputValue.match(patternValue)) {
|
735
|
+
error[name] = {
|
736
|
+
type: INPUT_VALIDATION_RULES.pattern,
|
737
|
+
message,
|
738
|
+
ref,
|
739
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message),
|
740
|
+
};
|
741
|
+
if (!validateAllFieldCriteria) {
|
742
|
+
setCustomValidity(message);
|
743
|
+
return error;
|
744
|
+
}
|
745
|
+
}
|
746
|
+
}
|
747
|
+
if (validate) {
|
748
|
+
if (isFunction(validate)) {
|
749
|
+
const result = await validate(inputValue);
|
750
|
+
const validateError = getValidateError(result, inputRef);
|
751
|
+
if (validateError) {
|
752
|
+
error[name] = {
|
753
|
+
...validateError,
|
754
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message),
|
755
|
+
};
|
756
|
+
if (!validateAllFieldCriteria) {
|
757
|
+
setCustomValidity(validateError.message);
|
758
|
+
return error;
|
759
|
+
}
|
760
|
+
}
|
761
|
+
}
|
762
|
+
else if (isObject(validate)) {
|
763
|
+
let validationResult = {};
|
764
|
+
for (const key in validate) {
|
765
|
+
if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) {
|
766
|
+
break;
|
767
|
+
}
|
768
|
+
const validateError = getValidateError(await validate[key](inputValue), inputRef, key);
|
769
|
+
if (validateError) {
|
770
|
+
validationResult = {
|
771
|
+
...validateError,
|
772
|
+
...appendErrorsCurry(key, validateError.message),
|
773
|
+
};
|
774
|
+
setCustomValidity(validateError.message);
|
775
|
+
if (validateAllFieldCriteria) {
|
776
|
+
error[name] = validationResult;
|
777
|
+
}
|
778
|
+
}
|
779
|
+
}
|
780
|
+
if (!isEmptyObject(validationResult)) {
|
781
|
+
error[name] = {
|
782
|
+
ref: inputRef,
|
783
|
+
...validationResult,
|
784
|
+
};
|
785
|
+
if (!validateAllFieldCriteria) {
|
786
|
+
return error;
|
787
|
+
}
|
788
|
+
}
|
789
|
+
}
|
790
|
+
}
|
791
|
+
setCustomValidity(true);
|
792
|
+
return error;
|
793
|
+
};
|
794
|
+
|
558
795
|
function append(data, value) {
|
559
796
|
return [...data, ...convertToArrayPayload(value)];
|
560
797
|
}
|
@@ -591,6 +828,14 @@ function cloneObject(data) {
|
|
591
828
|
|
592
829
|
var fillEmptyArray = (value) => Array.isArray(value) ? value.map(() => undefined) : undefined;
|
593
830
|
|
831
|
+
var getValidationModes = (mode) => ({
|
832
|
+
isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
|
833
|
+
isOnBlur: mode === VALIDATION_MODE.onBlur,
|
834
|
+
isOnChange: mode === VALIDATION_MODE.onChange,
|
835
|
+
isOnAll: mode === VALIDATION_MODE.all,
|
836
|
+
isOnTouch: mode === VALIDATION_MODE.onTouched,
|
837
|
+
});
|
838
|
+
|
594
839
|
function insert(data, index, value) {
|
595
840
|
return [
|
596
841
|
...data.slice(0, index),
|
@@ -639,6 +884,14 @@ function baseGet(object, updatePath) {
|
|
639
884
|
}
|
640
885
|
return object;
|
641
886
|
}
|
887
|
+
function isEmptyArray(obj) {
|
888
|
+
for (const key in obj) {
|
889
|
+
if (!isUndefined(obj[key])) {
|
890
|
+
return false;
|
891
|
+
}
|
892
|
+
}
|
893
|
+
return true;
|
894
|
+
}
|
642
895
|
function unset(object, path) {
|
643
896
|
const updatePath = isKey(path) ? [path] : stringToPath(path);
|
644
897
|
const childObject = updatePath.length == 1 ? object : baseGet(object, updatePath);
|
@@ -660,8 +913,7 @@ function unset(object, path) {
|
|
660
913
|
objectRef = objectRef ? objectRef[item] : object[item];
|
661
914
|
if (currentPathsLength === index &&
|
662
915
|
((isObject(objectRef) && isEmptyObject(objectRef)) ||
|
663
|
-
(Array.isArray(objectRef) &&
|
664
|
-
!objectRef.filter((data) => !isUndefined(data)).length))) {
|
916
|
+
(Array.isArray(objectRef) && isEmptyArray(objectRef)))) {
|
665
917
|
previousObjRef ? delete previousObjRef[item] : delete object[item];
|
666
918
|
}
|
667
919
|
previousObjRef = objectRef;
|
@@ -723,6 +975,8 @@ function useFieldArray(props) {
|
|
723
975
|
_name.current = name;
|
724
976
|
_fieldIds.current = fields;
|
725
977
|
control._names.array.add(name);
|
978
|
+
props.rules &&
|
979
|
+
control.register(name, props.rules);
|
726
980
|
const callback = React.useCallback(({ values, name: fieldArrayName, }) => {
|
727
981
|
if (fieldArrayName === _name.current || !fieldArrayName) {
|
728
982
|
const fieldValues = get(values, _name.current, []);
|
@@ -825,18 +1079,33 @@ function useFieldArray(props) {
|
|
825
1079
|
control._stateFlags.action = false;
|
826
1080
|
isWatched(name, control._names) && control._subjects.state.next({});
|
827
1081
|
if (_actioned.current) {
|
828
|
-
control.
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
error
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
1082
|
+
if (control._options.resolver) {
|
1083
|
+
control._executeSchema([name]).then((result) => {
|
1084
|
+
const error = get(result.errors, name);
|
1085
|
+
const existingError = get(control._formState.errors, name);
|
1086
|
+
if (existingError ? !error && existingError.type : error && error.type) {
|
1087
|
+
error
|
1088
|
+
? set(control._formState.errors, name, error)
|
1089
|
+
: unset(control._formState.errors, name);
|
1090
|
+
control._subjects.state.next({
|
1091
|
+
errors: control._formState.errors,
|
1092
|
+
});
|
1093
|
+
}
|
1094
|
+
});
|
1095
|
+
}
|
1096
|
+
else {
|
1097
|
+
const field = get(control._fields, name);
|
1098
|
+
const validationModeBeforeSubmit = getValidationModes(control._options.mode);
|
1099
|
+
if ((!validationModeBeforeSubmit.isOnSubmit ||
|
1100
|
+
control._formState.isSubmitted) &&
|
1101
|
+
field &&
|
1102
|
+
field._f) {
|
1103
|
+
validateField(field, get(control._formValues, name), control._options.criteriaMode === VALIDATION_MODE.all, control._options.shouldUseNativeValidation, true).then((error) => !isEmptyObject(error) &&
|
1104
|
+
control._subjects.state.next({
|
1105
|
+
errors: updateFieldArrayRootError(control._formState.errors, error, name),
|
1106
|
+
}));
|
838
1107
|
}
|
839
|
-
}
|
1108
|
+
}
|
840
1109
|
}
|
841
1110
|
control._subjects.watch.next({
|
842
1111
|
name,
|
@@ -931,18 +1200,6 @@ function deepEqual(object1, object2) {
|
|
931
1200
|
return true;
|
932
1201
|
}
|
933
1202
|
|
934
|
-
var getValidationModes = (mode) => ({
|
935
|
-
isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
|
936
|
-
isOnBlur: mode === VALIDATION_MODE.onBlur,
|
937
|
-
isOnChange: mode === VALIDATION_MODE.onChange,
|
938
|
-
isOnAll: mode === VALIDATION_MODE.all,
|
939
|
-
isOnTouch: mode === VALIDATION_MODE.onTouched,
|
940
|
-
});
|
941
|
-
|
942
|
-
var isBoolean = (value) => typeof value === 'boolean';
|
943
|
-
|
944
|
-
var isFileInput = (element) => element.type === 'file';
|
945
|
-
|
946
1203
|
var isHTMLElement = (value) => {
|
947
1204
|
const owner = value ? value.ownerDocument : 0;
|
948
1205
|
const ElementClass = owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement;
|
@@ -951,8 +1208,6 @@ var isHTMLElement = (value) => {
|
|
951
1208
|
|
952
1209
|
var isMultipleSelect = (element) => element.type === `select-multiple`;
|
953
1210
|
|
954
|
-
var isRadioInput = (element) => element.type === 'radio';
|
955
|
-
|
956
1211
|
var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
|
957
1212
|
|
958
1213
|
var live = (ref) => isHTMLElement(ref) && ref.isConnected;
|
@@ -998,31 +1253,6 @@ function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues
|
|
998
1253
|
}
|
999
1254
|
var getDirtyFields = (defaultValues, formValues) => getDirtyFieldsFromDefaultValues(defaultValues, formValues, markFieldsDirty(formValues));
|
1000
1255
|
|
1001
|
-
const defaultResult = {
|
1002
|
-
value: false,
|
1003
|
-
isValid: false,
|
1004
|
-
};
|
1005
|
-
const validResult = { value: true, isValid: true };
|
1006
|
-
var getCheckboxValue = (options) => {
|
1007
|
-
if (Array.isArray(options)) {
|
1008
|
-
if (options.length > 1) {
|
1009
|
-
const values = options
|
1010
|
-
.filter((option) => option && option.checked && !option.disabled)
|
1011
|
-
.map((option) => option.value);
|
1012
|
-
return { value: values, isValid: !!values.length };
|
1013
|
-
}
|
1014
|
-
return options[0].checked && !options[0].disabled
|
1015
|
-
? // @ts-expect-error expected to work in the browser
|
1016
|
-
options[0].attributes && !isUndefined(options[0].attributes.value)
|
1017
|
-
? isUndefined(options[0].value) || options[0].value === ''
|
1018
|
-
? validResult
|
1019
|
-
: { value: options[0].value, isValid: true }
|
1020
|
-
: validResult
|
1021
|
-
: defaultResult;
|
1022
|
-
}
|
1023
|
-
return defaultResult;
|
1024
|
-
};
|
1025
|
-
|
1026
1256
|
var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isUndefined(value)
|
1027
1257
|
? value
|
1028
1258
|
: valueAsNumber
|
@@ -1035,19 +1265,6 @@ var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isU
|
|
1035
1265
|
? setValueAs(value)
|
1036
1266
|
: value;
|
1037
1267
|
|
1038
|
-
const defaultReturn = {
|
1039
|
-
isValid: false,
|
1040
|
-
value: null,
|
1041
|
-
};
|
1042
|
-
var getRadioValue = (options) => Array.isArray(options)
|
1043
|
-
? options.reduce((previous, option) => option && option.checked && !option.disabled
|
1044
|
-
? {
|
1045
|
-
isValid: true,
|
1046
|
-
value: option.value,
|
1047
|
-
}
|
1048
|
-
: previous, defaultReturn)
|
1049
|
-
: defaultReturn;
|
1050
|
-
|
1051
1268
|
function getFieldValue(_f) {
|
1052
1269
|
const ref = _f.ref;
|
1053
1270
|
if (_f.refs ? _f.refs.every((ref) => ref.disabled) : ref.disabled) {
|
@@ -1082,8 +1299,6 @@ var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeVal
|
|
1082
1299
|
};
|
1083
1300
|
};
|
1084
1301
|
|
1085
|
-
var isRegex = (value) => value instanceof RegExp;
|
1086
|
-
|
1087
1302
|
var getRuleValue = (rule) => isUndefined(rule)
|
1088
1303
|
? undefined
|
1089
1304
|
: isRegex(rule)
|
@@ -1150,186 +1365,6 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
|
|
1150
1365
|
|
1151
1366
|
var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
|
1152
1367
|
|
1153
|
-
var isMessage = (value) => isString(value) || React.isValidElement(value);
|
1154
|
-
|
1155
|
-
function getValidateError(result, ref, type = 'validate') {
|
1156
|
-
if (isMessage(result) ||
|
1157
|
-
(Array.isArray(result) && result.every(isMessage)) ||
|
1158
|
-
(isBoolean(result) && !result)) {
|
1159
|
-
return {
|
1160
|
-
type,
|
1161
|
-
message: isMessage(result) ? result : '',
|
1162
|
-
ref,
|
1163
|
-
};
|
1164
|
-
}
|
1165
|
-
}
|
1166
|
-
|
1167
|
-
var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData)
|
1168
|
-
? validationData
|
1169
|
-
: {
|
1170
|
-
value: validationData,
|
1171
|
-
message: '',
|
1172
|
-
};
|
1173
|
-
|
1174
|
-
var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUseNativeValidation) => {
|
1175
|
-
const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount, disabled, } = field._f;
|
1176
|
-
if (!mount || disabled) {
|
1177
|
-
return {};
|
1178
|
-
}
|
1179
|
-
const inputRef = refs ? refs[0] : ref;
|
1180
|
-
const setCustomValidity = (message) => {
|
1181
|
-
if (shouldUseNativeValidation && inputRef.reportValidity) {
|
1182
|
-
inputRef.setCustomValidity(isBoolean(message) ? '' : message || ' ');
|
1183
|
-
inputRef.reportValidity();
|
1184
|
-
}
|
1185
|
-
};
|
1186
|
-
const error = {};
|
1187
|
-
const isRadio = isRadioInput(ref);
|
1188
|
-
const isCheckBox = isCheckBoxInput(ref);
|
1189
|
-
const isRadioOrCheckbox = isRadio || isCheckBox;
|
1190
|
-
const isEmpty = ((valueAsNumber || isFileInput(ref)) && !ref.value) ||
|
1191
|
-
inputValue === '' ||
|
1192
|
-
(Array.isArray(inputValue) && !inputValue.length);
|
1193
|
-
const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
|
1194
|
-
const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
|
1195
|
-
const message = exceedMax ? maxLengthMessage : minLengthMessage;
|
1196
|
-
error[name] = {
|
1197
|
-
type: exceedMax ? maxType : minType,
|
1198
|
-
message,
|
1199
|
-
ref,
|
1200
|
-
...appendErrorsCurry(exceedMax ? maxType : minType, message),
|
1201
|
-
};
|
1202
|
-
};
|
1203
|
-
if (required &&
|
1204
|
-
((!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue))) ||
|
1205
|
-
(isBoolean(inputValue) && !inputValue) ||
|
1206
|
-
(isCheckBox && !getCheckboxValue(refs).isValid) ||
|
1207
|
-
(isRadio && !getRadioValue(refs).isValid))) {
|
1208
|
-
const { value, message } = isMessage(required)
|
1209
|
-
? { value: !!required, message: required }
|
1210
|
-
: getValueAndMessage(required);
|
1211
|
-
if (value) {
|
1212
|
-
error[name] = {
|
1213
|
-
type: INPUT_VALIDATION_RULES.required,
|
1214
|
-
message,
|
1215
|
-
ref: inputRef,
|
1216
|
-
...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message),
|
1217
|
-
};
|
1218
|
-
if (!validateAllFieldCriteria) {
|
1219
|
-
setCustomValidity(message);
|
1220
|
-
return error;
|
1221
|
-
}
|
1222
|
-
}
|
1223
|
-
}
|
1224
|
-
if (!isEmpty && (!isNullOrUndefined(min) || !isNullOrUndefined(max))) {
|
1225
|
-
let exceedMax;
|
1226
|
-
let exceedMin;
|
1227
|
-
const maxOutput = getValueAndMessage(max);
|
1228
|
-
const minOutput = getValueAndMessage(min);
|
1229
|
-
if (!isNullOrUndefined(inputValue) && !isNaN(inputValue)) {
|
1230
|
-
const valueNumber = ref.valueAsNumber || +inputValue;
|
1231
|
-
if (!isNullOrUndefined(maxOutput.value)) {
|
1232
|
-
exceedMax = valueNumber > maxOutput.value;
|
1233
|
-
}
|
1234
|
-
if (!isNullOrUndefined(minOutput.value)) {
|
1235
|
-
exceedMin = valueNumber < minOutput.value;
|
1236
|
-
}
|
1237
|
-
}
|
1238
|
-
else {
|
1239
|
-
const valueDate = ref.valueAsDate || new Date(inputValue);
|
1240
|
-
if (isString(maxOutput.value)) {
|
1241
|
-
exceedMax = valueDate > new Date(maxOutput.value);
|
1242
|
-
}
|
1243
|
-
if (isString(minOutput.value)) {
|
1244
|
-
exceedMin = valueDate < new Date(minOutput.value);
|
1245
|
-
}
|
1246
|
-
}
|
1247
|
-
if (exceedMax || exceedMin) {
|
1248
|
-
getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
|
1249
|
-
if (!validateAllFieldCriteria) {
|
1250
|
-
setCustomValidity(error[name].message);
|
1251
|
-
return error;
|
1252
|
-
}
|
1253
|
-
}
|
1254
|
-
}
|
1255
|
-
if ((maxLength || minLength) && !isEmpty && isString(inputValue)) {
|
1256
|
-
const maxLengthOutput = getValueAndMessage(maxLength);
|
1257
|
-
const minLengthOutput = getValueAndMessage(minLength);
|
1258
|
-
const exceedMax = !isNullOrUndefined(maxLengthOutput.value) &&
|
1259
|
-
inputValue.length > maxLengthOutput.value;
|
1260
|
-
const exceedMin = !isNullOrUndefined(minLengthOutput.value) &&
|
1261
|
-
inputValue.length < minLengthOutput.value;
|
1262
|
-
if (exceedMax || exceedMin) {
|
1263
|
-
getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
|
1264
|
-
if (!validateAllFieldCriteria) {
|
1265
|
-
setCustomValidity(error[name].message);
|
1266
|
-
return error;
|
1267
|
-
}
|
1268
|
-
}
|
1269
|
-
}
|
1270
|
-
if (pattern && !isEmpty && isString(inputValue)) {
|
1271
|
-
const { value: patternValue, message } = getValueAndMessage(pattern);
|
1272
|
-
if (isRegex(patternValue) && !inputValue.match(patternValue)) {
|
1273
|
-
error[name] = {
|
1274
|
-
type: INPUT_VALIDATION_RULES.pattern,
|
1275
|
-
message,
|
1276
|
-
ref,
|
1277
|
-
...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message),
|
1278
|
-
};
|
1279
|
-
if (!validateAllFieldCriteria) {
|
1280
|
-
setCustomValidity(message);
|
1281
|
-
return error;
|
1282
|
-
}
|
1283
|
-
}
|
1284
|
-
}
|
1285
|
-
if (validate) {
|
1286
|
-
if (isFunction(validate)) {
|
1287
|
-
const result = await validate(inputValue);
|
1288
|
-
const validateError = getValidateError(result, inputRef);
|
1289
|
-
if (validateError) {
|
1290
|
-
error[name] = {
|
1291
|
-
...validateError,
|
1292
|
-
...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message),
|
1293
|
-
};
|
1294
|
-
if (!validateAllFieldCriteria) {
|
1295
|
-
setCustomValidity(validateError.message);
|
1296
|
-
return error;
|
1297
|
-
}
|
1298
|
-
}
|
1299
|
-
}
|
1300
|
-
else if (isObject(validate)) {
|
1301
|
-
let validationResult = {};
|
1302
|
-
for (const key in validate) {
|
1303
|
-
if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) {
|
1304
|
-
break;
|
1305
|
-
}
|
1306
|
-
const validateError = getValidateError(await validate[key](inputValue), inputRef, key);
|
1307
|
-
if (validateError) {
|
1308
|
-
validationResult = {
|
1309
|
-
...validateError,
|
1310
|
-
...appendErrorsCurry(key, validateError.message),
|
1311
|
-
};
|
1312
|
-
setCustomValidity(validateError.message);
|
1313
|
-
if (validateAllFieldCriteria) {
|
1314
|
-
error[name] = validationResult;
|
1315
|
-
}
|
1316
|
-
}
|
1317
|
-
}
|
1318
|
-
if (!isEmptyObject(validationResult)) {
|
1319
|
-
error[name] = {
|
1320
|
-
ref: inputRef,
|
1321
|
-
...validationResult,
|
1322
|
-
};
|
1323
|
-
if (!validateAllFieldCriteria) {
|
1324
|
-
return error;
|
1325
|
-
}
|
1326
|
-
}
|
1327
|
-
}
|
1328
|
-
}
|
1329
|
-
setCustomValidity(true);
|
1330
|
-
return error;
|
1331
|
-
};
|
1332
|
-
|
1333
1368
|
const defaultOptions = {
|
1334
1369
|
mode: VALIDATION_MODE.onSubmit,
|
1335
1370
|
reValidateMode: VALIDATION_MODE.onChange,
|
@@ -1396,7 +1431,7 @@ function createFormControl(props = {}) {
|
|
1396
1431
|
if (_proxyFormState.isValid) {
|
1397
1432
|
isValid = _options.resolver
|
1398
1433
|
? isEmptyObject((await _executeSchema()).errors)
|
1399
|
-
: await
|
1434
|
+
: await executeBuiltInValidation(_fields, true);
|
1400
1435
|
if (!shouldSkipRender && isValid !== _formState.isValid) {
|
1401
1436
|
_formState.isValid = isValid;
|
1402
1437
|
_subjects.state.next({
|
@@ -1547,29 +1582,31 @@ function createFormControl(props = {}) {
|
|
1547
1582
|
}
|
1548
1583
|
return errors;
|
1549
1584
|
};
|
1550
|
-
const
|
1585
|
+
const executeBuiltInValidation = async (fields, shouldOnlyCheckValid, context = {
|
1551
1586
|
valid: true,
|
1552
1587
|
}) => {
|
1553
1588
|
for (const name in fields) {
|
1554
1589
|
const field = fields[name];
|
1555
1590
|
if (field) {
|
1556
|
-
const { _f
|
1557
|
-
if (
|
1558
|
-
const
|
1559
|
-
|
1591
|
+
const { _f, ...fieldValue } = field;
|
1592
|
+
if (_f) {
|
1593
|
+
const isFieldArrayRoot = _names.array.has(_f.name);
|
1594
|
+
const fieldError = await validateField(field, get(_formValues, _f.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation, isFieldArrayRoot);
|
1595
|
+
if (fieldError[_f.name]) {
|
1560
1596
|
context.valid = false;
|
1561
1597
|
if (shouldOnlyCheckValid) {
|
1562
1598
|
break;
|
1563
1599
|
}
|
1564
1600
|
}
|
1565
|
-
|
1566
|
-
fieldError
|
1567
|
-
?
|
1568
|
-
|
1569
|
-
|
1601
|
+
!shouldOnlyCheckValid &&
|
1602
|
+
(get(fieldError, _f.name)
|
1603
|
+
? isFieldArrayRoot
|
1604
|
+
? updateFieldArrayRootError(_formState.errors, fieldError, _f.name)
|
1605
|
+
: set(_formState.errors, _f.name, fieldError[_f.name])
|
1606
|
+
: unset(_formState.errors, _f.name));
|
1570
1607
|
}
|
1571
1608
|
fieldValue &&
|
1572
|
-
(await
|
1609
|
+
(await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context));
|
1573
1610
|
}
|
1574
1611
|
}
|
1575
1612
|
return context.valid;
|
@@ -1764,12 +1801,12 @@ function createFormControl(props = {}) {
|
|
1764
1801
|
else if (name) {
|
1765
1802
|
validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
|
1766
1803
|
const field = get(_fields, fieldName);
|
1767
|
-
return await
|
1804
|
+
return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
|
1768
1805
|
}))).every(Boolean);
|
1769
1806
|
!(!validationResult && !_formState.isValid) && _updateValid();
|
1770
1807
|
}
|
1771
1808
|
else {
|
1772
|
-
validationResult = isValid = await
|
1809
|
+
validationResult = isValid = await executeBuiltInValidation(_fields);
|
1773
1810
|
}
|
1774
1811
|
_subjects.state.next({
|
1775
1812
|
...(!isString(name) ||
|
@@ -1949,7 +1986,7 @@ function createFormControl(props = {}) {
|
|
1949
1986
|
fieldValues = values;
|
1950
1987
|
}
|
1951
1988
|
else {
|
1952
|
-
await
|
1989
|
+
await executeBuiltInValidation(_fields);
|
1953
1990
|
}
|
1954
1991
|
if (isEmptyObject(_formState.errors)) {
|
1955
1992
|
_subjects.state.next({
|
@@ -2032,9 +2069,10 @@ function createFormControl(props = {}) {
|
|
2032
2069
|
? field._f.refs[0]
|
2033
2070
|
: field._f.ref;
|
2034
2071
|
try {
|
2035
|
-
isHTMLElement(fieldReference)
|
2072
|
+
if (isHTMLElement(fieldReference)) {
|
2036
2073
|
fieldReference.closest('form').reset();
|
2037
|
-
|
2074
|
+
break;
|
2075
|
+
}
|
2038
2076
|
}
|
2039
2077
|
catch (_a) { }
|
2040
2078
|
}
|
@@ -2094,7 +2132,8 @@ function createFormControl(props = {}) {
|
|
2094
2132
|
const setFocus = (name, options = {}) => {
|
2095
2133
|
const field = get(_fields, name)._f;
|
2096
2134
|
const fieldRef = field.refs ? field.refs[0] : field.ref;
|
2097
|
-
|
2135
|
+
fieldRef.focus();
|
2136
|
+
options.shouldSelect && fieldRef.select();
|
2098
2137
|
};
|
2099
2138
|
return {
|
2100
2139
|
control: {
|
@@ -2164,7 +2203,7 @@ function createFormControl(props = {}) {
|
|
2164
2203
|
}
|
2165
2204
|
|
2166
2205
|
/**
|
2167
|
-
* Custom hook to
|
2206
|
+
* Custom hook to manage the entire form.
|
2168
2207
|
*
|
2169
2208
|
* @remarks
|
2170
2209
|
* [API](https://react-hook-form.com/api/useform) • [Demo](https://codesandbox.io/s/react-hook-form-get-started-ts-5ksmm) • [Video](https://www.youtube.com/watch?v=RkXv4AXXC_4)
|