react-hook-form 7.52.2 → 7.53.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.
@@ -551,6 +551,22 @@ function useController(props) {
551
551
  */
552
552
  const Controller = (props) => props.render(useController(props));
553
553
 
554
+ const flatten = (obj) => {
555
+ const output = {};
556
+ for (const key of Object.keys(obj)) {
557
+ if (isObjectType(obj[key])) {
558
+ const nested = flatten(obj[key]);
559
+ for (const nestedKey of Object.keys(nested)) {
560
+ output[`${key}.${nestedKey}`] = nested[nestedKey];
561
+ }
562
+ }
563
+ else {
564
+ output[key] = obj[key];
565
+ }
566
+ }
567
+ return output;
568
+ };
569
+
554
570
  const POST_REQUEST = 'post';
555
571
  /**
556
572
  * Form component to manage submission.
@@ -588,8 +604,9 @@ function Form(props) {
588
604
  formDataJson = JSON.stringify(data);
589
605
  }
590
606
  catch (_a) { }
591
- for (const name of control._names.mount) {
592
- formData.append(name, get(data, name));
607
+ const flattenFormValues = flatten(control._formValues);
608
+ for (const key in flattenFormValues) {
609
+ formData.append(key, flattenFormValues[key]);
593
610
  }
594
611
  if (onSubmit) {
595
612
  await onSubmit({
@@ -693,20 +710,25 @@ const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
693
710
  const { _f, ...currentField } = field;
694
711
  if (_f) {
695
712
  if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) {
696
- break;
713
+ return true;
697
714
  }
698
715
  else if (_f.ref && action(_f.ref, _f.name) && !abortEarly) {
699
- break;
716
+ return true;
700
717
  }
701
718
  else {
702
- iterateFieldsByAction(currentField, action);
719
+ if (iterateFieldsByAction(currentField, action)) {
720
+ break;
721
+ }
703
722
  }
704
723
  }
705
724
  else if (isObject(currentField)) {
706
- iterateFieldsByAction(currentField, action);
725
+ if (iterateFieldsByAction(currentField, action)) {
726
+ break;
727
+ }
707
728
  }
708
729
  }
709
730
  }
731
+ return;
710
732
  };
711
733
 
712
734
  var updateFieldArrayRootError = (errors, error, name) => {
@@ -1466,6 +1488,13 @@ var getRuleValue = (rule) => isUndefined(rule)
1466
1488
  : rule.value
1467
1489
  : rule;
1468
1490
 
1491
+ const ASYNC_FUNCTION = 'AsyncFunction';
1492
+ var hasPromiseValidation = (fieldReference) => (!fieldReference || !fieldReference.validate) &&
1493
+ !!((isFunction(fieldReference.validate) &&
1494
+ fieldReference.validate.constructor.name === ASYNC_FUNCTION) ||
1495
+ (isObject(fieldReference.validate) &&
1496
+ Object.values(fieldReference.validate).find((validateFunction) => validateFunction.constructor.name === ASYNC_FUNCTION)));
1497
+
1469
1498
  var hasValidation = (options) => options.mount &&
1470
1499
  (options.required ||
1471
1500
  options.min ||
@@ -1589,7 +1618,7 @@ function createFormControl(props = {}) {
1589
1618
  timer = setTimeout(callback, wait);
1590
1619
  };
1591
1620
  const _updateValid = async (shouldUpdateValid) => {
1592
- if (_proxyFormState.isValid || shouldUpdateValid) {
1621
+ if (!props.disabled && (_proxyFormState.isValid || shouldUpdateValid)) {
1593
1622
  const isValid = _options.resolver
1594
1623
  ? isEmptyObject((await _executeSchema()).errors)
1595
1624
  : await executeBuiltInValidation(_fields, true);
@@ -1601,7 +1630,8 @@ function createFormControl(props = {}) {
1601
1630
  }
1602
1631
  };
1603
1632
  const _updateIsValidating = (names, isValidating) => {
1604
- if (_proxyFormState.isValidating || _proxyFormState.validatingFields) {
1633
+ if (!props.disabled &&
1634
+ (_proxyFormState.isValidating || _proxyFormState.validatingFields)) {
1605
1635
  (names || Array.from(_names.mount)).forEach((name) => {
1606
1636
  if (name) {
1607
1637
  isValidating
@@ -1616,7 +1646,7 @@ function createFormControl(props = {}) {
1616
1646
  }
1617
1647
  };
1618
1648
  const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
1619
- if (args && method) {
1649
+ if (args && method && !props.disabled) {
1620
1650
  _state.action = true;
1621
1651
  if (shouldUpdateFieldsAndState && Array.isArray(get(_fields, name))) {
1622
1652
  const fieldValues = method(get(_fields, name), args.argA, args.argB);
@@ -1680,38 +1710,40 @@ function createFormControl(props = {}) {
1680
1710
  const output = {
1681
1711
  name,
1682
1712
  };
1683
- const disabledField = !!(get(_fields, name) &&
1684
- get(_fields, name)._f &&
1685
- get(_fields, name)._f.disabled);
1686
- if (!isBlurEvent || shouldDirty) {
1687
- if (_proxyFormState.isDirty) {
1688
- isPreviousDirty = _formState.isDirty;
1689
- _formState.isDirty = output.isDirty = _getDirty();
1690
- shouldUpdateField = isPreviousDirty !== output.isDirty;
1691
- }
1692
- const isCurrentFieldPristine = disabledField || deepEqual(get(_defaultValues, name), fieldValue);
1693
- isPreviousDirty = !!(!disabledField && get(_formState.dirtyFields, name));
1694
- isCurrentFieldPristine || disabledField
1695
- ? unset(_formState.dirtyFields, name)
1696
- : set(_formState.dirtyFields, name, true);
1697
- output.dirtyFields = _formState.dirtyFields;
1698
- shouldUpdateField =
1699
- shouldUpdateField ||
1700
- (_proxyFormState.dirtyFields &&
1701
- isPreviousDirty !== !isCurrentFieldPristine);
1702
- }
1703
- if (isBlurEvent) {
1704
- const isPreviousFieldTouched = get(_formState.touchedFields, name);
1705
- if (!isPreviousFieldTouched) {
1706
- set(_formState.touchedFields, name, isBlurEvent);
1707
- output.touchedFields = _formState.touchedFields;
1713
+ if (!props.disabled) {
1714
+ const disabledField = !!(get(_fields, name) &&
1715
+ get(_fields, name)._f &&
1716
+ get(_fields, name)._f.disabled);
1717
+ if (!isBlurEvent || shouldDirty) {
1718
+ if (_proxyFormState.isDirty) {
1719
+ isPreviousDirty = _formState.isDirty;
1720
+ _formState.isDirty = output.isDirty = _getDirty();
1721
+ shouldUpdateField = isPreviousDirty !== output.isDirty;
1722
+ }
1723
+ const isCurrentFieldPristine = disabledField || deepEqual(get(_defaultValues, name), fieldValue);
1724
+ isPreviousDirty = !!(!disabledField && get(_formState.dirtyFields, name));
1725
+ isCurrentFieldPristine || disabledField
1726
+ ? unset(_formState.dirtyFields, name)
1727
+ : set(_formState.dirtyFields, name, true);
1728
+ output.dirtyFields = _formState.dirtyFields;
1708
1729
  shouldUpdateField =
1709
1730
  shouldUpdateField ||
1710
- (_proxyFormState.touchedFields &&
1711
- isPreviousFieldTouched !== isBlurEvent);
1731
+ (_proxyFormState.dirtyFields &&
1732
+ isPreviousDirty !== !isCurrentFieldPristine);
1712
1733
  }
1734
+ if (isBlurEvent) {
1735
+ const isPreviousFieldTouched = get(_formState.touchedFields, name);
1736
+ if (!isPreviousFieldTouched) {
1737
+ set(_formState.touchedFields, name, isBlurEvent);
1738
+ output.touchedFields = _formState.touchedFields;
1739
+ shouldUpdateField =
1740
+ shouldUpdateField ||
1741
+ (_proxyFormState.touchedFields &&
1742
+ isPreviousFieldTouched !== isBlurEvent);
1743
+ }
1744
+ }
1745
+ shouldUpdateField && shouldRender && _subjects.state.next(output);
1713
1746
  }
1714
- shouldUpdateField && shouldRender && _subjects.state.next(output);
1715
1747
  return shouldUpdateField ? output : {};
1716
1748
  };
1717
1749
  const shouldRenderByError = (name, isValid, error, fieldState) => {
@@ -1776,9 +1808,14 @@ function createFormControl(props = {}) {
1776
1808
  const { _f, ...fieldValue } = field;
1777
1809
  if (_f) {
1778
1810
  const isFieldArrayRoot = _names.array.has(_f.name);
1779
- _updateIsValidating([name], true);
1811
+ const isPromiseFunction = field._f && hasPromiseValidation(field._f);
1812
+ if (isPromiseFunction && _proxyFormState.validatingFields) {
1813
+ _updateIsValidating([name], true);
1814
+ }
1780
1815
  const fieldError = await validateField(field, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
1781
- _updateIsValidating([name]);
1816
+ if (isPromiseFunction && _proxyFormState.validatingFields) {
1817
+ _updateIsValidating([name]);
1818
+ }
1782
1819
  if (fieldError[_f.name]) {
1783
1820
  context.valid = false;
1784
1821
  if (shouldOnlyCheckValid) {
@@ -1809,8 +1846,9 @@ function createFormControl(props = {}) {
1809
1846
  }
1810
1847
  _names.unMount = new Set();
1811
1848
  };
1812
- const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
1813
- !deepEqual(getValues(), _defaultValues));
1849
+ const _getDirty = (name, data) => !props.disabled &&
1850
+ (name && data && set(_formValues, name, data),
1851
+ !deepEqual(getValues(), _defaultValues));
1814
1852
  const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
1815
1853
  ...(_state.mount
1816
1854
  ? _formValues
@@ -1874,7 +1912,7 @@ function createFormControl(props = {}) {
1874
1912
  const fieldName = `${name}.${fieldKey}`;
1875
1913
  const field = get(_fields, fieldName);
1876
1914
  (_names.array.has(name) ||
1877
- !isPrimitive(fieldValue) ||
1915
+ isObject(fieldValue) ||
1878
1916
  (field && !field._f)) &&
1879
1917
  !isDateObject(fieldValue)
1880
1918
  ? setValues(fieldName, fieldValue, options)
@@ -1921,7 +1959,8 @@ function createFormControl(props = {}) {
1921
1959
  const _updateIsFieldValueUpdated = (fieldValue) => {
1922
1960
  isFieldValueUpdated =
1923
1961
  Number.isNaN(fieldValue) ||
1924
- fieldValue === get(_formValues, name, fieldValue);
1962
+ (isDateObject(fieldValue) && isNaN(fieldValue.getTime())) ||
1963
+ deepEqual(fieldValue, get(_formValues, name, fieldValue));
1925
1964
  };
1926
1965
  if (field) {
1927
1966
  let error;
@@ -1951,7 +1990,16 @@ function createFormControl(props = {}) {
1951
1990
  values: { ..._formValues },
1952
1991
  });
1953
1992
  if (shouldSkipValidation) {
1954
- _proxyFormState.isValid && _updateValid();
1993
+ if (_proxyFormState.isValid) {
1994
+ if (props.mode === 'onBlur') {
1995
+ if (isBlurEvent) {
1996
+ _updateValid();
1997
+ }
1998
+ }
1999
+ else {
2000
+ _updateValid();
2001
+ }
2002
+ }
1955
2003
  return (shouldRender &&
1956
2004
  _subjects.state.next({ name, ...(watched ? {} : fieldState) }));
1957
2005
  }
@@ -2114,7 +2162,7 @@ function createFormControl(props = {}) {
2114
2162
  };
2115
2163
  const register = (name, options = {}) => {
2116
2164
  let field = get(_fields, name);
2117
- const disabledIsDefined = isBoolean(options.disabled);
2165
+ const disabledIsDefined = isBoolean(options.disabled) || isBoolean(props.disabled);
2118
2166
  set(_fields, name, {
2119
2167
  ...(field || {}),
2120
2168
  _f: {
@@ -2128,7 +2176,9 @@ function createFormControl(props = {}) {
2128
2176
  if (field) {
2129
2177
  _updateDisabledField({
2130
2178
  field,
2131
- disabled: options.disabled,
2179
+ disabled: isBoolean(options.disabled)
2180
+ ? options.disabled
2181
+ : props.disabled,
2132
2182
  name,
2133
2183
  value: options.value,
2134
2184
  });
@@ -2137,7 +2187,9 @@ function createFormControl(props = {}) {
2137
2187
  updateValidAndValue(name, true, options.value);
2138
2188
  }
2139
2189
  return {
2140
- ...(disabledIsDefined ? { disabled: options.disabled } : {}),
2190
+ ...(disabledIsDefined
2191
+ ? { disabled: options.disabled || props.disabled }
2192
+ : {}),
2141
2193
  ...(_options.progressive
2142
2194
  ? {
2143
2195
  required: !!options.required,
@@ -2297,7 +2349,11 @@ function createFormControl(props = {}) {
2297
2349
  }
2298
2350
  if (!keepStateOptions.keepValues) {
2299
2351
  if (keepStateOptions.keepDirtyValues) {
2300
- for (const fieldName of _names.mount) {
2352
+ const fieldsToCheck = new Set([
2353
+ ..._names.mount,
2354
+ ...Object.keys(getDirtyFields(_defaultValues, _formValues)),
2355
+ ]);
2356
+ for (const fieldName of Array.from(fieldsToCheck)) {
2301
2357
  get(_formState.dirtyFields, fieldName)
2302
2358
  ? set(values, fieldName, get(_formValues, fieldName))
2303
2359
  : setValue(fieldName, get(values, fieldName));
@@ -2595,6 +2651,11 @@ function useForm(props = {}) {
2595
2651
  values: control._getWatch(),
2596
2652
  });
2597
2653
  }, [props.shouldUnregister, control]);
2654
+ React.useEffect(() => {
2655
+ if (_formControl.current) {
2656
+ _formControl.current.watch = _formControl.current.watch.bind({});
2657
+ }
2658
+ }, [formState]);
2598
2659
  _formControl.current.formState = getProxyFormState(formState, control);
2599
2660
  return _formControl.current;
2600
2661
  }