react-hook-form 8.0.0-alpha.2 → 8.0.0-alpha.3

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.
@@ -22,7 +22,7 @@ var getNodeParentName = (name) => name.substring(0, name.search(/.\d/)) || name;
22
22
 
23
23
  var isNameInFieldArray = (names, name) => [...names].some((current) => getNodeParentName(name) === current);
24
24
 
25
- var compact = (value) => value.filter(Boolean);
25
+ var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
26
26
 
27
27
  var isUndefined = (val) => val === undefined;
28
28
 
@@ -569,6 +569,241 @@ var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
569
569
  [..._names.watch].some((watchName) => name.startsWith(watchName) &&
570
570
  /^\.\w+/.test(name.slice(watchName.length))));
571
571
 
572
+ var updateFieldArrayRootError = (errors, error, name) => {
573
+ const fieldArrayErrors = compact(get(errors, name));
574
+ set(fieldArrayErrors, 'root', error[name]);
575
+ set(errors, name, fieldArrayErrors);
576
+ return errors;
577
+ };
578
+
579
+ var isBoolean = (value) => typeof value === 'boolean';
580
+
581
+ var isFileInput = (element) => element.type === 'file';
582
+
583
+ var isMessage = (value) => isString(value) || React.isValidElement(value);
584
+
585
+ var isRadioInput = (element) => element.type === 'radio';
586
+
587
+ var isRegex = (value) => value instanceof RegExp;
588
+
589
+ const defaultResult = {
590
+ value: false,
591
+ isValid: false,
592
+ };
593
+ const validResult = { value: true, isValid: true };
594
+ var getCheckboxValue = (options) => {
595
+ if (Array.isArray(options)) {
596
+ if (options.length > 1) {
597
+ const values = options
598
+ .filter((option) => option && option.checked && !option.disabled)
599
+ .map((option) => option.value);
600
+ return { value: values, isValid: !!values.length };
601
+ }
602
+ return options[0].checked && !options[0].disabled
603
+ ? // @ts-expect-error expected to work in the browser
604
+ options[0].attributes && !isUndefined(options[0].attributes.value)
605
+ ? isUndefined(options[0].value) || options[0].value === ''
606
+ ? validResult
607
+ : { value: options[0].value, isValid: true }
608
+ : validResult
609
+ : defaultResult;
610
+ }
611
+ return defaultResult;
612
+ };
613
+
614
+ const defaultReturn = {
615
+ isValid: false,
616
+ value: null,
617
+ };
618
+ var getRadioValue = (options) => Array.isArray(options)
619
+ ? options.reduce((previous, option) => option && option.checked && !option.disabled
620
+ ? {
621
+ isValid: true,
622
+ value: option.value,
623
+ }
624
+ : previous, defaultReturn)
625
+ : defaultReturn;
626
+
627
+ function getValidateError(result, ref, type = 'validate') {
628
+ if (isMessage(result) ||
629
+ (Array.isArray(result) && result.every(isMessage)) ||
630
+ (isBoolean(result) && !result)) {
631
+ return {
632
+ type,
633
+ message: isMessage(result) ? result : '',
634
+ ref,
635
+ };
636
+ }
637
+ }
638
+
639
+ var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData)
640
+ ? validationData
641
+ : {
642
+ value: validationData,
643
+ message: '',
644
+ };
645
+
646
+ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
647
+ const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount, disabled, } = field._f;
648
+ if (!mount || disabled) {
649
+ return {};
650
+ }
651
+ const inputRef = refs ? refs[0] : ref;
652
+ const setCustomValidity = (message) => {
653
+ if (shouldUseNativeValidation && inputRef.reportValidity) {
654
+ inputRef.setCustomValidity(isBoolean(message) ? '' : message || ' ');
655
+ inputRef.reportValidity();
656
+ }
657
+ };
658
+ const error = {};
659
+ const isRadio = isRadioInput(ref);
660
+ const isCheckBox = isCheckBoxInput(ref);
661
+ const isRadioOrCheckbox = isRadio || isCheckBox;
662
+ const isEmpty = ((valueAsNumber || isFileInput(ref)) && !ref.value) ||
663
+ inputValue === '' ||
664
+ (Array.isArray(inputValue) && !inputValue.length);
665
+ const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
666
+ const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
667
+ const message = exceedMax ? maxLengthMessage : minLengthMessage;
668
+ error[name] = {
669
+ type: exceedMax ? maxType : minType,
670
+ message,
671
+ ref,
672
+ ...appendErrorsCurry(exceedMax ? maxType : minType, message),
673
+ };
674
+ };
675
+ if (required &&
676
+ ((!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue))) ||
677
+ (isBoolean(inputValue) && !inputValue) ||
678
+ (isCheckBox && !getCheckboxValue(refs).isValid) ||
679
+ (isRadio && !getRadioValue(refs).isValid))) {
680
+ const { value, message } = isMessage(required)
681
+ ? { value: !!required, message: required }
682
+ : getValueAndMessage(required);
683
+ if (value) {
684
+ error[name] = {
685
+ type: INPUT_VALIDATION_RULES.required,
686
+ message,
687
+ ref: inputRef,
688
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message),
689
+ };
690
+ if (!validateAllFieldCriteria) {
691
+ setCustomValidity(message);
692
+ return error;
693
+ }
694
+ }
695
+ }
696
+ if (!isEmpty && (!isNullOrUndefined(min) || !isNullOrUndefined(max))) {
697
+ let exceedMax;
698
+ let exceedMin;
699
+ const maxOutput = getValueAndMessage(max);
700
+ const minOutput = getValueAndMessage(min);
701
+ if (!isNaN(inputValue)) {
702
+ const valueNumber = ref.valueAsNumber || +inputValue;
703
+ if (!isNullOrUndefined(maxOutput.value)) {
704
+ exceedMax = valueNumber > maxOutput.value;
705
+ }
706
+ if (!isNullOrUndefined(minOutput.value)) {
707
+ exceedMin = valueNumber < minOutput.value;
708
+ }
709
+ }
710
+ else {
711
+ const valueDate = ref.valueAsDate || new Date(inputValue);
712
+ if (isString(maxOutput.value)) {
713
+ exceedMax = valueDate > new Date(maxOutput.value);
714
+ }
715
+ if (isString(minOutput.value)) {
716
+ exceedMin = valueDate < new Date(minOutput.value);
717
+ }
718
+ }
719
+ if (exceedMax || exceedMin) {
720
+ getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
721
+ if (!validateAllFieldCriteria) {
722
+ setCustomValidity(error[name].message);
723
+ return error;
724
+ }
725
+ }
726
+ }
727
+ if ((maxLength || minLength) &&
728
+ ((!isEmpty && isString(inputValue)) ||
729
+ (isFieldArray && Array.isArray(inputValue)))) {
730
+ const maxLengthOutput = getValueAndMessage(maxLength);
731
+ const minLengthOutput = getValueAndMessage(minLength);
732
+ const exceedMax = !isNullOrUndefined(maxLengthOutput.value) &&
733
+ inputValue.length > maxLengthOutput.value;
734
+ const exceedMin = !isNullOrUndefined(minLengthOutput.value) &&
735
+ inputValue.length < minLengthOutput.value;
736
+ if (exceedMax || exceedMin) {
737
+ getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
738
+ if (!validateAllFieldCriteria) {
739
+ setCustomValidity(error[name].message);
740
+ return error;
741
+ }
742
+ }
743
+ }
744
+ if (pattern && !isEmpty && isString(inputValue)) {
745
+ const { value: patternValue, message } = getValueAndMessage(pattern);
746
+ if (isRegex(patternValue) && !inputValue.match(patternValue)) {
747
+ error[name] = {
748
+ type: INPUT_VALIDATION_RULES.pattern,
749
+ message,
750
+ ref,
751
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message),
752
+ };
753
+ if (!validateAllFieldCriteria) {
754
+ setCustomValidity(message);
755
+ return error;
756
+ }
757
+ }
758
+ }
759
+ if (validate) {
760
+ if (isFunction(validate)) {
761
+ const result = await validate(inputValue);
762
+ const validateError = getValidateError(result, inputRef);
763
+ if (validateError) {
764
+ error[name] = {
765
+ ...validateError,
766
+ ...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message),
767
+ };
768
+ if (!validateAllFieldCriteria) {
769
+ setCustomValidity(validateError.message);
770
+ return error;
771
+ }
772
+ }
773
+ }
774
+ else if (isObject(validate)) {
775
+ let validationResult = {};
776
+ for (const key in validate) {
777
+ if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) {
778
+ break;
779
+ }
780
+ const validateError = getValidateError(await validate[key](inputValue), inputRef, key);
781
+ if (validateError) {
782
+ validationResult = {
783
+ ...validateError,
784
+ ...appendErrorsCurry(key, validateError.message),
785
+ };
786
+ setCustomValidity(validateError.message);
787
+ if (validateAllFieldCriteria) {
788
+ error[name] = validationResult;
789
+ }
790
+ }
791
+ }
792
+ if (!isEmptyObject(validationResult)) {
793
+ error[name] = {
794
+ ref: inputRef,
795
+ ...validationResult,
796
+ };
797
+ if (!validateAllFieldCriteria) {
798
+ return error;
799
+ }
800
+ }
801
+ }
802
+ }
803
+ setCustomValidity(true);
804
+ return error;
805
+ };
806
+
572
807
  function append(data, value) {
573
808
  return [...data, ...convertToArrayPayload(value)];
574
809
  }
