react-hook-form 7.33.1 → 7.34.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.
@@ -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._executeSchema([name]).then((result) => {
829
- const error = get(result.errors, name);
830
- const existingError = get(control._formState.errors, name);
831
- if (existingError ? !error && existingError.type : error && error.type) {
832
- error
833
- ? set(control._formState.errors, name, error)
834
- : unset(control._formState.errors, name);
835
- control._subjects.state.next({
836
- errors: control._formState.errors,
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 executeBuildInValidation(_fields, true);
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 executeBuildInValidation = async (fields, shouldOnlyCheckValid, context = {
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: fieldReference, ...fieldValue } = field;
1557
- if (fieldReference) {
1558
- const fieldError = await validateField(field, get(_formValues, fieldReference.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation);
1559
- if (fieldError[fieldReference.name]) {
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
- if (!shouldOnlyCheckValid) {
1566
- fieldError[fieldReference.name]
1567
- ? set(_formState.errors, fieldReference.name, fieldError[fieldReference.name])
1568
- : unset(_formState.errors, fieldReference.name);
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 executeBuildInValidation(fieldValue, shouldOnlyCheckValid, context));
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 executeBuildInValidation(field && field._f ? { [fieldName]: field } : field);
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 executeBuildInValidation(_fields);
1809
+ validationResult = isValid = await executeBuiltInValidation(_fields);
1773
1810
  }
1774
1811
  _subjects.state.next({
1775
1812
  ...(!isString(name) ||
@@ -1939,9 +1976,6 @@ function createFormControl(props = {}) {
1939
1976
  }
1940
1977
  let hasNoPromiseError = true;
1941
1978
  let fieldValues = cloneObject(_formValues);
1942
- _subjects.state.next({
1943
- isSubmitting: true,
1944
- });
1945
1979
  try {
1946
1980
  if (_options.resolver) {
1947
1981
  const { errors, values } = await _executeSchema();
@@ -1949,7 +1983,7 @@ function createFormControl(props = {}) {
1949
1983
  fieldValues = values;
1950
1984
  }
1951
1985
  else {
1952
- await executeBuildInValidation(_fields);
1986
+ await executeBuiltInValidation(_fields);
1953
1987
  }
1954
1988
  if (isEmptyObject(_formState.errors)) {
1955
1989
  _subjects.state.next({
@@ -1965,6 +1999,9 @@ function createFormControl(props = {}) {
1965
1999
  _options.shouldFocusError &&
1966
2000
  focusFieldBy(_fields, (key) => get(_formState.errors, key), _names.mount);
1967
2001
  }
2002
+ _subjects.state.next({
2003
+ isSubmitting: true,
2004
+ });
1968
2005
  }
1969
2006
  catch (err) {
1970
2007
  hasNoPromiseError = false;
@@ -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
- break;
2074
+ break;
2075
+ }
2038
2076
  }
2039
2077
  catch (_a) { }
2040
2078
  }
@@ -2165,7 +2203,7 @@ function createFormControl(props = {}) {
2165
2203
  }
2166
2204
 
2167
2205
  /**
2168
- * Custom hook to mange the entire form.
2206
+ * Custom hook to manage the entire form.
2169
2207
  *
2170
2208
  * @remarks
2171
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)