react-hook-form 7.82.0 → 7.84.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.
Files changed (47) hide show
  1. package/README.md +2 -2
  2. package/dist/fieldArray.d.ts +2 -1
  3. package/dist/fieldArray.d.ts.map +1 -1
  4. package/dist/form.d.ts +1 -1
  5. package/dist/form.d.ts.map +1 -1
  6. package/dist/formStateSubscribe.d.ts +8 -3
  7. package/dist/formStateSubscribe.d.ts.map +1 -1
  8. package/dist/index.cjs.js +1 -1
  9. package/dist/index.cjs.js.map +1 -1
  10. package/dist/index.d.ts +2 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.esm.mjs +150 -82
  13. package/dist/index.esm.mjs.map +1 -1
  14. package/dist/index.umd.js +1 -1
  15. package/dist/index.umd.js.map +1 -1
  16. package/dist/logic/collectDirtyFieldNames.d.ts +3 -0
  17. package/dist/logic/collectDirtyFieldNames.d.ts.map +1 -0
  18. package/dist/logic/createFormControl.d.ts.map +1 -1
  19. package/dist/logic/getEventValue.d.ts.map +1 -1
  20. package/dist/logic/getFieldValue.d.ts.map +1 -1
  21. package/dist/logic/getValueAndMessage.d.ts +1 -4
  22. package/dist/logic/getValueAndMessage.d.ts.map +1 -1
  23. package/dist/logic/iterateFieldsByAction.d.ts.map +1 -1
  24. package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
  25. package/dist/react-server.esm.mjs +69 -27
  26. package/dist/react-server.esm.mjs.map +1 -1
  27. package/dist/types/errors.d.ts +2 -2
  28. package/dist/types/errors.d.ts.map +1 -1
  29. package/dist/types/form.d.ts +62 -61
  30. package/dist/types/form.d.ts.map +1 -1
  31. package/dist/types/path/common.d.ts +6 -0
  32. package/dist/types/path/common.d.ts.map +1 -1
  33. package/dist/types/path/eager.d.ts +15 -11
  34. package/dist/types/path/eager.d.ts.map +1 -1
  35. package/dist/types/utils.d.ts +1 -1
  36. package/dist/types/utils.d.ts.map +1 -1
  37. package/dist/types/validator.d.ts +1 -1
  38. package/dist/types/validator.d.ts.map +1 -1
  39. package/dist/types/watch.d.ts +1 -1
  40. package/dist/types/watch.d.ts.map +1 -1
  41. package/dist/useFormState.d.ts +2 -2
  42. package/dist/useWatch.d.ts +14 -14
  43. package/dist/utils/formData.d.ts +3 -0
  44. package/dist/utils/formData.d.ts.map +1 -0
  45. package/dist/utils/json.d.ts +9 -0
  46. package/dist/utils/json.d.ts.map +1 -0
  47. package/package.json +1 -3
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  export * from './controller';
2
2
  export { FieldArray } from './fieldArray';
3
3
  export * from './form';
4
- export * from './formStateSubscribe';
4
+ export type { FormStateProps, FormStateSubscribeProps, } from './formStateSubscribe';
5
+ export { FormState, FormStateSubscribe } from './formStateSubscribe';
5
6
  export * from './logic';
6
7
  export * from './types';
7
8
  export * from './useController';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,cAAc,QAAQ,CAAC;AACvB,cAAc,sBAAsB,CAAC;AACrC,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,cAAc,QAAQ,CAAC;AACvB,YAAY,EACV,cAAc,EACd,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrE,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
@@ -2,6 +2,8 @@ import React from 'react';
2
2
 
3
3
  var isCheckBoxInput = (element) => element.type === 'checkbox';
4
4
 
5
+ var isFileInput = (element) => element.type === 'file';
6
+
5
7
  var isDateObject = (value) => value instanceof Date;
6
8
 
7
9
  var isNullOrUndefined = (value) => value == null;
