react-hook-form 7.37.0 → 7.39.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.
@@ -395,15 +395,10 @@ function useController(props) {
395
395
  },
396
396
  type: EVENTS.BLUR,
397
397
  }), [name, control]),
398
- ref: (elm) => {
398
+ ref: (ref) => {
399
399
  const field = get(control._fields, name);
400
- if (field && elm) {
401
- field._f.ref = {
402
- focus: () => elm.focus(),
403
- select: () => elm.select(),
404
- setCustomValidity: (message) => elm.setCustomValidity(message),
405
- reportValidity: () => elm.reportValidity(),
406
- };
400
+ if (field && ref) {
401
+ field._f.ref = ref;
407
402
  }
408
403
  },
409
404
  },
@@ -632,8 +627,8 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
632
627
  }
633
628
  const inputRef = refs ? refs[0] : ref;
634
629
  const setCustomValidity = (message) => {
635
- if (shouldUseNativeValidation && inputRef.reportValidity) {
636
- inputRef.setCustomValidity(isBoolean(message) ? '' : message || ' ');
630
+ if (shouldUseNativeValidation && isString(message)) {
631
+ inputRef.setCustomValidity(message);
637
632
  inputRef.reportValidity();
638
633
  }
639
634
  };
@@ -694,11 +689,22 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
694
689
  }
