react-hook-form 7.39.4 → 7.39.6

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 (50) hide show
  1. package/dist/__typetest__/__fixtures__/pathString.d.ts +2 -2
  2. package/dist/__typetest__/__fixtures__/pathString.d.ts.map +1 -1
  3. package/dist/__typetest__/__fixtures__/traversable.d.ts +3 -3
  4. package/dist/__typetest__/__fixtures__/traversable.d.ts.map +1 -1
  5. package/dist/__typetest__/__fixtures__/tuple.d.ts +2 -2
  6. package/dist/__typetest__/__fixtures__/tuple.d.ts.map +1 -1
  7. package/dist/index.cjs.js +1 -1
  8. package/dist/index.cjs.js.map +1 -1
  9. package/dist/index.esm.mjs +69 -65
  10. package/dist/index.esm.mjs.map +1 -1
  11. package/dist/index.umd.js +1 -1
  12. package/dist/index.umd.js.map +1 -1
  13. package/dist/logic/createFormControl.d.ts.map +1 -1
  14. package/dist/logic/generateWatchOutput.d.ts.map +1 -1
  15. package/dist/logic/getCheckboxValue.d.ts +1 -1
  16. package/dist/logic/getCheckboxValue.d.ts.map +1 -1
  17. package/dist/logic/getProxyFormState.d.ts +1 -1
  18. package/dist/logic/getProxyFormState.d.ts.map +1 -1
  19. package/dist/logic/getRadioValue.d.ts +1 -1
  20. package/dist/logic/getRadioValue.d.ts.map +1 -1
  21. package/dist/types/controller.d.ts +5 -5
  22. package/dist/types/controller.d.ts.map +1 -1
  23. package/dist/types/errors.d.ts +8 -8
  24. package/dist/types/errors.d.ts.map +1 -1
  25. package/dist/types/events.d.ts +1 -1
  26. package/dist/types/events.d.ts.map +1 -1
  27. package/dist/types/fieldArray.d.ts +13 -13
  28. package/dist/types/fieldArray.d.ts.map +1 -1
  29. package/dist/types/fields.d.ts +10 -10
  30. package/dist/types/fields.d.ts.map +1 -1
  31. package/dist/types/form.d.ts +52 -52
  32. package/dist/types/form.d.ts.map +1 -1
  33. package/dist/types/path/common.d.ts +32 -32
  34. package/dist/types/path/common.d.ts.map +1 -1
  35. package/dist/types/path/eager.d.ts +11 -11
  36. package/dist/types/path/eager.d.ts.map +1 -1
  37. package/dist/types/resolvers.d.ts +4 -4
  38. package/dist/types/resolvers.d.ts.map +1 -1
  39. package/dist/types/utils.d.ts +13 -13
  40. package/dist/types/utils.d.ts.map +1 -1
  41. package/dist/types/validator.d.ts +6 -6
  42. package/dist/types/validator.d.ts.map +1 -1
  43. package/dist/useFormContext.d.ts +1 -1
  44. package/dist/useFormContext.d.ts.map +1 -1
  45. package/dist/useFormState.d.ts.map +1 -1
  46. package/dist/useSubscribe.d.ts +1 -1
  47. package/dist/useSubscribe.d.ts.map +1 -1
  48. package/dist/utils/createSubject.d.ts +3 -3
  49. package/dist/utils/createSubject.d.ts.map +1 -1
  50. package/package.json +3 -3
@@ -122,10 +122,7 @@ const useFormContext = () => React.useContext(HookFormContext);
122
122
  * }
