react-hook-form 7.71.2 → 7.72.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.
@@ -1 +1 @@
1
- {"version":3,"file":"createFormControl.d.ts","sourceRoot":"","sources":["../../src/logic/createFormControl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAaV,WAAW,EAiBX,YAAY,EAIZ,aAAa,EAUd,MAAM,UAAU,CAAC;AAqDlB,wBAAgB,iBAAiB,CAC/B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,GAAG,EACd,kBAAkB,GAAG,YAAY,EAEjC,KAAK,GAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAM,GACnE,IAAI,CACL,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAC,EACzD,WAAW,CACZ,GAAG;IACF,WAAW,EAAE,IAAI,CACf,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAC,EACzD,WAAW,CACZ,CAAC;CACH,CAk/CA"}
1
+ {"version":3,"file":"createFormControl.d.ts","sourceRoot":"","sources":["../../src/logic/createFormControl.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAaV,WAAW,EAiBX,YAAY,EAIZ,aAAa,EAWd,MAAM,UAAU,CAAC;AAsDlB,wBAAgB,iBAAiB,CAC/B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,GAAG,EACd,kBAAkB,GAAG,YAAY,EAEjC,KAAK,GAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAM,GACnE,IAAI,CACL,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAC,EACzD,WAAW,CACZ,GAAG;IACF,WAAW,EAAE,IAAI,CACf,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAC,EACzD,WAAW,CACZ,CAAC;CACH,CAkmDA"}
@@ -1 +1 @@
1
- {"version":3,"file":"isNameInFieldArray.d.ts","sourceRoot":"","sources":["../../src/logic/isNameInFieldArray.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;yBAIlC,OAAO,GAAG,CAAC,iBAAiB,CAAC,EAAE,MAAM,iBAAiB;AAAtE,wBACqC"}
1
+ {"version":3,"file":"isNameInFieldArray.d.ts","sourceRoot":"","sources":["../../src/logic/isNameInFieldArray.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;yBAElC,OAAO,GAAG,CAAC,iBAAiB,CAAC,EAAE,MAAM,iBAAiB;AAAtE,wBAMM"}
@@ -1 +1 @@
1
- {"version":3,"file":"updateFieldArrayRootError.d.ts","sourceRoot":"","sources":["../../src/logic/updateFieldArrayRootError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,EAClB,MAAM,UAAU,CAAC;yBAKF,CAAC,SAAS,WAAW,GAAG,WAAW,EACjD,QAAQ,WAAW,CAAC,CAAC,CAAC,EACtB,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,EAC1C,MAAM,iBAAiB,KACtB,WAAW,CAAC,CAAC,CAAC;AAJjB,wBASE"}
1
+ {"version":3,"file":"updateFieldArrayRootError.d.ts","sourceRoot":"","sources":["../../src/logic/updateFieldArrayRootError.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,EAClB,MAAM,UAAU,CAAC;yBAKF,CAAC,SAAS,WAAW,GAAG,WAAW,EACjD,QAAQ,WAAW,CAAC,CAAC,CAAC,EACtB,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,EAC1C,MAAM,iBAAiB,KACtB,WAAW,CAAC,CAAC,CAAC;AAJjB,wBASE"}
@@ -10,7 +10,11 @@ var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => va
10
10
 
11
11
  const EVENTS = {
12
12
  BLUR: 'blur',
13
- FOCUS_OUT: 'focusout'};
13
+ FOCUS_OUT: 'focusout',
14
+ SUBMIT: 'submit',
15
+ TRIGGER: 'trigger',
16
+ VALID: 'valid',
17
+ };
14
18
  const VALIDATION_MODE = {
15
19
  onBlur: 'onBlur',
16
20
  onChange: 'onChange',
@@ -27,6 +31,8 @@ const INPUT_VALIDATION_RULES = {
27
31
  required: 'required',
28
32
  validate: 'validate',
29
33
  };
34
+ const FORM_ERROR_TYPE = 'form';
35
+ const ROOT_ERROR_TYPE = 'root';
30
36
 
31
37
  var isDateObject = (value) => value instanceof Date;
32
38
 
@@ -127,8 +133,8 @@ function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
127
133
  if (key !== 'ref') {
128
134
  const val2 = object2[key];
129
135
  if ((isDateObject(val1) && isDateObject(val2)) ||
130
- (isObject(val1) && isObject(val2)) ||
131
- (Array.isArray(val1) && Array.isArray(val2))
136
+ ((isObject(val1) || Array.isArray(val1)) &&
137
+ (isObject(val2) || Array.isArray(val2)))
132
138
  ? !deepEqual(val1, val2, _internal_visited)
133
139
  : !Object.is(val1, val2)) {
134
140
  return false;
@@ -401,6 +407,8 @@ function getFieldValue(_f) {
401
407
  return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f);
402
408
  }
403
409
 
410
+ var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
411
+
404
412
  var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
405
413
  const fields = {};
406
414
  for (const name of fieldsNames) {
@@ -452,9 +460,9 @@ var hasValidation = (options) => options.mount &&
452
460
  options.pattern ||
453
461
  options.validate);
454
462
 
455
- var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
456
-
457
- var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
463
+ var isNameInFieldArray = (names, name) => name
464
+ .split('.')
465
+ .some((part, index, arr) => !isNaN(Number(part)) && names.has(arr.slice(0, index).join('.')));
458
466
 
459
467
  var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
460
468
  (_names.watchAll ||
@@ -563,7 +571,7 @@ var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(re
563
571
 
564
572
  var updateFieldArrayRootError = (errors, error, name) => {
565
573
  const fieldArrayErrors = convertToArrayPayload(get(errors, name));
566
- set(fieldArrayErrors, 'root', error[name]);
574
+ set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
567
575
  set(errors, name, fieldArrayErrors);
568
576
  return errors;
569
577
  };
@@ -811,6 +819,7 @@ function createFormControl(props = {}) {
811
819
  unMount: new Set(),
812
820
  array: new Set(),
813
821
  watch: new Set(),
822
+ registerName: new Set(),
814
823
  };
815
824
  let delayErrorCallback;
816
825
  let timer = 0;
@@ -852,7 +861,11 @@ function createFormControl(props = {}) {
852
861
  _updateIsValidating();
853
862
  }
854
863
  else {
855
- isValid = await executeBuiltInValidation(_fields, true);
864
+ isValid = await executeBuiltInValidation({
865
+ fields: _fields,
866
+ onlyCheckValid: true,
867
+ eventType: EVENTS.VALID,
868
+ });
856
869
  }
857
870
  if (isValid !== _formState.isValid) {
858
871
  _subjects.state.next({
@@ -880,6 +893,11 @@ function createFormControl(props = {}) {
880
893
  });
881
894
  }
882
895
  };
896
+ const _updateDirtyFields = (name) => {
897
+ const fullDirtyFields = getDirtyFields(_defaultValues, _formValues);
898
+ const rootName = getNodeParentName(name);
899
+ set(_formState.dirtyFields, rootName, get(fullDirtyFields, rootName));
900
+ };
883
901
  const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
884
902
  if (args && method && !_options.disabled) {
885
903
  _state.action = true;
@@ -901,7 +919,7 @@ function createFormControl(props = {}) {
901
919
  shouldSetValues && set(_formState.touchedFields, name, touchedFields);
902
920
  }
903
921
  if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
904
- _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
922
+ _updateDirtyFields(name);
905
923
  }
906
924
  _subjects.state.next({
907
925
  name,
@@ -1015,8 +1033,7 @@ function createFormControl(props = {}) {
1015
1033
  };
1016
1034
  const _runSchema = async (name) => {
1017
1035
  _updateIsValidating(name, true);
1018
- const result = await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1019
- return result;
1036
+ return await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1020
1037
  };
1021
1038
  const executeSchemaAndUpdateState = async (names) => {
1022
1039
  const { errors } = await _runSchema(names);
@@ -1034,9 +1051,55 @@ function createFormControl(props = {}) {
1034
1051
  }
1035
1052
  return errors;
1036
1053
  };
1037
- const executeBuiltInValidation = async (fields, shouldOnlyCheckValid, context = {
1054
+ const validateForm = async ({ name, eventType, }) => {
1055
+ if (props.validate) {
1056
+ const result = await props.validate({
1057
+ formValues: _formValues,
1058
+ formState: _formState,
1059
+ name,
1060
+ eventType,
1061
+ });
1062
+ if (isObject(result)) {
1063
+ for (const key in result) {
1064
+ const error = result[key];
1065
+ if (error) {
1066
+ setError(`${FORM_ERROR_TYPE}.${key}`, {
1067
+ message: isString(result.message) ? result.message : '',
1068
+ type: INPUT_VALIDATION_RULES.validate,
1069
+ });
1070
+ }
1071
+ }
1072
+ }
1073
+ else if (isString(result) || !result) {
1074
+ setError(FORM_ERROR_TYPE, {
1075
+ message: result || '',
1076
+ type: INPUT_VALIDATION_RULES.validate,
1077
+ });
1078
+ }
1079
+ else {
1080
+ clearErrors(FORM_ERROR_TYPE);
1081
+ }
1082
+ return result;
1083
+ }
1084
+ return true;
1085
+ };
1086
+ const executeBuiltInValidation = async ({ fields, onlyCheckValid, name, eventType, context = {
1038
1087
  valid: true,
1039
- }) => {
1088
+ runRootValidation: false,
1089
+ }, }) => {
1090
+ if (props.validate) {
1091
+ context.runRootValidation = true;
1092
+ const result = await validateForm({
1093
+ name,
1094
+ eventType,
1095
+ });
1096
+ if (!result) {
1097
+ context.valid = false;
1098
+ if (onlyCheckValid) {
1099
+ return context.valid;
1100
+ }
1101
+ }
1102
+ }
1040
1103
  for (const name in fields) {
1041
1104
  const field = fields[name];
1042
1105
  if (field) {
@@ -1047,25 +1110,34 @@ function createFormControl(props = {}) {
1047
1110
  if (isPromiseFunction && _proxyFormState.validatingFields) {
1048
1111
  _updateIsValidating([_f.name], true);
1049
1112
  }
1050
- const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
1113
+ const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
1051
1114
  if (isPromiseFunction && _proxyFormState.validatingFields) {
1052
1115
  _updateIsValidating([_f.name]);
1053
1116
  }
1054
1117
  if (fieldError[_f.name]) {
1055
1118
  context.valid = false;
1056
- if (shouldOnlyCheckValid || props.shouldUseNativeValidation) {
1119
+ if (onlyCheckValid) {
1057
1120
  break;
1058
1121
  }
1059
1122
  }
1060
- !shouldOnlyCheckValid &&
1123
+ !onlyCheckValid &&
1061
1124
  (get(fieldError, _f.name)
1062
1125
  ? isFieldArrayRoot
1063
1126
  ? updateFieldArrayRootError(_formState.errors, fieldError, _f.name)
1064
1127
  : set(_formState.errors, _f.name, fieldError[_f.name])
1065
1128
  : unset(_formState.errors, _f.name));
1129
+ if (props.shouldUseNativeValidation && fieldError[_f.name]) {
1130
+ break;
1131
+ }
1066
1132
  }
1067
1133
  !isEmptyObject(fieldValue) &&
1068
- (await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context));
1134
+ (await executeBuiltInValidation({
1135
+ context,
1136
+ onlyCheckValid,
1137
+ fields: fieldValue,
1138
+ name: name,
1139
+ eventType,
1140
+ }));
1069
1141
  }
1070
1142
  }
1071
1143
  return context.valid;
@@ -1176,9 +1248,10 @@ function createFormControl(props = {}) {
1176
1248
  _proxySubscribeFormState.isDirty ||
1177
1249
  _proxySubscribeFormState.dirtyFields) &&
1178
1250
  options.shouldDirty) {
1251
+ _updateDirtyFields(name);
1179
1252
  _subjects.state.next({
1180
1253
  name,
1181
- dirtyFields: getDirtyFields(_defaultValues, _formValues),
1254
+ dirtyFields: _formState.dirtyFields,
1182
1255
  isDirty: _getDirty(name, cloneValue),
1183
1256
  });
1184
1257
  }
@@ -1224,6 +1297,7 @@ function createFormControl(props = {}) {
1224
1297
  : getEventValue(event);
1225
1298
  const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
1226
1299
  const shouldSkipValidation = (!hasValidation(field._f) &&
1300
+ !props.validate &&
1227
1301
  !_options.resolver &&
1228
1302
  !get(_formState.errors, name) &&
1229
1303
  !field._f.deps) ||
@@ -1261,6 +1335,12 @@ function createFormControl(props = {}) {
1261
1335
  return (shouldRender &&
1262
1336
  _subjects.state.next({ name, ...(watched ? {} : fieldState) }));
1263
1337
  }
1338
+ if (!_options.resolver && props.validate) {
1339
+ await validateForm({
1340
+ name: name,
1341
+ eventType: event.type,
1342
+ });
1343
+ }
1264
1344
  !isBlurEvent && watched && _subjects.state.next({ ..._formState });
1265
1345
  if (_options.resolver) {
1266
1346
  const { errors } = await _runSchema([name]);
@@ -1285,7 +1365,12 @@ function createFormControl(props = {}) {
1285
1365
  }
1286
1366
  else if (_proxyFormState.isValid ||
1287
1367
  _proxySubscribeFormState.isValid) {
1288
- isValid = await executeBuiltInValidation(_fields, true);
1368
+ isValid = await executeBuiltInValidation({
1369
+ fields: _fields,
1370
+ onlyCheckValid: true,
1371
+ name: name,
1372
+ eventType: event.type,
1373
+ });
1289
1374
  }
1290
1375
  }
1291
1376
  }
@@ -1318,12 +1403,19 @@ function createFormControl(props = {}) {
1318
1403
  else if (name) {
1319
1404
  validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
1320
1405
  const field = get(_fields, fieldName);
1321
- return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
1406
+ return await executeBuiltInValidation({
1407
+ fields: field && field._f ? { [fieldName]: field } : field,
1408
+ eventType: EVENTS.TRIGGER,
1409
+ });
1322
1410
  }))).every(Boolean);
1323
1411
  !(!validationResult && !_formState.isValid) && _setValid();
1324
1412
  }
1325
1413
  else {
1326
- validationResult = isValid = await executeBuiltInValidation(_fields);
1414
+ validationResult = isValid = await executeBuiltInValidation({
1415
+ fields: _fields,
1416
+ name,
1417
+ eventType: EVENTS.TRIGGER,
1418
+ });
1327
1419
  }
1328
1420
  _subjects.state.next({
1329
1421
  ...(!isString(name) ||
@@ -1469,6 +1561,7 @@ function createFormControl(props = {}) {
1469
1561
  const register = (name, options = {}) => {
1470
1562
  let field = get(_fields, name);
1471
1563
  const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
1564
+ const shouldRevalidateRemount = !_names.registerName.has(name) && field && !field._f.mount;
1472
1565
  set(_fields, name, {
1473
1566
  ...(field || {}),
1474
1567
  _f: {
@@ -1479,7 +1572,7 @@ function createFormControl(props = {}) {
1479
1572
  },
1480
1573
  });
1481
1574
  _names.mount.add(name);
1482
- if (field) {
1575
+ if (field && !shouldRevalidateRemount) {
1483
1576
  _setDisabledField({
1484
1577
  disabled: isBoolean(options.disabled)
1485
1578
  ? options.disabled
@@ -1509,7 +1602,9 @@ function createFormControl(props = {}) {
1509
1602
  onBlur: onChange,
1510
1603
  ref: (ref) => {
1511
1604
  if (ref) {
1605
+ _names.registerName.add(name);
1512
1606
  register(name, options);
1607
+ _names.registerName.delete(name);
1513
1608
  field = get(_fields, name);
1514
1609
  const fieldRef = isUndefined(ref.value)
1515
1610
  ? ref.querySelectorAll
@@ -1588,14 +1683,17 @@ function createFormControl(props = {}) {
1588
1683
  fieldValues = cloneObject(values);
1589
1684
  }
1590
1685
  else {
1591
- await executeBuiltInValidation(_fields);
1686
+ await executeBuiltInValidation({
1687
+ fields: _fields,
1688
+ eventType: EVENTS.SUBMIT,
1689
+ });
1592
1690
  }
1593
1691
  if (_names.disabled.size) {
1594
1692
  for (const name of _names.disabled) {
1595
1693
  unset(fieldValues, name);
1596
1694
  }
1597
1695
  }
1598
- unset(_formState.errors, 'root');
1696
+ unset(_formState.errors, ROOT_ERROR_TYPE);
1599
1697
  if (isEmptyObject(_formState.errors)) {
1600
1698
  _subjects.state.next({
1601
1699
  errors: {},
@@ -1719,6 +1817,7 @@ function createFormControl(props = {}) {
1719
1817
  mount: keepStateOptions.keepDirtyValues ? _names.mount : new Set(),
1720
1818
  unMount: new Set(),
1721
1819
  array: new Set(),
1820
+ registerName: new Set(),
1722
1821
  disabled: new Set(),
1723
1822
  watch: new Set(),
1724
1823
  watchAll: false,