695
690
  else {
696
691
  const valueDate = ref.valueAsDate || new Date(inputValue);
697
- if (isString(maxOutput.value)) {
698
- exceedMax = valueDate > new Date(maxOutput.value);
692
+ const convertTimeToDate = (time) => new Date(new Date().toDateString() + ' ' + time);
693
+ const isTime = ref.type == 'time';
694
+ const isWeek = ref.type == 'week';
695
+ if (isString(maxOutput.value) && inputValue) {
696
+ exceedMax = isTime
697
+ ? convertTimeToDate(inputValue) > convertTimeToDate(maxOutput.value)
698
+ : isWeek
699
+ ? inputValue > maxOutput.value
700
+ : valueDate > new Date(maxOutput.value);
699
701
  }
700
- if (isString(minOutput.value)) {
701
- exceedMin = valueDate < new Date(minOutput.value);
702
+ if (isString(minOutput.value) && inputValue) {
703
+ exceedMin = isTime
704
+ ? convertTimeToDate(inputValue) < convertTimeToDate(minOutput.value)
705
+ : isWeek
706
+ ? inputValue < minOutput.value
707
+ : valueDate < new Date(minOutput.value);
702
708
  }
703
709
  }
704
710
  if (exceedMax || exceedMin) {
@@ -931,7 +937,7 @@ var updateAt = (fieldValues, index, value) => {
931
937
  };
932
938
 
933
939
  /**
934
- * A custom hook that exposes convenient methods to perform operations with a list of dynamic inputs that need to be appended, updated, removed etc.
940
+ * A custom hook that exposes convenient methods to perform operations with a list of dynamic inputs that need to be appended, updated, removed etc. • [Demo](https://codesandbox.io/s/react-hook-form-usefieldarray-ssugn) • [Video](https://youtu.be/4MrbfGSFY2A)
935
941
  *
936
942
  * @remarks
937
943
  * [API](https://react-hook-form.com/api/usefieldarray) • [Demo](https://codesandbox.io/s/react-hook-form-usefieldarray-ssugn)
@@ -982,9 +988,11 @@ function useFieldArray(props) {
982
988
  control.register(name, props.rules);
983
989
  const callback = React.useCallback(({ values, name: fieldArrayName, }) => {
984
990
  if (fieldArrayName === _name.current || !fieldArrayName) {
985
- const fieldValues = get(values, _name.current, []);
986
- setFields(fieldValues);
987
- ids.current = fieldValues.map(generateId);
991
+ const fieldValues = get(values, _name.current);
992
+ if (Array.isArray(fieldValues)) {
993
+ setFields(fieldValues);
994
+ ids.current = fieldValues.map(generateId);
995
+ }
988
996
  }
989
997
  }, []);
990
998
  useSubscribe({
@@ -1113,7 +1121,7 @@ function useFieldArray(props) {
1113
1121
  values: control._formValues,
1114
1122
  });
1115
1123
  control._names.focus &&
1116
- focusFieldBy(control._fields, (key) => key.startsWith(control._names.focus));
1124
+ focusFieldBy(control._fields, (key) => !!key && key.startsWith(control._names.focus));
1117
1125
  control._names.focus = '';
1118
1126
  control._proxyFormState.isValid && control._updateValid();
1119
1127
  }, [fields, name, control]);
@@ -1246,7 +1254,9 @@ function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues
1246
1254
  }
1247
1255
  }
1248
1256
  else {
1249
- dirtyFieldsFromValues[key] = !deepEqual(data[key], formValues[key]);
1257
+ deepEqual(data[key], formValues[key])
1258
+ ? delete dirtyFieldsFromValues[key]
1259
+ : (dirtyFieldsFromValues[key] = true);
1250
1260
  }
1251
1261
  }
1252
1262
  }
@@ -1429,13 +1439,13 @@ function createFormControl(props = {}) {
1429
1439
  clearTimeout(timer);
1430
1440
  timer = window.setTimeout(callback, wait);
1431
1441
  };
1432
- const _updateValid = async (shouldSkipRender) => {
1442
+ const _updateValid = async () => {
1433
1443
  let isValid = false;
1434
1444
  if (_proxyFormState.isValid) {
1435
1445
  isValid = _options.resolver
1436
1446
  ? isEmptyObject((await _executeSchema()).errors)
1437
1447
  : await executeBuiltInValidation(_fields, true);
1438
- if (!shouldSkipRender && isValid !== _formState.isValid) {
1448
+ if (isValid !== _formState.isValid) {
1439
1449
  _formState.isValid = isValid;
1440
1450
  _subjects.state.next({
1441
1451
  isValid,
@@ -1529,9 +1539,11 @@ function createFormControl(props = {}) {
1529
1539
  isFieldDirty && shouldRender && _subjects.state.next(output);
1530
1540
  return isFieldDirty ? output : {};
1531
1541
  };
1532
- const shouldRenderByError = async (name, isValid, error, fieldState) => {
1542
+ const shouldRenderByError = (name, isValid, error, fieldState) => {
1533
1543
  const previousFieldError = get(_formState.errors, name);
1534
- const shouldUpdateValid = _proxyFormState.isValid && _formState.isValid !== isValid;
1544
+ const shouldUpdateValid = _proxyFormState.isValid &&
1545
+ isBoolean(isValid) &&
1546
+ _formState.isValid !== isValid;
1535
1547
  if (props.delayError && error) {
1536
1548
  delayErrorCallback = debounce(() => updateErrors(name, error));
1537
1549
  delayErrorCallback(props.delayError);
@@ -1548,7 +1560,7 @@ function createFormControl(props = {}) {
1548
1560
  shouldUpdateValid) {
1549
1561
  const updatedFormState = {
1550
1562
  ...fieldState,
1551
- ...(shouldUpdateValid ? { isValid } : {}),
1563
+ ...(shouldUpdateValid && isBoolean(isValid) ? { isValid } : {}),
1552
1564
  errors: _formState.errors,
1553
1565
  name,
1554
1566
  };
@@ -1762,11 +1774,14 @@ function createFormControl(props = {}) {
1762
1774
  type: event.type,
1763
1775
  });
1764
1776
  if (shouldSkipValidation) {
1777
+ _proxyFormState.isValid && _updateValid();
1765
1778
  return (shouldRender &&
1766
1779
  _subjects.state.next({ name, ...(watched ? {} : fieldState) }));
1767
1780
  }
1768
1781
  !isBlurEvent && watched && _subjects.state.next({});
1769
- validateFields[name] = validateFields[name] ? +1 : 1;
1782
+ validateFields[name] = validateFields[name]
1783
+ ? validateFields[name] + 1
1784
+ : 1;
1770
1785
  _subjects.state.next({
1771
1786
  isValidating: true,
1772
1787
  });
@@ -1780,7 +1795,7 @@ function createFormControl(props = {}) {
1780
1795
  }
1781
1796
  else {
1782
1797
  error = (await validateField(field, get(_formValues, name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
1783
- isValid = await _updateValid(true);
1798
+ _updateValid();
1784
1799
  }
1785
1800
  field._f.deps &&
1786
1801
  trigger(field._f.deps);
@@ -1816,13 +1831,13 @@ function createFormControl(props = {}) {
1816
1831
  (_proxyFormState.isValid && isValid !== _formState.isValid)
1817
1832
  ? {}
1818
1833
  : { name }),
1819
- ...(_options.resolver ? { isValid } : {}),
1834
+ ...(_options.resolver || !name ? { isValid } : {}),
1820
1835
  errors: _formState.errors,
1821
1836
  isValidating: false,
1822
1837
  });
1823
1838
  options.shouldFocus &&
1824
1839
  !validationResult &&
1825
- focusFieldBy(_fields, (key) => get(_formState.errors, key), name ? fieldNames : _names.mount);
1840
+ focusFieldBy(_fields, (key) => key && get(_formState.errors, key), name ? fieldNames : _names.mount);
1826
1841
  return validationResult;
1827
1842
  };
1828
1843
  const getValues = (fieldNames) => {
@@ -1973,6 +1988,8 @@ function createFormControl(props = {}) {
1973
1988
  },
1974
1989
  };
1975
1990
  };
1991
+ const _focusError = () => _options.shouldFocusError &&
1992
+ focusFieldBy(_fields, (key) => key && get(_formState.errors, key), _names.mount);
1976
1993
  const handleSubmit = (onValid, onInvalid) => async (e) => {
1977
1994
  if (e) {
1978
1995
  e.preventDefault && e.preventDefault();
@@ -2003,8 +2020,7 @@ function createFormControl(props = {}) {
2003
2020
  if (onInvalid) {
2004
2021
  await onInvalid({ ..._formState.errors }, e);
2005
2022
  }
2006
- _options.shouldFocusError &&
2007
- focusFieldBy(_fields, (key) => get(_formState.errors, key), _names.mount);
2023
+ _focusError();
2008
2024
  }
2009
2025
  }
2010
2026
  catch (err) {
@@ -2072,13 +2088,13 @@ function createFormControl(props = {}) {
2072
2088
  const fieldReference = Array.isArray(field._f.refs)
2073
2089
  ? field._f.refs[0]
2074
2090
  : field._f.ref;
2075
- try {
2076
- if (isHTMLElement(fieldReference)) {
2077
- fieldReference.closest('form').reset();
2091
+ if (isHTMLElement(fieldReference)) {
2092
+ const form = fieldReference.closest('form');
2093
+ if (form) {
2094
+ form.reset();
2078
2095
  break;
2079
2096
  }
2080
2097
  }
2081
- catch (_a) { }
2082
2098
  }
2083
2099
  }
2084
2100
  }
@@ -2153,6 +2169,7 @@ function createFormControl(props = {}) {
2153
2169
  unregister,
2154
2170
  getFieldState,
2155
2171
  _executeSchema,
2172
+ _focusError,
2156
2173
  _getWatch,
2157
2174
  _getDirty,
2158
2175
  _updateValid,
@@ -2289,6 +2306,9 @@ function useForm(props = {}) {
2289
2306
  }
2290
2307
  control._removeUnmounted();
2291
2308
  });
2309
+ React.useEffect(() => {
2310
+ formState.submitCount && control._focusError();
2311
+ }, [control, formState.submitCount]);
2292
2312
  _formControl.current.formState = getProxyFormState(formState, control);
2293
2313
  return _formControl.current;
2294
2314
  }