123
123
  * ```
124
124
  */
125
- const FormProvider = (props) => {
126
- const { children, ...data } = props;
127
- return (React.createElement(HookFormContext.Provider, { value: data }, children));
128
- };
125
+ const FormProvider = ({ children, ...data }) => (React.createElement(HookFormContext.Provider, { value: React.useState(data)[0] }, children));
129
126
 
130
127
  var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
131
128
  const result = {
@@ -239,24 +236,29 @@ function useFormState(props) {
239
236
  });
240
237
  React.useEffect(() => {
241
238
  _mounted.current = true;
239
+ const isDirty = control._proxyFormState.isDirty && control._getDirty();
240
+ if (isDirty !== control._formState.isDirty) {
241
+ control._subjects.state.next({
242
+ isDirty,
243
+ });
244
+ }
245
+ control._updateValid();
242
246
  return () => {
243
247
  _mounted.current = false;
244
248
  };
245
- }, []);
249
+ }, [control]);
246
250
  return getProxyFormState(formState, control, _localProxyFormState.current, false);
247
251
  }
248
252
 
249
253
  var isString = (value) => typeof value === 'string';
250
254
 
251
255
  var generateWatchOutput = (names, _names, formValues, isGlobal) => {
252
- const isArray = Array.isArray(names);
253
256
  if (isString(names)) {
254
257
  isGlobal && _names.watch.add(names);
255
258
  return get(formValues, names);
256
259
  }
257
- if (isArray) {
258
- return names.map((fieldName) => (isGlobal && _names.watch.add(fieldName),
259
- get(formValues, fieldName)));
260
+ if (Array.isArray(names)) {
261
+ return names.map((fieldName) => (isGlobal && _names.watch.add(fieldName), get(formValues, fieldName)));
260
262
  }
261
263
  isGlobal && (_names.watchAll = true);
262
264
  return formValues;
@@ -322,16 +324,12 @@ function useWatch(props) {
322
324
  useSubscribe({
323
325
  disabled,
324
326
  subject: control._subjects.watch,
325
- callback: React.useCallback((formState) => {
327
+ callback: (formState) => {
326
328
  if (shouldSubscribeByName(_name.current, formState.name, exact)) {
327
329
  const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
328
- updateValue(isUndefined(_name.current) || !isUndefined(fieldValues)
329
- ? cloneObject(fieldValues)
330
- : isUndefined(fieldValues)
331
- ? defaultValue
332
- : fieldValues);
330
+ updateValue(isUndefined(fieldValues) ? defaultValue : cloneObject(fieldValues));
333
331
  }
334
- }, [control, exact, defaultValue]),
332
+ },
335
333
  });
336
334
  const [value, updateValue] = React.useState(isUndefined(defaultValue)
337
335
  ? control._getWatch(name)
@@ -1114,7 +1112,7 @@ function useFieldArray(props) {
1114
1112
  values: control._formValues,
1115
1113
  });
1116
1114
  control._names.focus &&
1117
- focusFieldBy(control._fields, (key) => !!key && key.startsWith(control._names.focus));
1115
+ focusFieldBy(control._fields, (key) => !!key && key.startsWith(control._names.focus || ''));
1118
1116
  control._names.focus = '';
1119
1117
  control._proxyFormState.isValid && control._updateValid();
1120
1118
  }, [fields, name, control]);
@@ -1315,7 +1313,7 @@ var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeVal
1315
1313
  };
1316
1314
 
1317
1315
  var getRuleValue = (rule) => isUndefined(rule)
1318
- ? undefined
1316
+ ? rule
1319
1317
  : isRegex(rule)
1320
1318
  ? rule.source
1321
1319
  : isObject(rule)
@@ -1442,11 +1440,10 @@ function createFormControl(props = {}) {
1442
1440
  timer = window.setTimeout(callback, wait);
1443
1441
  };
1444
1442
  const _updateValid = async () => {
1445
- let isValid = false;
1446
1443
  if (_proxyFormState.isValid) {
1447
- isValid = _options.resolver
1444
+ const isValid = _options.resolver
1448
1445
  ? isEmptyObject((await _executeSchema()).errors)
1449
- : await executeBuiltInValidation(_fields, true);
1446
+ : (await executeBuiltInValidation(_fields, true)).valid;
1450
1447
  if (isValid !== _formState.isValid) {
1451
1448
  _formState.isValid = isValid;
1452
1449
  _subjects.state.next({
@@ -1454,7 +1451,6 @@ function createFormControl(props = {}) {
1454
1451
  });
1455
1452
  }
1456
1453
  }
1457
- return isValid;
1458
1454
  };
1459
1455
  const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
1460
1456
  if (args && method) {
@@ -1463,8 +1459,7 @@ function createFormControl(props = {}) {
1463
1459
  const fieldValues = method(get(_fields, name), args.argA, args.argB);
1464
1460
  shouldSetValues && set(_fields, name, fieldValues);
1465
1461
  }
1466
- if (_proxyFormState.errors &&
1467
- shouldUpdateFieldsAndState &&
1462
+ if (shouldUpdateFieldsAndState &&
1468
1463
  Array.isArray(get(_formState.errors, name))) {
1469
1464
  const errors = method(get(_formState.errors, name), args.argA, args.argB);
1470
1465
  shouldSetValues && set(_formState.errors, name, errors);
@@ -1480,6 +1475,7 @@ function createFormControl(props = {}) {
1480
1475
  _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1481
1476
  }
1482
1477
  _subjects.state.next({
1478
+ name,
1483
1479
  isDirty: _getDirty(name, values),
1484
1480
  dirtyFields: _formState.dirtyFields,
1485
1481
  errors: _formState.errors,
@@ -1509,37 +1505,39 @@ function createFormControl(props = {}) {
1509
1505
  }
1510
1506
  };
1511
1507
  const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
1512
- let isFieldDirty = false;
1508
+ let shouldUpdateField = false;
1509
+ let isPreviousDirty = false;
1513
1510
  const output = {
1514
1511
  name,
1515
1512
  };
1516
- const isPreviousFieldTouched = get(_formState.touchedFields, name);
1517
1513
  if (_proxyFormState.isDirty) {
1518
- const isPreviousFormDirty = _formState.isDirty;
1514
+ isPreviousDirty = _formState.isDirty;
1519
1515
  _formState.isDirty = output.isDirty = _getDirty();
1520
- isFieldDirty = isPreviousFormDirty !== output.isDirty;
1516
+ shouldUpdateField = isPreviousDirty !== output.isDirty;
1521
1517
  }
1522
1518
  if (_proxyFormState.dirtyFields && (!isBlurEvent || shouldDirty)) {
1523
- const isPreviousFieldDirty = get(_formState.dirtyFields, name);
1519
+ isPreviousDirty = get(_formState.dirtyFields, name);
1524
1520
  const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
1525
1521
  isCurrentFieldPristine
1526
1522
  ? unset(_formState.dirtyFields, name)
1527
1523
  : set(_formState.dirtyFields, name, true);
1528
1524
  output.dirtyFields = _formState.dirtyFields;
1529
- isFieldDirty =
1530
- isFieldDirty ||
1531
- isPreviousFieldDirty !== get(_formState.dirtyFields, name);
1525
+ shouldUpdateField =
1526
+ shouldUpdateField || isPreviousDirty !== !isCurrentFieldPristine;
1532
1527
  }
1533
- if (isBlurEvent && !isPreviousFieldTouched) {
1534
- set(_formState.touchedFields, name, isBlurEvent);
1535
- output.touchedFields = _formState.touchedFields;
1536
- isFieldDirty =
1537
- isFieldDirty ||
1538
- (_proxyFormState.touchedFields &&
1539
- isPreviousFieldTouched !== isBlurEvent);
1528
+ if (isBlurEvent) {
1529
+ const isPreviousFieldTouched = get(_formState.touchedFields, name);
1530
+ if (!isPreviousFieldTouched) {
1531
+ set(_formState.touchedFields, name, isBlurEvent);
1532
+ output.touchedFields = _formState.touchedFields;
1533
+ shouldUpdateField =
1534
+ shouldUpdateField ||
1535
+ (_proxyFormState.touchedFields &&
1536
+ isPreviousFieldTouched !== isBlurEvent);
1537
+ }
1540
1538
  }
1541
- isFieldDirty && shouldRender && _subjects.state.next(output);
1542
- return isFieldDirty ? output : {};
1539
+ shouldUpdateField && shouldRender && _subjects.state.next(output);
1540
+ return shouldUpdateField ? output : {};
1543
1541
  };
1544
1542
  const shouldRenderByError = (name, isValid, error, fieldState) => {
1545
1543
  const previousFieldError = get(_formState.errors, name);
@@ -1581,9 +1579,7 @@ function createFormControl(props = {}) {
1581
1579
  validateFields = {};
1582
1580
  }
1583
1581
  };
1584
- const _executeSchema = async (name) => _options.resolver
1585
- ? await _options.resolver({ ..._formValues }, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation))
1586
- : {};
1582
+ const _executeSchema = async (name) => await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1587
1583
  const executeSchemaAndUpdateState = async (names) => {
1588
1584
  const { errors } = await _executeSchema();
1589
1585
  if (names) {
@@ -1610,6 +1606,9 @@ function createFormControl(props = {}) {
1610
1606
  const isFieldArrayRoot = _names.array.has(_f.name);
1611
1607
  const fieldError = await validateField(field, get(_formValues, _f.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation, isFieldArrayRoot);
1612
1608
  if (fieldError[_f.name]) {
1609
+ if (_f.name === context.name) {
1610
+ context.error = fieldError[context.name];
1611
+ }
1613
1612
  context.valid = false;
1614
1613
  if (shouldOnlyCheckValid) {
1615
1614
  break;
@@ -1626,7 +1625,7 @@ function createFormControl(props = {}) {
1626
1625
  (await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context));
1627
1626
  }
1628
1627
  }
1629
- return context.valid;
1628
+ return context;
1630
1629
  };
1631
1630
  const _removeUnmounted = () => {
1632
1631
  for (const name of _names.unMount) {
@@ -1641,18 +1640,15 @@ function createFormControl(props = {}) {
1641
1640
  };
1642
1641
  const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
1643
1642
  !deepEqual(getValues(), _defaultValues));
1644
- const _getWatch = (names, defaultValue, isGlobal) => {
1645
- const fieldValues = {
1646
- ...(_stateFlags.mount
1647
- ? _formValues
1648
- : isUndefined(defaultValue)
1649
- ? _defaultValues
1650
- : isString(names)
1651
- ? { [names]: defaultValue }
1652
- : defaultValue),
1653
- };
1654
- return generateWatchOutput(names, _names, fieldValues, isGlobal);
1655
- };
1643
+ const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
1644
+ ...(_stateFlags.mount
1645
+ ? _formValues
1646
+ : isUndefined(defaultValue)
1647
+ ? _defaultValues
1648
+ : isString(names)
1649
+ ? { [names]: defaultValue }
1650
+ : defaultValue),
1651
+ }, isGlobal);
1656
1652
  const _getFieldArray = (name) => compact(get(_stateFlags.mount ? _formValues : _defaultValues, name, props.shouldUnregister ? get(_defaultValues, name, []) : []));
1657
1653
  const setFieldValue = (name, value, options = {}) => {
1658
1654
  const field = get(_fields, name);
@@ -1796,8 +1792,17 @@ function createFormControl(props = {}) {
1796
1792
  isValid = isEmptyObject(errors);
1797
1793
  }
1798
1794
  else {
1799
- error = (await validateField(field, get(_formValues, name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
1800
- _updateValid();
1795
+ if (_proxyFormState.isValid) {
1796
+ const buildInValidationResult = await executeBuiltInValidation(_fields, true, {
1797
+ name,
1798
+ valid: true,
1799
+ });
1800
+ error = buildInValidationResult.error || {};
1801
+ isValid = buildInValidationResult.valid;
1802
+ }
1803
+ if (!error || isEmptyObject(error)) {
1804
+ error = (await validateField(field, get(_formValues, name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
1805
+ }
1801
1806
  }
1802
1807
  field._f.deps &&
1803
1808
  trigger(field._f.deps);
@@ -1821,12 +1826,13 @@ function createFormControl(props = {}) {
1821
1826
  else if (name) {
1822
1827
  validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
1823
1828
  const field = get(_fields, fieldName);
1824
- return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
1829
+ return (await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field)).valid;
1825
1830
  }))).every(Boolean);
1826
1831
  !(!validationResult && !_formState.isValid) && _updateValid();
1827
1832
  }
1828
1833
  else {
1829
- validationResult = isValid = await executeBuiltInValidation(_fields);
1834
+ validationResult = isValid = (await executeBuiltInValidation(_fields))
1835
+ .valid;
1830
1836
  }
1831
1837
  _subjects.state.next({
1832
1838
  ...(!isString(name) ||
@@ -1882,7 +1888,7 @@ function createFormControl(props = {}) {
1882
1888
  };
1883
1889
  const watch = (name, defaultValue) => isFunction(name)
1884
1890
  ? _subjects.watch.subscribe({
1885
- next: (info) => name(_getWatch(undefined, defaultValue), info),
1891
+ next: (payload) => name(_getWatch(undefined, defaultValue), payload),
1886
1892
  })
1887
1893
  : _getWatch(name, defaultValue, true);
1888
1894
  const unregister = (name, options = {}) => {
@@ -1967,9 +1973,7 @@ function createFormControl(props = {}) {
1967
1973
  refs: [
1968
1974
  ...refs.filter(live),
1969
1975
  fieldRef,
1970
- ...(!!Array.isArray(get(_defaultValues, name))
1971
- ? [{}]
1972
- : []),
1976
+ ...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
1973
1977
  ],
1974
1978
  ref: { type: fieldRef.type, name },
1975
1979
  }