@@ -15,7 +17,9 @@ var isObject = (value) => !isNullOrUndefined(value) &&
15
17
  var getEventValue = (event) => isObject(event) && event.target
16
18
  ? isCheckBoxInput(event.target)
17
19
  ? event.target.checked
18
- : event.target.value
20
+ : isFileInput(event.target)
21
+ ? event.target.files
22
+ : event.target.value
19
23
  : event;
20
24
 
21
25
  var isNameInFieldArray = (names, name) => name
@@ -167,12 +171,12 @@ const useIsomorphicLayoutEffect = isWeb
167
171
  : React.useEffect;
168
172
 
169
173
  /**
170
- * This custom hook allows you to subscribe to each form state, and isolate the re-render at the custom hook level. It has its scope in terms of form state subscription, so it would not affect other useFormState and useForm. Using this hook can reduce the re-render impact on large and complex form application.
174
+ * Subscribes to each form state and isolates re-renders at the custom hook level. It has its own scope for form state subscriptions, so it will not affect other useFormState or useForm instances. Using this hook can reduce the re-render impact on large and complex form applications.
171
175
  *
172
176
  * @remarks
173
177
  * [API](https://react-hook-form.com/docs/useformstate) • [Demo](https://codesandbox.io/s/useformstate-75xly)
174
178
  *
175
- * @param props - include options on specify fields to subscribe. {@link UseFormStateReturn}
179
+ * @param props - Include options to specify fields to subscribe to. {@link UseFormStateReturn}
176
180
  *
177
181
  * @example
178
182
  * ```tsx
@@ -304,7 +308,7 @@ function deepEqual(object1, object2, visited = new WeakMap()) {
304
308
  }
305
309
 
306
310
  /**
307
- * Custom hook to subscribe to field change and isolate re-rendering at the component level.
311
+ * Custom hook to subscribe to field changes and isolate re-rendering at the component level.
308
312
  *
309
313
  * @remarks
310
314
  *
@@ -314,7 +318,7 @@ function deepEqual(object1, object2, visited = new WeakMap()) {
314
318
  * ```tsx
315
319
  * const { control } = useForm();
316
320
  * const values = useWatch({
317
- * name: "fieldName"
321
+ * name: "fieldName",
318
322
  * control,
319
323
  * })
320
324
  * ```
@@ -508,7 +512,7 @@ function useController(props) {
508
512
  }), [name, disabled, formState.disabled, onChange, onBlur, ref, value]);
509
513
  React.useEffect(() => {
510
514
  const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
511
- control.register(name, {
515
+ _registerProps.current = control.register(name, {
512
516
  ..._props.current.rules,
513
517
  ...(isBoolean(_props.current.disabled)
514
518
  ? { disabled: _props.current.disabled }
@@ -640,9 +644,12 @@ var isWatched = (name, _names, isBlurEvent) => {
640
644
 
641
645
  const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
642
646
  for (const key of fieldsNames || Object.keys(fields)) {
643
- const field = get(fields, key);
647
+ if (key === '_f') {
648
+ continue;
649
+ }
650
+ const field = fieldsNames ? get(fields, key) : fields[key];
644
651
  if (field) {
645
- const { _f, ...currentField } = field;
652
+ const { _f } = field;
646
653
  if (_f) {
647
654
  if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) {
648
655
  return true;
@@ -651,13 +658,13 @@ const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
651
658
  return true;
652
659
  }
653
660
  else {
654
- if (iterateFieldsByAction(currentField, action)) {
661
+ if (iterateFieldsByAction(field, action)) {
655
662
  break;
656
663
  }
657
664
  }
658
665
  }
659
- else if (isObject(currentField)) {
660
- if (iterateFieldsByAction(currentField, action)) {
666
+ else if (isObject(field) || Array.isArray(field)) {
667
+ if (iterateFieldsByAction(field, action)) {
661
668
  break;
662
669
  }
663
670
  }
@@ -676,8 +683,6 @@ var updateFieldArrayRootError = (errors, error, name) => {
676
683
 
677
684
  var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
678
685
 
679
- var isFileInput = (element) => element.type === 'file';
680
-
681
686
  var isHTMLElement = (value) => {
682
687
  if (!isWeb) {
683
688
  return false;
@@ -996,7 +1001,7 @@ var swapArrayAt = (data, indexA, indexB) => {
996
1001
  };
997
1002
 
998
1003
  function baseGet(object, updatePath) {
999
- const length = updatePath.slice(0, -1).length;
1004
+ const length = updatePath.length - 1;
1000
1005
  let index = 0;
1001
1006
  while (index < length) {
1002
1007
  if (isNullOrUndefined(object)) {
@@ -1415,6 +1420,26 @@ const flatten = (obj) => {
1415
1420
  return output;
1416
1421
  };
1417
1422
 
1423
+ function jsonToFormData(json) {
1424
+ const result = new FormData();
1425
+ const flattenFormValues = flatten(json);
1426
+ for (const key in flattenFormValues) {
1427
+ result.append(key, flattenFormValues[key]);
1428
+ }
1429
+ return result;
1430
+ }
1431
+
1432
+ function safeJSONStringify(value) {
1433
+ try {
1434
+ return JSON.stringify(value);
1435
+ }
1436
+ catch (_a) {
1437
+ return '';
1438
+ }
1439
+ }
1440
+
1441
+ function noop() { }
1442
+
1418
1443
  const HookFormContext = React.createContext(null);
1419
1444
  HookFormContext.displayName = 'HookFormContext';
1420
1445
  /**
@@ -1523,6 +1548,9 @@ const FormProvider = ({ children, watch, getValues, getFieldState, setError, cle
1523
1548
  };
1524
1549
 
1525
1550
  const POST_REQUEST = 'post';
1551
+ function defaultValidateStatus(status) {
1552
+ return status >= 200 && status < 300;
1553
+ }
1526
1554
  /**
1527
1555
  * Form component to manage submission.
1528
1556
  *
@@ -1548,21 +1576,11 @@ const POST_REQUEST = 'post';
1548
1576
  function Form(props) {
1549
1577
  const methods = useFormContext();
1550
1578
  const [mounted, setMounted] = React.useState(false);
1551
- const { control = methods.control, onSubmit, children, action, method = POST_REQUEST, headers, encType, onError, render, onSuccess, validateStatus, ...rest } = props;
1552
- const submit = React.useCallback(async (event) => {
1553
- let hasError = false;
1554
- let type = '';
1555
- await control.handleSubmit(async (data) => {
1556
- const formData = new FormData();
1557
- let formDataJson = '';
1558
- try {
1559
- formDataJson = JSON.stringify(data);
1560
- }
1561
- catch (_a) { }
1562
- const flattenFormValues = flatten(data);
1563
- for (const key in flattenFormValues) {
1564
- formData.append(key, flattenFormValues[key]);
1565
- }
1579
+ const { control = methods.control, onSubmit = noop, children, action, method = POST_REQUEST, headers, encType, onError = noop, render, onSuccess = noop, validateStatus = defaultValidateStatus, ...rest } = props;
1580
+ const handleSubmit = React.useMemo(() => {
1581
+ return control.handleSubmit(async (data, event) => {
1582
+ const formData = jsonToFormData(data);
1583
+ const formDataJson = safeJSONStringify(data);
1566
1584
  if (onSubmit) {
1567
1585
  await onSubmit({
1568
1586
  data,
@@ -1572,48 +1590,48 @@ function Form(props) {
1572
1590
  formDataJson,
1573
1591
  });
1574
1592
  }
1575
- if (action) {
1593
+ if (isString(action)) {
1576
1594
  try {
1577
- const shouldStringifySubmissionData = [
1578
- headers && headers['Content-Type'],
1579
- encType,
1580
- ].some((value) => value && value.includes('json'));
1581
- const response = await fetch(String(action), {
1595
+ const shouldStringifySubmissionData = (headers &&
1596
+ headers['Content-Type'] &&
1597
+ headers['Content-Type'].includes('json')) ||
1598
+ (encType && encType.includes('json'));
1599
+ const response = await fetch(action, {
1582
1600
  method,
1583
1601
  headers: {
1584
1602
  ...headers,
1585
- ...(encType && encType !== 'multipart/form-data'
1586
- ? { 'Content-Type': encType }
1587
- : {}),
1603
+ ...(encType &&
1604
+ encType !== 'multipart/form-data' && {
1605
+ 'Content-Type': encType,
1606
+ }),
1588
1607
  },
1589
1608
  body: shouldStringifySubmissionData ? formDataJson : formData,
1590
1609
  });
1591
- if (response &&
1592
- (validateStatus
1593
- ? !validateStatus(response.status)
1594
- : response.status < 200 || response.status >= 300)) {
1595
- hasError = true;
1596
- onError && onError({ response });
1597
- type = String(response.status);
1610
+ if (response && !validateStatus(response.status)) {
1611
+ onError({ response });
1612
+ return { type: String(response.status) };
1598
1613
  }
1599
1614
  else {
1600
- onSuccess && onSuccess({ response });
1615
+ onSuccess({ response });
1601
1616
  }
1602
1617
  }
1603
1618
  catch (error) {
1604
- hasError = true;
1605
- onError && onError({ error });
1619
+ onError({ error });
1620
+ return { type: '' };
1606
1621
  }
1607
1622
  }
1608
- })(event);
1609
- if (hasError && control) {
1610
- control._subjects.state.next({
1611
- isSubmitSuccessful: false,
1612
- });
1613
- control.setError('root.server', {
1614
- type,
1615
- });
1616
- }
1623
+ if (isFunction(action)) {
1624
+ try {
1625
+ await action(formData);
1626
+ }
1627
+ catch (error) {
1628
+ onError({ error });
1629
+ return { type: '' };
1630
+ }
1631
+ }
1632
+ // Return nothing when successful.
1633
+ return;
1634
+ });
1617
1635
  }, [
1618
1636
  control,
1619
1637
  onSubmit,
@@ -1625,15 +1643,28 @@ function Form(props) {
1625
1643
  onError,
1626
1644
  onSuccess,
1627
1645
  ]);
1646
+ const submit = React.useCallback(async (event) => {
1647
+ const err = await handleSubmit(event);
1648
+ if (err && control) {
1649
+ control._subjects.state.next({ isSubmitSuccessful: false });
1650
+ control.setError('root.server', err);
1651
+ }
1652
+ }, [handleSubmit, control]);
1628
1653
  React.useEffect(() => {
1629
1654
  setMounted(true);
1630
1655
  }, []);
1631
- return render ? (React.createElement(React.Fragment, null, render({
1632
- submit,
1633
- }))) : (React.createElement("form", { noValidate: mounted, action: action, method: method, encType: encType, onSubmit: submit, ...rest }, children));
1656
+ if (render) {
1657
+ return render({ submit });
1658
+ }
1659
+ // React forbids passing `method`/`encType` alongside a function `action`
1660
+ // (a Server-Action-style submission) -- it manages those itself and warns
1661
+ // if they're present, so they're only rendered for string/URL actions.
1662
+ return (React.createElement("form", { noValidate: mounted, action: action, ...(!isFunction(action) && { method, encType }), onSubmit: submit, ...rest }, children));
1634
1663
  }
1635
1664
 
1636
- const FormStateSubscribe = ({ control, disabled, exact, name, render, }) => render(useFormState({ control, name, disabled, exact }));
1665
+ const FormState = ({ control, disabled, exact, name, render, }) => render(useFormState({ control, name, disabled, exact }));
1666
+ /** @deprecated Use `FormState` instead. Kept as an alias for backward compatibility. */
1667
+ const FormStateSubscribe = FormState;
1637
1668
 
