react-hook-form 7.0.4 → 7.0.7

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.
Files changed (90) hide show
  1. package/CHANGELOG.md +8 -3
  2. package/dist/index.cjs.js +2 -0
  3. package/dist/index.cjs.js.map +1 -0
  4. package/dist/index.esm.js +47 -49
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/index.umd.js +2 -0
  7. package/dist/index.umd.js.map +1 -0
  8. package/dist/types/form.d.ts +80 -2
  9. package/package.json +10 -11
  10. package/dist/__tests__/logic/appendErrors.test.d.ts +0 -1
  11. package/dist/__tests__/logic/focusFieldBy.test.d.ts +0 -1
  12. package/dist/__tests__/logic/generateId.test.d.ts +0 -1
  13. package/dist/__tests__/logic/getCheckboxValue.test.d.ts +0 -1
  14. package/dist/__tests__/logic/getControllerValue.test.d.ts +0 -1
  15. package/dist/__tests__/logic/getFieldValue.test.d.ts +0 -1
  16. package/dist/__tests__/logic/getFields.test.d.ts +0 -1
  17. package/dist/__tests__/logic/getFieldsValues.test.d.ts +0 -1
  18. package/dist/__tests__/logic/getMultipleSelectValue.test.d.ts +0 -1
  19. package/dist/__tests__/logic/getNodeParentName.test.d.ts +0 -1
  20. package/dist/__tests__/logic/getRadioValue.test.d.ts +0 -1
  21. package/dist/__tests__/logic/getValidateError.test.d.ts +0 -1
  22. package/dist/__tests__/logic/getValueAndMessage.test.d.ts +0 -1
  23. package/dist/__tests__/logic/isErrorStateChanged.test.d.ts +0 -1
  24. package/dist/__tests__/logic/isNameInFieldArray.test.d.ts +0 -1
  25. package/dist/__tests__/logic/setFieldArrayDirtyFields.test.d.ts +0 -1
  26. package/dist/__tests__/logic/skipValidation.test.d.ts +0 -1
  27. package/dist/__tests__/logic/validateField.test.d.ts +0 -1
  28. package/dist/__tests__/useFieldArray/append.test.d.ts +0 -1
  29. package/dist/__tests__/useFieldArray/focus.test.d.ts +0 -1
  30. package/dist/__tests__/useFieldArray/insert.test.d.ts +0 -1
  31. package/dist/__tests__/useFieldArray/move.test.d.ts +0 -1
  32. package/dist/__tests__/useFieldArray/prepend.test.d.ts +0 -1
  33. package/dist/__tests__/useFieldArray/remove.test.d.ts +0 -1
  34. package/dist/__tests__/useFieldArray/swap.test.d.ts +0 -1
  35. package/dist/__tests__/useForm/clearErrors.test.d.ts +0 -1
  36. package/dist/__tests__/useForm/formState.test.d.ts +0 -1
  37. package/dist/__tests__/useForm/getValues.test.d.ts +0 -1
  38. package/dist/__tests__/useForm/handleSubmit.test.d.ts +0 -1
  39. package/dist/__tests__/useForm/register.test.d.ts +0 -1
  40. package/dist/__tests__/useForm/reset.test.d.ts +0 -1
  41. package/dist/__tests__/useForm/setError.test.d.ts +0 -1
  42. package/dist/__tests__/useForm/setValue.test.d.ts +0 -1
  43. package/dist/__tests__/useForm/trigger.test.d.ts +0 -1
  44. package/dist/__tests__/useForm/unregister.test.d.ts +0 -1
  45. package/dist/__tests__/useForm/watch.test.d.ts +0 -1
  46. package/dist/__tests__/utils/Subject.test.d.ts +0 -1
  47. package/dist/__tests__/utils/compact.test.d.ts +0 -1
  48. package/dist/__tests__/utils/deepEqual.test.d.ts +0 -1
  49. package/dist/__tests__/utils/deepMerge.test.d.ts +0 -1
  50. package/dist/__tests__/utils/fillBooleanArray.test.d.ts +0 -1
  51. package/dist/__tests__/utils/fillEmptyArray.test.d.ts +0 -1
  52. package/dist/__tests__/utils/get.test.d.ts +0 -1
  53. package/dist/__tests__/utils/insert.test.d.ts +0 -1
  54. package/dist/__tests__/utils/isBoolean.test.d.ts +0 -1
  55. package/dist/__tests__/utils/isCheckBoxInput.test.d.ts +0 -1
  56. package/dist/__tests__/utils/isEmptyObject.test.d.ts +0 -1
  57. package/dist/__tests__/utils/isFileInput.test.d.ts +0 -1
  58. package/dist/__tests__/utils/isFunction.test.d.ts +0 -1
  59. package/dist/__tests__/utils/isHTMLElement.test.d.ts +0 -1
  60. package/dist/__tests__/utils/isKey.test.d.ts +0 -1
  61. package/dist/__tests__/utils/isMessage.test.d.ts +0 -1
  62. package/dist/__tests__/utils/isMultipleSelect.test.d.ts +0 -1
  63. package/dist/__tests__/utils/isNullOrUndefined.test.d.ts +0 -1
  64. package/dist/__tests__/utils/isObject.test.d.ts +0 -1
  65. package/dist/__tests__/utils/isPrimitive.test.d.ts +0 -1
  66. package/dist/__tests__/utils/isRadioInput.test.d.ts +0 -1
  67. package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts +0 -1
  68. package/dist/__tests__/utils/isRegex.test.d.ts +0 -1
  69. package/dist/__tests__/utils/isSelectInput.test.d.ts +0 -1
  70. package/dist/__tests__/utils/isString.test.d.ts +0 -1
  71. package/dist/__tests__/utils/isUndefined.test.d.ts +0 -1
  72. package/dist/__tests__/utils/move.test.d.ts +0 -1
  73. package/dist/__tests__/utils/omit.test.d.ts +0 -1
  74. package/dist/__tests__/utils/prepend.test.d.ts +0 -1
  75. package/dist/__tests__/utils/remove.test.d.ts +0 -1
  76. package/dist/__tests__/utils/set.test.d.ts +0 -1
  77. package/dist/__tests__/utils/stringToPath.test.d.ts +0 -1
  78. package/dist/__tests__/utils/swap.test.d.ts +0 -1
  79. package/dist/__tests__/utils/unset.test.d.ts +0 -1
  80. package/dist/__tests__/utils/validationModeChecker.test.d.ts +0 -1
  81. package/dist/index.cjs.development.js +0 -1676
  82. package/dist/index.cjs.development.js.map +0 -1
  83. package/dist/index.cjs.production.min.js +0 -2
  84. package/dist/index.cjs.production.min.js.map +0 -1
  85. package/dist/index.js +0 -8
  86. package/dist/index.umd.development.js +0 -1680
  87. package/dist/index.umd.development.js.map +0 -1
  88. package/dist/index.umd.production.min.js +0 -2
  89. package/dist/index.umd.production.min.js.map +0 -1
  90. package/dist/logic/isErrorStateChanged.d.ts +0 -9
