react-hook-form 7.33.1 → 7.34.0-next.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.
@@ -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,
@@ -1553,20 +1588,22 @@ function createFormControl(props = {}) {
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
1609
  (await executeBuildInValidation(fieldValue, shouldOnlyCheckValid, context));
@@ -2165,7 +2202,7 @@ function createFormControl(props = {}) {
2165
2202
  }
2166
2203
 
2167
2204
  /**
2168
- * Custom hook to mange the entire form.
2205
+ * Custom hook to manage the entire form.
2169
2206
  *
2170
2207
  * @remarks
2171
2208
  * [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)