1638
1669
  var createSubject = () => {
1639
1670
  let _observers = [];
@@ -1689,6 +1720,24 @@ var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
1689
1720
 
1690
1721
  var live = (ref) => isHTMLElement(ref) && ref.isConnected;
1691
1722
 
1723
+ function isDirtyContainer(value) {
1724
+ return Array.isArray(value) || isObject(value);
1725
+ }
1726
+ function collectDirtyFieldNames(dirtyTree, cachedDirtyFields, prefix = '', names = []) {
1727
+ for (const key in dirtyTree) {
1728
+ const path = prefix ? `${prefix}.${key}` : key;
1729
+ const value = dirtyTree[key];
1730
+ if (isDirtyContainer(value) &&
1731
+ isDirtyContainer(get(cachedDirtyFields, path))) {
1732
+ collectDirtyFieldNames(value, cachedDirtyFields, path, names);
1733
+ }
1734
+ else {
1735
+ names.push(path);
1736
+ }
1737
+ }
1738
+ return names;
1739
+ }
1740
+
1692
1741
  var objectHasFunction = (data) => {
1693
1742
  for (const key in data) {
1694
1743
  if (isFunction(data[key])) {
@@ -1792,7 +1841,7 @@ function getFieldValue(_f) {
1792
1841
  if (isCheckBoxInput(ref)) {
1793
1842
  return getCheckboxValue(_f.refs).value;
1794
1843
  }
1795
- return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f);
1844
+ return getFieldValueAs(ref.value, _f);
1796
1845
  }
1797
1846
 
1798
1847
  var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
@@ -1883,8 +1932,7 @@ function schemaErrorLookup(errors, _fields, name) {
1883
1932
 
1884
1933
  var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
1885
1934
  updateFormState(formStateData);
1886
- const { name, ...formState } = formStateData;
1887
- const keys = Object.keys(formState);
1935
+ const keys = Object.keys(formStateData).filter((key) => key !== 'name');
1888
1936
  return (!keys.length ||
1889
1937
  (isRoot && keys.length >= Object.keys(_proxyFormState).length) ||
1890
1938
  keys.find((key) => _proxyFormState[key] ===
@@ -1924,6 +1972,14 @@ const defaultOptions = {
1924
1972
  shouldFocusError: true,
1925
1973
  };
1926
1974
  const FORM_ERROR_TYPE = 'form';
1975
+ const updateDirtyFields = (dirtyFields, nextDirtyFields) => {
1976
+ for (const key in dirtyFields) {
1977
+ if (!(key in nextDirtyFields)) {
1978
+ delete dirtyFields[key];
1979
+ }
1980
+ }
1981
+ Object.assign(dirtyFields, nextDirtyFields);
1982
+ };
1927
1983
  const DEFAULT_FORM_STATE = {
1928
1984
  submitCount: 0,
1929
1985
  isDirty: false,
@@ -2166,7 +2222,7 @@ function createFormControl(props = {}) {
2166
2222
  }
2167
2223
  isPreviousDirty = !!get(_formState.dirtyFields, name);
2168
2224
  if (isCurrentFieldPristine !== _formState.isDirty) {
2169
- _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
2225
+ updateDirtyFields(_formState.dirtyFields, getDirtyFields(_defaultValues, _formValues, undefined, _fields));
2170
2226
  }
2171
2227
  else {
2172
2228
  isCurrentFieldPristine
@@ -2427,6 +2483,12 @@ function createFormControl(props = {}) {
2427
2483
  });
2428
2484
  };
2429
2485
  const setFieldValues = (name, value, options, skipClone = false, skipRender = false) => {
2486
+ if (_names.array.has(name)) {
2487
+ _subjects.array.next({
2488
+ name,
2489
+ values: skipClone ? _formValues : cloneObject(_formValues),
2490
+ });
2491
+ }
2430
2492
  for (const fieldKey in value) {
2431
2493
  if (!value.hasOwnProperty(fieldKey)) {
2432
2494
  return;
@@ -2723,8 +2785,9 @@ function createFormControl(props = {}) {
2723
2785
  });
2724
2786
  }
2725
2787
  else {
2788
+ _formState.errors = {};
2726
2789
  _subjects.state.next({
2727
- errors: {},
2790
+ errors: _formState.errors,
2728
2791
  });
2729
2792
  }
2730
2793
  };
@@ -2909,20 +2972,23 @@ function createFormControl(props = {}) {
2909
2972
  : fieldRef === field._f.ref) {
2910
2973
  return;
2911
2974
  }
2975
+ const newField = {
2976
+ ...field._f,
2977
+ };
2978
+ if (radioOrCheckbox) {
2979
+ newField.refs = [
2980
+ ...refs.filter(live),
2981
+ fieldRef,
2982
+ ...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
2983
+ ];
2984
+ newField.ref = { type: fieldRef.type, name };
2985
+ }
2986
+ else {
2987
+ newField.ref = fieldRef;
2988
+ delete newField.refs;
2989
+ }
2912
2990
  set(_fields, name, {
2913
- _f: {
2914
- ...field._f,
2915
- ...(radioOrCheckbox
2916
- ? {
2917
- refs: [
2918
- ...refs.filter(live),
2919
- fieldRef,
2920
- ...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
2921
- ],
2922
- ref: { type: fieldRef.type, name },
2923
- }
2924
- : { ref: fieldRef }),
2925
- },
2991
+ _f: newField,
2926
2992
  });
2927
2993
  updateValidAndValue(name, false, undefined, fieldRef);
2928
2994
  }
@@ -2958,6 +3024,7 @@ function createFormControl(props = {}) {
2958
3024
  }
2959
3025
  };
2960
3026
  const handleSubmit = (onValid, onInvalid) => async (e) => {
3027
+ let result = undefined;
2961
3028
  let onValidError = undefined;
2962
3029
  if (e) {
2963
3030
  e.preventDefault && e.preventDefault();
@@ -2991,7 +3058,7 @@ function createFormControl(props = {}) {
2991
3058
  errors: {},
2992
3059
  });
2993
3060
  try {
2994
- await onValid(fieldValues, e);
3061
+ result = await onValid(fieldValues, e);
2995
3062
  }
2996
3063
  catch (error) {
2997
3064
  onValidError = error;
@@ -3014,6 +3081,7 @@ function createFormControl(props = {}) {
3014
3081
  if (onValidError) {
3015
3082
  throw onValidError;
3016
3083
  }
3084
+ return result;
3017
3085
  };
3018
3086
  const resetField = (name, options = {}) => {
3019
3087
  if (get(_fields, name)) {
@@ -3053,7 +3121,7 @@ function createFormControl(props = {}) {
3053
3121
  if (keepStateOptions.keepDirtyValues) {
3054
3122
  const fieldsToCheck = new Set([
3055
3123
  ..._names.mount,
3056
- ...Object.keys(getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs)),
3124
+ ...collectDirtyFieldNames(getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs), _formState.dirtyFields),
3057
3125
  ]);
3058
3126
  for (const fieldName of Array.from(fieldsToCheck)) {
3059
3127
  const isDirty = get(_formState.dirtyFields, fieldName);
@@ -3482,5 +3550,5 @@ function useForm(props = {}) {
3482
3550
  */
3483
3551
  const Watch = (props) => props.render(useWatch({ name: props.names, ...props }));
3484
3552
 
3485
- export { Controller, FieldArray, Form, FormProvider, FormStateSubscribe, Watch, appendErrors, createFormControl, get, set, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
3553
+ export { Controller, FieldArray, Form, FormProvider, FormState, FormStateSubscribe, Watch, appendErrors, createFormControl, get, set, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
3486
3554
  //# sourceMappingURL=index.esm.mjs.map