package/dist/index.esm.js CHANGED
@@ -725,14 +725,6 @@ function getFieldValue(field) {
725
725
  }
726
726
  }
727
727
 
728
- var isErrorStateChanged = ({ errors, name, error, validFields, fieldsWithValidation, }) => {
729
- const isValid = isUndefined(error);
730
- const previousError = get(errors, name);
731
- return ((isValid && !!previousError) ||
732
- (!isValid && !deepEqual(previousError, error, true)) ||
733
- (isValid && get(fieldsWithValidation, name) && !get(validFields, name)));
734
- };
735
-
736
728
  var skipValidation = ({ isOnBlur, isOnChange, isOnTouch, isTouched, isReValidateOnBlur, isReValidateOnChange, isBlurEvent, isSubmitted, isOnAll, }) => {
737
729
  if (isOnAll) {
738
730
  return false;
@@ -779,7 +771,7 @@ var validateField = async ({ _f: { ref, refs, required, maxLength, minLength, mi
779
771
  const isRadio = isRadioInput(ref);
780
772
  const isCheckBox = isCheckBoxInput(ref);
781
773
  const isRadioOrCheckbox = isRadio || isCheckBox;
782
- const isEmpty = (valueAsNumber && ref.value === '') ||
774
+ const isEmpty = ((valueAsNumber || isFileInput(ref)) && !ref.value) ||
783
775
  inputValue === '' ||
784
776
  (Array.isArray(inputValue) && !inputValue.length);
785
777
  const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
@@ -850,7 +842,7 @@ var validateField = async ({ _f: { ref, refs, required, maxLength, minLength, mi
850
842
  }
851
843
  if (isString(inputValue) && pattern && !isEmpty) {
852
844
  const { value: patternValue, message } = getValueAndMessage(pattern);
853
- if (isRegex(patternValue) && !patternValue.test(inputValue)) {
845
+ if (isRegex(patternValue) && !inputValue.match(patternValue)) {
854
846
  error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.pattern, message,
855
847
  ref }, appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message));
856
848
  if (!validateAllFieldCriteria) {
@@ -1001,15 +993,13 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1001
993
  deepEqual(validFieldsRef.current, fieldsWithValidationRef.current) &&
1002
994
  isEmptyObject(formStateRef.current.errors));
1003
995
  const shouldRenderBaseOnError = React.useCallback((name, error, shouldRender = false, state = {}, isValid, isWatched) => {
1004
- let shouldReRender = shouldRender ||
1005
- isErrorStateChanged({
1006
- errors: formStateRef.current.errors,
1007
- error,
1008
- name,
1009
- validFields: validFieldsRef.current,
1010
- fieldsWithValidation: fieldsWithValidationRef.current,
1011
- });
1012
996
  const previousError = get(formStateRef.current.errors, name);
997
+ let shouldReRender = shouldRender ||
998
+ !deepEqual(previousError, error, true) ||
999
+ (readFormStateRef.current.isValid &&
1000
+ isUndefined(error) &&
1001
+ get(fieldsWithValidationRef.current, name) &&
1002
+ !get(validFieldsRef.current, name));
1013
1003
  if (error) {
1014
1004
  unset(validFieldsRef.current, name);
1015
1005
  shouldReRender =
@@ -1182,18 +1172,33 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1182
1172
  const isFieldWatched = (name) => isWatchAllRef.current ||
1183
1173
  watchFieldsRef.current.has(name) ||
1184
1174
  watchFieldsRef.current.has((name.match(/\w+/) || [])[0]);
1185
- const updateValueAndGetDefault = (name) => {
1175
+ const updateValidAndValue = (name, options, isWithinRefCallback) => {
1186
1176
  let defaultValue;
1187
1177
  const field = get(fieldsRef.current, name);
1178
+ const useFormDefaultValue = get(defaultValuesRef.current, name);
1188
1179
  if (field &&
1189
1180
  (!isEmptyObject(defaultValuesRef.current) || !isUndefined(field._f.value))) {
1190
1181
  defaultValue = isUndefined(field._f.value)
1191
- ? get(defaultValuesRef.current, name)
1182
+ ? useFormDefaultValue
1192
1183
  : field._f.value;
1193
- if (!isUndefined(defaultValue)) {
1184
+ if (!isNullOrUndefined(defaultValue)) {
1194
1185
  setFieldValue(name, defaultValue);
1195
1186
  }
1196
1187
  }
1188
+ if ((useFormDefaultValue || (!useFormDefaultValue && isWithinRefCallback)) &&
1189
+ options &&
1190
+ !validationMode.isOnSubmit &&
1191
+ field &&
1192
+ readFormStateRef.current.isValid) {
1193
+ validateField(field, isValidateAllFieldCriteria).then((error) => {
1194
+ isEmptyObject(error)
1195
+ ? set(validFieldsRef.current, name, true)
1196
+ : unset(validFieldsRef.current, name);
1197
+ formStateRef.current.isValid &&
1198
+ !isEmptyObject(error) &&
1199
+ setFormState(Object.assign(Object.assign({}, formStateRef.current), { isValid: getIsValid() }));
1200
+ });
1201
+ }
1197
1202
  return defaultValue;
1198
1203
  };
1199
1204
  const setValue = (name, value, options = {}) => {
@@ -1231,7 +1236,8 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1231
1236
  let isValid;
1232
1237
  const field = get(fieldsRef.current, name);
1233
1238
  if (field) {
1234
- const inputValue = inputType ? getFieldValue(field) : value;
1239
+ let inputValue = inputType ? getFieldValue(field) : undefined;
1240
+ inputValue = isUndefined(inputValue) ? value : inputValue;
1235
1241
  const isBlurEvent = type === EVENTS.BLUR;
1236
1242
  const { isOnBlur: isReValidateOnBlur, isOnChange: isReValidateOnChange, } = getValidationModes(reValidateMode);
1237
1243
  const shouldSkipValidation = skipValidation(Object.assign({ isBlurEvent, isTouched: !!get(formStateRef.current.touchedFields, name), isSubmitted: formStateRef.current.isSubmitted, isReValidateOnBlur,
@@ -1243,7 +1249,8 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1243
1249
  const state = updateAndGetDirtyState(name, field._f.value, false);
1244
1250
  if (isBlurEvent && !get(formStateRef.current.touchedFields, name)) {
1245
1251
  set(formStateRef.current.touchedFields, name, true);
1246
- state.touchedFields = formStateRef.current.touchedFields;
1252
+ readFormStateRef.current.touchedFields &&
1253
+ (state.touchedFields = formStateRef.current.touchedFields);
1247
1254
  }
1248
1255
  let shouldRender = !isEmptyObject(state) || isWatched;
1249
1256
  if (shouldSkipValidation) {
@@ -1393,12 +1400,11 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1393
1400
  let field = get(fieldsRef.current, name);
1394
1401
  if (field) {
1395
1402
  const isRadioOrCheckbox = isRadioOrCheckboxFunction(ref);
1396
- if ((isRadioOrCheckbox
1397
- ? Array.isArray(field._f.refs) &&
1398
- compact(field._f.refs).find((option) => ref.value === option.value && option === ref)
1399
- : ref === field._f.ref) ||
1400
- !field ||
1401
- (isWeb && isHTMLElement(field._f.ref) && !isHTMLElement(ref))) {
1403
+ if (ref === field._f.ref ||
1404
+ (isWeb && isHTMLElement(field._f.ref) && !isHTMLElement(ref)) ||
1405
+ (isRadioOrCheckbox &&
1406
+ Array.isArray(field._f.refs) &&
1407
+ compact(field._f.refs).find((option) => option === ref))) {
1402
1408
  return;
1403
1409
  }
1404
1410
  field = {
@@ -1409,26 +1415,12 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1409
1415
  ], ref: { type: ref.type, name } }) : Object.assign(Object.assign({}, field._f), { ref }),
1410
1416
  };
1411
1417
  set(fieldsRef.current, name, field);
1412
- const defaultValue = updateValueAndGetDefault(name);
1418
+ const defaultValue = updateValidAndValue(name, options, true);
1413
1419
  if (isRadioOrCheckbox && Array.isArray(defaultValue)
1414
1420
  ? !deepEqual(get(fieldsRef.current, name)._f.value, defaultValue)
1415
1421
  : isUndefined(get(fieldsRef.current, name)._f.value)) {
1416
1422
  get(fieldsRef.current, name)._f.value = getFieldValue(get(fieldsRef.current, name));
1417
1423
  }
1418
- if (options) {
1419
- if (!validationMode.isOnSubmit &&
1420
- field &&
1421
- readFormStateRef.current.isValid) {
1422
- validateField(field, isValidateAllFieldCriteria).then((error) => {
1423
- isEmptyObject(error)
1424
- ? set(validFieldsRef.current, name, true)
1425
- : unset(validFieldsRef.current, name);
1426
- formStateRef.current.isValid &&
1427
- !isEmptyObject(error) &&
1428
- setFormState(Object.assign(Object.assign({}, formStateRef.current), { isValid: getIsValid() }));
1429
- });
1430
- }
1431
- }
1432
1424
  }
1433
1425
  };
1434
1426
  const register = React.useCallback((name, options) => {
@@ -1440,7 +1432,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1440
1432
  });
1441
1433
  options && set(fieldsWithValidationRef.current, name, true);
1442
1434
  fieldsNamesRef.current.add(name);
1443
- isInitialRegister && updateValueAndGetDefault(name);
1435
+ isInitialRegister && updateValidAndValue(name, options);
1444
1436
  return isWindowUndefined
1445
1437
  ? { name: name }
1446
1438
  : {
@@ -1615,6 +1607,8 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1615
1607
  function useWatch(props) {
1616
1608
  const { control, name, defaultValue } = props || {};
1617
1609
  const methods = useFormContext();
1610
+ const nameRef = React.useRef(name);
1611
+ nameRef.current = name;
1618
1612
  const { watchInternal, watchSubjectRef } = control || methods.control;
1619
1613
  const [value, updateValue] = React.useState(isUndefined(defaultValue)
1620
1614
  ? watchInternal(name)
@@ -1622,14 +1616,18 @@ function useWatch(props) {
1622
1616
  React.useEffect(() => {
1623
1617
  watchInternal(name);
1624
1618
  const watchSubscription = watchSubjectRef.current.subscribe({
1625
- next: ({ name: inputName, value }) => (!name ||
1619
+ next: ({ name: inputName, value }) => (!nameRef.current ||
1626
1620
  !inputName ||
1627
- (Array.isArray(name) ? name : [name]).some((fieldName) => inputName &&
1621
+ (Array.isArray(nameRef.current)
1622
+ ? nameRef.current
1623
+ : [nameRef.current]).some((fieldName) => inputName &&
1628
1624
  fieldName &&
1629
1625
  inputName.startsWith(fieldName))) &&
1630
- updateValue(isString(inputName) && name === inputName && !isUndefined(value)
1626
+ updateValue(isString(inputName) &&
1627
+ nameRef.current === inputName &&
1628
+ !isUndefined(value)
1631
1629
  ? value
1632
- : watchInternal(name, defaultValue)),
1630
+ : watchInternal(nameRef.current, defaultValue)),
1633
1631
  });
1634
1632
  return () => watchSubscription.unsubscribe();
1635
1633
  }, []);