@@ -600,6 +835,14 @@ function cloneObject(data) {
600
835
 
601
836
  var fillEmptyArray = (value) => Array.isArray(value) ? value.map(() => undefined) : undefined;
602
837
 
838
+ var getValidationModes = (mode) => ({
839
+ isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
840
+ isOnBlur: mode === VALIDATION_MODE.onBlur,
841
+ isOnChange: mode === VALIDATION_MODE.onChange,
842
+ isOnAll: mode === VALIDATION_MODE.all,
843
+ isOnTouch: mode === VALIDATION_MODE.onTouched,
844
+ });
845
+
603
846
  function insert(data, index, value) {
604
847
  return [
605
848
  ...data.slice(0, index),
@@ -693,6 +936,9 @@ function useFieldArray(props) {
693
936
  _name.current = name;
694
937
  _fieldIds.current = fields;
695
938
  control._names.array.add(name);
939
+ if (props.rules) {
940
+ control.register(name, props.rules);
941
+ }
696
942
  const callback = React.useCallback(({ values, name: fieldArrayName }) => {
697
943
  if (fieldArrayName === _name.current || !fieldArrayName) {
698
944
  const fieldValues = get(values, _name.current, []);
@@ -795,15 +1041,33 @@ function useFieldArray(props) {
795
1041
  control._stateFlags.action = false;
796
1042
  isWatched(name, control._names) && control._subjects.state.next({});
797
1043
  if (_actioned.current) {
798
- control._executeSchema([name]).then((result) => {
799
- const error = get(result.errors, name);
800
- if (error && error.type && !get(control._formState.errors, name)) {
801
- set(control._formState.errors, name, error);
802
- control._subjects.state.next({
803
- errors: control._formState.errors,
1044
+ if (control._options.resolver) {
1045
+ control._executeSchema([name]).then((result) => {
1046
+ const error = get(result.errors, name);
1047
+ if (error && error.type && !get(control._formState.errors, name)) {
1048
+ set(control._formState.errors, name, error);
1049
+ control._subjects.state.next({
1050
+ errors: control._formState.errors,
1051
+ });
1052
+ }
1053
+ });
1054
+ }
1055
+ else {
1056
+ const field = get(control._fields, name);
1057
+ const validationModeBeforeSubmit = getValidationModes(control._options.mode);
1058
+ if ((!validationModeBeforeSubmit.isOnSubmit ||
1059
+ control._formState.isSubmitted) &&
1060
+ field &&
1061
+ field._f) {
1062
+ validateField(field, get(control._formValues, name), control._options.criteriaMode === VALIDATION_MODE.all, control._options.shouldUseNativeValidation, true).then((error) => {
1063
+ if (!isEmptyObject(error)) {
1064
+ control._subjects.state.next({
1065
+ errors: updateFieldArrayRootError(control._formState.errors, error, name),
1066
+ });
1067
+ }
804
1068
  });
805
1069
  }
806
- });
1070
+ }
807
1071
  }
808
1072
  control._subjects.watch.next({
809
1073
  name,
@@ -898,24 +1162,10 @@ function deepEqual(object1, object2) {
898
1162
  return true;
899
1163
  }
900
1164
 
901
- var getValidationModes = (mode) => ({
902
- isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
903
- isOnBlur: mode === VALIDATION_MODE.onBlur,
904
- isOnChange: mode === VALIDATION_MODE.onChange,
905
- isOnAll: mode === VALIDATION_MODE.all,
906
- isOnTouch: mode === VALIDATION_MODE.onTouched,
907
- });
908
-
909
- var isBoolean = (value) => typeof value === 'boolean';
910
-
911
- var isFileInput = (element) => element.type === 'file';
912
-
913
1165
  var isHTMLElement = (value) => value instanceof HTMLElement;
914
1166
 
915
1167
  var isMultipleSelect = (element) => element.type === `select-multiple`;
916
1168
 
917
- var isRadioInput = (element) => element.type === 'radio';
918
-
919
1169
  var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
920
1170
 
921
1171
  var isWeb = typeof window !== 'undefined' &&
@@ -932,6 +1182,14 @@ function baseGet(object, updatePath) {
932
1182
  }
933
1183
  return object;
934
1184
  }
1185
+ function isEmptyArray(obj) {
1186
+ for (const key in obj) {
1187
+ if (!isUndefined(obj[key])) {
1188
+ return false;
1189
+ }
1190
+ }
1191
+ return true;
1192
+ }
935
1193
  function unset(object, path) {
936
1194
  const updatePath = isKey(path) ? [path] : stringToPath(path);
937
1195
  const childObject = updatePath.length == 1 ? object : baseGet(object, updatePath);
@@ -953,8 +1211,7 @@ function unset(object, path) {
953
1211
  objectRef = objectRef ? objectRef[item] : object[item];
954
1212
  if (currentPathsLength === index &&
955
1213
  ((isObject(objectRef) && isEmptyObject(objectRef)) ||
956
- (Array.isArray(objectRef) &&
957
- !objectRef.filter((data) => !isUndefined(data)).length))) {
1214
+ (Array.isArray(objectRef) && isEmptyArray(objectRef)))) {
958
1215
  previousObjRef ? delete previousObjRef[item] : delete object[item];
959
1216
  }
960
1217
  previousObjRef = objectRef;
@@ -1004,31 +1261,6 @@ function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues
1004
1261
  }
1005
1262
  var getDirtyFields = (defaultValues, formValues) => getDirtyFieldsFromDefaultValues(defaultValues, formValues, markFieldsDirty(formValues));
1006
1263
 
1007
- const defaultResult = {
1008
- value: false,
1009
- isValid: false,
1010
- };
1011
- const validResult = { value: true, isValid: true };
1012
- var getCheckboxValue = (options) => {
1013
- if (Array.isArray(options)) {
1014
- if (options.length > 1) {
1015
- const values = options
1016
- .filter((option) => option && option.checked && !option.disabled)
1017
- .map((option) => option.value);
1018
- return { value: values, isValid: !!values.length };
1019
- }
1020
- return options[0].checked && !options[0].disabled
1021
- ? // @ts-expect-error expected to work in the browser
1022
- options[0].attributes && !isUndefined(options[0].attributes.value)
1023
- ? isUndefined(options[0].value) || options[0].value === ''
1024
- ? validResult
1025
- : { value: options[0].value, isValid: true }
1026
- : validResult
1027
- : defaultResult;
1028
- }
1029
- return defaultResult;
1030
- };
1031
-
1032
1264
  var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isUndefined(value)
1033
1265
  ? value
1034
1266
  : valueAsNumber
@@ -1041,19 +1273,6 @@ var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isU
1041
1273
  ? setValueAs(value)
1042
1274
  : value;
1043
1275
 
1044
- const defaultReturn = {
1045
- isValid: false,
1046
- value: null,
1047
- };
1048
- var getRadioValue = (options) => Array.isArray(options)
1049
- ? options.reduce((previous, option) => option && option.checked && !option.disabled
1050
- ? {
1051
- isValid: true,
1052
- value: option.value,
1053
- }
1054
- : previous, defaultReturn)
1055
- : defaultReturn;
1056
-
1057
1276
  function getFieldValue(_f) {
1058
1277
  const ref = _f.ref;
1059
1278
  if (_f.refs ? _f.refs.every((ref) => ref.disabled) : ref.disabled) {
@@ -1088,8 +1307,6 @@ var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeVal
1088
1307
  };
1089
1308
  };
1090
1309
 
1091
- var isRegex = (value) => value instanceof RegExp;
1092
-
1093
1310
  var getRuleValue = (rule) => isUndefined(rule)
1094
1311
  ? undefined
1095
1312
  : isRegex(rule)
@@ -1156,186 +1373,6 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
1156
1373
 
1157
1374
  var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
1158
1375
 
1159
- var isMessage = (value) => isString(value) || React.isValidElement(value);
1160
-
1161
- function getValidateError(result, ref, type = 'validate') {
1162
- if (isMessage(result) ||
1163
- (Array.isArray(result) && result.every(isMessage)) ||
1164
- (isBoolean(result) && !result)) {
1165
- return {
1166
- type,
1167
- message: isMessage(result) ? result : '',
1168
- ref,
1169
- };
1170
- }
1171
- }
1172
-
1173
- var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData)
1174
- ? validationData
1175
- : {
1176
- value: validationData,
1177
- message: '',
1178
- };
1179
-
1180
- var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUseNativeValidation) => {
1181
- const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount, disabled, } = field._f;
1182
- if (!mount || disabled) {
1183
- return {};
1184
- }
1185
- const inputRef = refs ? refs[0] : ref;
1186
- const setCustomValidity = (message) => {
1187
- if (shouldUseNativeValidation && inputRef.reportValidity) {
1188
- inputRef.setCustomValidity(isBoolean(message) ? '' : message || ' ');
1189
- inputRef.reportValidity();
1190
- }
1191
- };
1192
- const error = {};
1193
- const isRadio = isRadioInput(ref);
1194
- const isCheckBox = isCheckBoxInput(ref);
1195
- const isRadioOrCheckbox = isRadio || isCheckBox;
1196
- const isEmpty = ((valueAsNumber || isFileInput(ref)) && !ref.value) ||
1197
- inputValue === '' ||
1198
- (Array.isArray(inputValue) && !inputValue.length);
1199
- const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
1200
- const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
1201
- const message = exceedMax ? maxLengthMessage : minLengthMessage;
1202
- error[name] = {
1203
- type: exceedMax ? maxType : minType,
1204
- message,
1205
- ref,
1206
- ...appendErrorsCurry(exceedMax ? maxType : minType, message),
1207
- };
1208
- };
1209
- if (required &&
1210
- ((!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue))) ||
1211
- (isBoolean(inputValue) && !inputValue) ||
1212
- (isCheckBox && !getCheckboxValue(refs).isValid) ||
1213
- (isRadio && !getRadioValue(refs).isValid))) {
1214
- const { value, message } = isMessage(required)
1215
- ? { value: !!required, message: required }
1216
- : getValueAndMessage(required);
1217
- if (value) {
1218
- error[name] = {
1219
- type: INPUT_VALIDATION_RULES.required,
1220
- message,
1221
- ref: inputRef,
1222
- ...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message),
1223
- };
1224
- if (!validateAllFieldCriteria) {
1225
- setCustomValidity(message);
1226
- return error;
1227
- }
1228
- }
1229
- }
1230
- if (!isEmpty && (!isNullOrUndefined(min) || !isNullOrUndefined(max))) {
1231
- let exceedMax;
1232
- let exceedMin;
1233
- const maxOutput = getValueAndMessage(max);
1234
- const minOutput = getValueAndMessage(min);
1235
- if (!isNaN(inputValue)) {
1236
- const valueNumber = ref.valueAsNumber || +inputValue;
1237
- if (!isNullOrUndefined(maxOutput.value)) {
1238
- exceedMax = valueNumber > maxOutput.value;
1239
- }
1240
- if (!isNullOrUndefined(minOutput.value)) {
1241
- exceedMin = valueNumber < minOutput.value;
1242
- }
1243
- }
1244
- else {
1245
- const valueDate = ref.valueAsDate || new Date(inputValue);
1246
- if (isString(maxOutput.value)) {
1247
- exceedMax = valueDate > new Date(maxOutput.value);
1248
- }
1249
- if (isString(minOutput.value)) {
1250
- exceedMin = valueDate < new Date(minOutput.value);
1251
- }
1252
- }
1253
- if (exceedMax || exceedMin) {
1254
- getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
1255
- if (!validateAllFieldCriteria) {
1256
- setCustomValidity(error[name].message);
1257
- return error;
1258
- }
1259
- }
1260
- }
1261
- if ((maxLength || minLength) && !isEmpty && isString(inputValue)) {
1262
- const maxLengthOutput = getValueAndMessage(maxLength);
1263
- const minLengthOutput = getValueAndMessage(minLength);
1264
- const exceedMax = !isNullOrUndefined(maxLengthOutput.value) &&
1265
- inputValue.length > maxLengthOutput.value;
1266
- const exceedMin = !isNullOrUndefined(minLengthOutput.value) &&
1267
- inputValue.length < minLengthOutput.value;
1268
- if (exceedMax || exceedMin) {
1269
- getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
1270
- if (!validateAllFieldCriteria) {
1271
- setCustomValidity(error[name].message);
1272
- return error;
1273
- }
1274
- }
1275
- }
1276
- if (pattern && !isEmpty && isString(inputValue)) {
1277
- const { value: patternValue, message } = getValueAndMessage(pattern);
1278
- if (isRegex(patternValue) && !inputValue.match(patternValue)) {
1279
- error[name] = {
1280
- type: INPUT_VALIDATION_RULES.pattern,
1281
- message,
1282
- ref,
1283
- ...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message),
1284
- };
1285
- if (!validateAllFieldCriteria) {
1286
- setCustomValidity(message);
1287
- return error;
1288
- }
1289
- }
1290
- }
1291
- if (validate) {
1292
- if (isFunction(validate)) {
1293
- const result = await validate(inputValue);
1294
- const validateError = getValidateError(result, inputRef);
1295
- if (validateError) {
1296
- error[name] = {
1297
- ...validateError,
1298
- ...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message),
1299
- };
1300
- if (!validateAllFieldCriteria) {
1301
- setCustomValidity(validateError.message);
1302
- return error;
1303
- }
1304
- }
1305
- }
1306
- else if (isObject(validate)) {
1307
- let validationResult = {};
1308
- for (const key in validate) {
1309
- if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) {
1310
- break;
1311
- }
1312
- const validateError = getValidateError(await validate[key](inputValue), inputRef, key);
1313
- if (validateError) {
1314
- validationResult = {
1315
- ...validateError,
1316
- ...appendErrorsCurry(key, validateError.message),
1317
- };
1318
- setCustomValidity(validateError.message);
1319
- if (validateAllFieldCriteria) {
1320
- error[name] = validationResult;
1321
- }
1322
- }
1323
- }
1324
- if (!isEmptyObject(validationResult)) {
1325
- error[name] = {
1326
- ref: inputRef,
1327
- ...validationResult,
1328
- };
1329
- if (!validateAllFieldCriteria) {
1330
- return error;
1331
- }
1332
- }
1333
- }
1334
- }
1335
- setCustomValidity(true);
1336
- return error;
1337
- };
1338
-
1339
1376
  const defaultOptions = {
1340
1377
  mode: VALIDATION_MODE.onSubmit,
1341
1378
  reValidateMode: VALIDATION_MODE.onChange,
@@ -1558,19 +1595,28 @@ function createFormControl(props = {}) {
1558
1595
  for (const name in fields) {
1559
1596
  const field = fields[name];
1560
1597
  if (field) {
1561
- const { _f: fieldReference, ...fieldValue } = field;
1562
- if (fieldReference) {
1563
- const fieldError = await validateField(field, get(_formValues, fieldReference.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation);
1564
- if (fieldError[fieldReference.name]) {
1598
+ const { _f, ...fieldValue } = field;
1599
+ if (_f) {
1600
+ const isFieldArrayRoot = _names.array.has(_f.name);
1601
+ const fieldError = await validateField(field, get(_formValues, _f.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation, isFieldArrayRoot);
1602
+ if (fieldError[_f.name]) {
1565
1603
  context.valid = false;
1566
1604
  if (shouldOnlyCheckValid) {
1567
1605
  break;
1568
1606
  }
1569
1607
  }
1570
1608
  if (!shouldOnlyCheckValid) {
1571
- fieldError[fieldReference.name]
1572
- ? set(_formState.errors, fieldReference.name, fieldError[fieldReference.name])
1573
- : unset(_formState.errors, fieldReference.name);
1609
+ if (get(fieldError, _f.name)) {
1610
+ if (isFieldArrayRoot) {
1611
+ updateFieldArrayRootError(_formState.errors, fieldError, _f.name);
1612
+ }
1613
+ else {
1614
+ set(_formState.errors, _f.name, fieldError[_f.name]);
1615
+ }
1616
+ }
1617
+ else {
1618
+ unset(_formState.errors, _f.name);
1619
+ }
1574
1620
  }
1575
1621
  }
1576
1622
  fieldValue &&