react-hook-form 7.73.1 → 7.75.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 (250) hide show
  1. package/README.md +1 -2
  2. package/dist/index.cjs.js +1 -1
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.esm.mjs +120 -68
  5. package/dist/index.esm.mjs.map +1 -1
  6. package/dist/index.umd.js +1 -1
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/logic/createFormControl.d.ts +13 -0
  9. package/dist/logic/createFormControl.d.ts.map +1 -1
  10. package/dist/logic/getDirtyFields.d.ts.map +1 -1
  11. package/dist/logic/getProxyFormState.d.ts.map +1 -1
  12. package/dist/logic/getResolverOptions.d.ts +2 -2
  13. package/dist/logic/hasValidation.d.ts +1 -1
  14. package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
  15. package/dist/logic/validateField.d.ts.map +1 -1
  16. package/dist/react-server.esm.mjs +98 -41
  17. package/dist/react-server.esm.mjs.map +1 -1
  18. package/dist/types/form.d.ts +3 -0
  19. package/dist/types/form.d.ts.map +1 -1
  20. package/dist/useController.d.ts.map +1 -1
  21. package/dist/useFieldArray.d.ts.map +1 -1
  22. package/dist/useForm.d.ts.map +1 -1
  23. package/dist/useFormContext.d.ts.map +1 -1
  24. package/dist/useFormState.d.ts.map +1 -1
  25. package/dist/utils/unset.d.ts.map +1 -1
  26. package/package.json +4 -5
  27. package/dist/__tests__/controller.server.test.d.ts +0 -2
  28. package/dist/__tests__/controller.server.test.d.ts.map +0 -1
  29. package/dist/__tests__/controller.test.d.ts +0 -2
  30. package/dist/__tests__/controller.test.d.ts.map +0 -1
  31. package/dist/__tests__/form.test.d.ts +0 -2
  32. package/dist/__tests__/form.test.d.ts.map +0 -1
  33. package/dist/__tests__/formStateSubscribe.server.test.d.ts +0 -2
  34. package/dist/__tests__/formStateSubscribe.server.test.d.ts.map +0 -1
  35. package/dist/__tests__/formStateSubscribe.test.d.ts +0 -2
  36. package/dist/__tests__/formStateSubscribe.test.d.ts.map +0 -1
  37. package/dist/__tests__/isPlainObject.test.d.ts +0 -2
  38. package/dist/__tests__/isPlainObject.test.d.ts.map +0 -1
  39. package/dist/__tests__/logic/appendErrors.test.d.ts +0 -2
  40. package/dist/__tests__/logic/appendErrors.test.d.ts.map +0 -1
  41. package/dist/__tests__/logic/createFormControl.test.d.ts +0 -2
  42. package/dist/__tests__/logic/createFormControl.test.d.ts.map +0 -1
  43. package/dist/__tests__/logic/generateId.test.d.ts +0 -2
  44. package/dist/__tests__/logic/generateId.test.d.ts.map +0 -1
  45. package/dist/__tests__/logic/getCheckboxValue.test.d.ts +0 -2
  46. package/dist/__tests__/logic/getCheckboxValue.test.d.ts.map +0 -1
  47. package/dist/__tests__/logic/getDirtyFields.test.d.ts +0 -2
  48. package/dist/__tests__/logic/getDirtyFields.test.d.ts.map +0 -1
  49. package/dist/__tests__/logic/getEventValue.test.d.ts +0 -2
  50. package/dist/__tests__/logic/getEventValue.test.d.ts.map +0 -1
  51. package/dist/__tests__/logic/getFieldValue.test.d.ts +0 -2
  52. package/dist/__tests__/logic/getFieldValue.test.d.ts.map +0 -1
  53. package/dist/__tests__/logic/getFieldValueAs.test.d.ts +0 -2
  54. package/dist/__tests__/logic/getFieldValueAs.test.d.ts.map +0 -1
  55. package/dist/__tests__/logic/getFocusFieldName.test.d.ts +0 -2
  56. package/dist/__tests__/logic/getFocusFieldName.test.d.ts.map +0 -1
  57. package/dist/__tests__/logic/getNodeParentName.test.d.ts +0 -2
  58. package/dist/__tests__/logic/getNodeParentName.test.d.ts.map +0 -1
  59. package/dist/__tests__/logic/getRadioValue.test.d.ts +0 -2
  60. package/dist/__tests__/logic/getRadioValue.test.d.ts.map +0 -1
  61. package/dist/__tests__/logic/getResolverOptions.test.d.ts +0 -2
  62. package/dist/__tests__/logic/getResolverOptions.test.d.ts.map +0 -1
  63. package/dist/__tests__/logic/getRuleValue.test.d.ts +0 -2
  64. package/dist/__tests__/logic/getRuleValue.test.d.ts.map +0 -1
  65. package/dist/__tests__/logic/getValidateError.test.d.ts +0 -2
  66. package/dist/__tests__/logic/getValidateError.test.d.ts.map +0 -1
  67. package/dist/__tests__/logic/getValidationModes.test.d.ts +0 -2
  68. package/dist/__tests__/logic/getValidationModes.test.d.ts.map +0 -1
  69. package/dist/__tests__/logic/getValueAndMessage.test.d.ts +0 -2
  70. package/dist/__tests__/logic/getValueAndMessage.test.d.ts.map +0 -1
  71. package/dist/__tests__/logic/hasPromiseValidation.test.d.ts +0 -2
  72. package/dist/__tests__/logic/hasPromiseValidation.test.d.ts.map +0 -1
  73. package/dist/__tests__/logic/hasValidation.test.d.ts +0 -2
  74. package/dist/__tests__/logic/hasValidation.test.d.ts.map +0 -1
  75. package/dist/__tests__/logic/isNameInFieldArray.test.d.ts +0 -2
  76. package/dist/__tests__/logic/isNameInFieldArray.test.d.ts.map +0 -1
  77. package/dist/__tests__/logic/isWatched.test.d.ts +0 -2
  78. package/dist/__tests__/logic/isWatched.test.d.ts.map +0 -1
  79. package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts +0 -2
  80. package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts.map +0 -1
  81. package/dist/__tests__/logic/schemaErrorLookup.test.d.ts +0 -2
  82. package/dist/__tests__/logic/schemaErrorLookup.test.d.ts.map +0 -1
  83. package/dist/__tests__/logic/shouldRenderFormState.test.d.ts +0 -2
  84. package/dist/__tests__/logic/shouldRenderFormState.test.d.ts.map +0 -1
  85. package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts +0 -2
  86. package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts.map +0 -1
  87. package/dist/__tests__/logic/skipValidation.test.d.ts +0 -2
  88. package/dist/__tests__/logic/skipValidation.test.d.ts.map +0 -1
  89. package/dist/__tests__/logic/unsetEmptyArray.test.d.ts +0 -2
  90. package/dist/__tests__/logic/unsetEmptyArray.test.d.ts.map +0 -1
  91. package/dist/__tests__/logic/validateField.test.d.ts +0 -2
  92. package/dist/__tests__/logic/validateField.test.d.ts.map +0 -1
  93. package/dist/__tests__/nested-null.test.d.ts +0 -2
  94. package/dist/__tests__/nested-null.test.d.ts.map +0 -1
  95. package/dist/__tests__/type.test.d.ts +0 -2
  96. package/dist/__tests__/type.test.d.ts.map +0 -1
  97. package/dist/__tests__/useController.test.d.ts +0 -2
  98. package/dist/__tests__/useController.test.d.ts.map +0 -1
  99. package/dist/__tests__/useFieldArray/append.test.d.ts +0 -2
  100. package/dist/__tests__/useFieldArray/append.test.d.ts.map +0 -1
  101. package/dist/__tests__/useFieldArray/dirtyFields.test.d.ts +0 -2
  102. package/dist/__tests__/useFieldArray/dirtyFields.test.d.ts.map +0 -1
  103. package/dist/__tests__/useFieldArray/focus.test.d.ts +0 -2
  104. package/dist/__tests__/useFieldArray/focus.test.d.ts.map +0 -1
  105. package/dist/__tests__/useFieldArray/insert.test.d.ts +0 -2
  106. package/dist/__tests__/useFieldArray/insert.test.d.ts.map +0 -1
  107. package/dist/__tests__/useFieldArray/move.test.d.ts +0 -2
  108. package/dist/__tests__/useFieldArray/move.test.d.ts.map +0 -1
  109. package/dist/__tests__/useFieldArray/prepend.test.d.ts +0 -2
  110. package/dist/__tests__/useFieldArray/prepend.test.d.ts.map +0 -1
  111. package/dist/__tests__/useFieldArray/remove.test.d.ts +0 -2
  112. package/dist/__tests__/useFieldArray/remove.test.d.ts.map +0 -1
  113. package/dist/__tests__/useFieldArray/replace.test.d.ts +0 -2
  114. package/dist/__tests__/useFieldArray/replace.test.d.ts.map +0 -1
  115. package/dist/__tests__/useFieldArray/swap.test.d.ts +0 -2
  116. package/dist/__tests__/useFieldArray/swap.test.d.ts.map +0 -1
  117. package/dist/__tests__/useFieldArray/update.test.d.ts +0 -2
  118. package/dist/__tests__/useFieldArray/update.test.d.ts.map +0 -1
  119. package/dist/__tests__/useFieldArray.test.d.ts +0 -2
  120. package/dist/__tests__/useFieldArray.test.d.ts.map +0 -1
  121. package/dist/__tests__/useForm/clearErrors.test.d.ts +0 -2
  122. package/dist/__tests__/useForm/clearErrors.test.d.ts.map +0 -1
  123. package/dist/__tests__/useForm/formState.test.d.ts +0 -2
  124. package/dist/__tests__/useForm/formState.test.d.ts.map +0 -1
  125. package/dist/__tests__/useForm/getFieldState.test.d.ts +0 -2
  126. package/dist/__tests__/useForm/getFieldState.test.d.ts.map +0 -1
  127. package/dist/__tests__/useForm/getValues.test.d.ts +0 -2
  128. package/dist/__tests__/useForm/getValues.test.d.ts.map +0 -1
  129. package/dist/__tests__/useForm/handleSubmit.test.d.ts +0 -2
  130. package/dist/__tests__/useForm/handleSubmit.test.d.ts.map +0 -1
  131. package/dist/__tests__/useForm/register.test.d.ts +0 -2
  132. package/dist/__tests__/useForm/register.test.d.ts.map +0 -1
  133. package/dist/__tests__/useForm/reset.test.d.ts +0 -2
  134. package/dist/__tests__/useForm/reset.test.d.ts.map +0 -1
  135. package/dist/__tests__/useForm/resetField.test.d.ts +0 -2
  136. package/dist/__tests__/useForm/resetField.test.d.ts.map +0 -1
  137. package/dist/__tests__/useForm/resolver.test.d.ts +0 -2
  138. package/dist/__tests__/useForm/resolver.test.d.ts.map +0 -1
  139. package/dist/__tests__/useForm/setError.test.d.ts +0 -2
  140. package/dist/__tests__/useForm/setError.test.d.ts.map +0 -1
  141. package/dist/__tests__/useForm/setFocus.test.d.ts +0 -2
  142. package/dist/__tests__/useForm/setFocus.test.d.ts.map +0 -1
  143. package/dist/__tests__/useForm/setValue.test.d.ts +0 -2
  144. package/dist/__tests__/useForm/setValue.test.d.ts.map +0 -1
  145. package/dist/__tests__/useForm/subscribe.test.d.ts +0 -2
  146. package/dist/__tests__/useForm/subscribe.test.d.ts.map +0 -1
  147. package/dist/__tests__/useForm/trigger.test.d.ts +0 -2
  148. package/dist/__tests__/useForm/trigger.test.d.ts.map +0 -1
  149. package/dist/__tests__/useForm/unregister.test.d.ts +0 -2
  150. package/dist/__tests__/useForm/unregister.test.d.ts.map +0 -1
  151. package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts +0 -2
  152. package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts.map +0 -1
  153. package/dist/__tests__/useForm/watch.test.d.ts +0 -2
  154. package/dist/__tests__/useForm/watch.test.d.ts.map +0 -1
  155. package/dist/__tests__/useForm.server.test.d.ts +0 -2
  156. package/dist/__tests__/useForm.server.test.d.ts.map +0 -1
  157. package/dist/__tests__/useForm.test.d.ts +0 -2
  158. package/dist/__tests__/useForm.test.d.ts.map +0 -1
  159. package/dist/__tests__/useFormContext.server.test.d.ts +0 -2
  160. package/dist/__tests__/useFormContext.server.test.d.ts.map +0 -1
  161. package/dist/__tests__/useFormContext.test.d.ts +0 -2
  162. package/dist/__tests__/useFormContext.test.d.ts.map +0 -1
  163. package/dist/__tests__/useFormState.test.d.ts +0 -2
  164. package/dist/__tests__/useFormState.test.d.ts.map +0 -1
  165. package/dist/__tests__/useWatch.test.d.ts +0 -2
  166. package/dist/__tests__/useWatch.test.d.ts.map +0 -1
  167. package/dist/__tests__/utils/append.test.d.ts +0 -2
  168. package/dist/__tests__/utils/append.test.d.ts.map +0 -1
  169. package/dist/__tests__/utils/cloneObject.test.d.ts +0 -2
  170. package/dist/__tests__/utils/cloneObject.test.d.ts.map +0 -1
  171. package/dist/__tests__/utils/compact.test.d.ts +0 -2
  172. package/dist/__tests__/utils/compact.test.d.ts.map +0 -1
  173. package/dist/__tests__/utils/convertToArrayPayload.test.d.ts +0 -2
  174. package/dist/__tests__/utils/convertToArrayPayload.test.d.ts.map +0 -1
  175. package/dist/__tests__/utils/createSubject.test.d.ts +0 -2
  176. package/dist/__tests__/utils/createSubject.test.d.ts.map +0 -1
  177. package/dist/__tests__/utils/deepEqual.test.d.ts +0 -2
  178. package/dist/__tests__/utils/deepEqual.test.d.ts.map +0 -1
  179. package/dist/__tests__/utils/deepMerge.test.d.ts +0 -2
  180. package/dist/__tests__/utils/deepMerge.test.d.ts.map +0 -1
  181. package/dist/__tests__/utils/extractFormValues.test.d.ts +0 -2
  182. package/dist/__tests__/utils/extractFormValues.test.d.ts.map +0 -1
  183. package/dist/__tests__/utils/fillEmptyArray.test.d.ts +0 -2
  184. package/dist/__tests__/utils/fillEmptyArray.test.d.ts.map +0 -1
  185. package/dist/__tests__/utils/flatten.test.d.ts +0 -2
  186. package/dist/__tests__/utils/flatten.test.d.ts.map +0 -1
  187. package/dist/__tests__/utils/get.test.d.ts +0 -2
  188. package/dist/__tests__/utils/get.test.d.ts.map +0 -1
  189. package/dist/__tests__/utils/insert.test.d.ts +0 -2
  190. package/dist/__tests__/utils/insert.test.d.ts.map +0 -1
  191. package/dist/__tests__/utils/isBoolean.test.d.ts +0 -2
  192. package/dist/__tests__/utils/isBoolean.test.d.ts.map +0 -1
  193. package/dist/__tests__/utils/isCheckBoxInput.test.d.ts +0 -2
  194. package/dist/__tests__/utils/isCheckBoxInput.test.d.ts.map +0 -1
  195. package/dist/__tests__/utils/isEmptyObject.test.d.ts +0 -2
  196. package/dist/__tests__/utils/isEmptyObject.test.d.ts.map +0 -1
  197. package/dist/__tests__/utils/isFileInput.test.d.ts +0 -2
  198. package/dist/__tests__/utils/isFileInput.test.d.ts.map +0 -1
  199. package/dist/__tests__/utils/isFunction.test.d.ts +0 -2
  200. package/dist/__tests__/utils/isFunction.test.d.ts.map +0 -1
  201. package/dist/__tests__/utils/isHTMLElement.test.d.ts +0 -2
  202. package/dist/__tests__/utils/isHTMLElement.test.d.ts.map +0 -1
  203. package/dist/__tests__/utils/isKey.test.d.ts +0 -2
  204. package/dist/__tests__/utils/isKey.test.d.ts.map +0 -1
  205. package/dist/__tests__/utils/isMultipleSelect.test.d.ts +0 -2
  206. package/dist/__tests__/utils/isMultipleSelect.test.d.ts.map +0 -1
  207. package/dist/__tests__/utils/isNullOrUndefined.test.d.ts +0 -2
  208. package/dist/__tests__/utils/isNullOrUndefined.test.d.ts.map +0 -1
  209. package/dist/__tests__/utils/isObject.test.d.ts +0 -2
  210. package/dist/__tests__/utils/isObject.test.d.ts.map +0 -1
  211. package/dist/__tests__/utils/isPrimitive.test.d.ts +0 -2
  212. package/dist/__tests__/utils/isPrimitive.test.d.ts.map +0 -1
  213. package/dist/__tests__/utils/isRadioInput.test.d.ts +0 -2
  214. package/dist/__tests__/utils/isRadioInput.test.d.ts.map +0 -1
  215. package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts +0 -2
  216. package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts.map +0 -1
  217. package/dist/__tests__/utils/isRegex.test.d.ts +0 -2
  218. package/dist/__tests__/utils/isRegex.test.d.ts.map +0 -1
  219. package/dist/__tests__/utils/isString.test.d.ts +0 -2
  220. package/dist/__tests__/utils/isString.test.d.ts.map +0 -1
  221. package/dist/__tests__/utils/isUndefined.test.d.ts +0 -2
  222. package/dist/__tests__/utils/isUndefined.test.d.ts.map +0 -1
  223. package/dist/__tests__/utils/live.test.d.ts +0 -2
  224. package/dist/__tests__/utils/live.test.d.ts.map +0 -1
  225. package/dist/__tests__/utils/move.test.d.ts +0 -2
  226. package/dist/__tests__/utils/move.test.d.ts.map +0 -1
  227. package/dist/__tests__/utils/noop.test.d.ts +0 -2
  228. package/dist/__tests__/utils/noop.test.d.ts.map +0 -1
  229. package/dist/__tests__/utils/objectHasFunction.test.d.ts +0 -2
  230. package/dist/__tests__/utils/objectHasFunction.test.d.ts.map +0 -1
  231. package/dist/__tests__/utils/prepend.test.d.ts +0 -2
  232. package/dist/__tests__/utils/prepend.test.d.ts.map +0 -1
  233. package/dist/__tests__/utils/remove.test.d.ts +0 -2
  234. package/dist/__tests__/utils/remove.test.d.ts.map +0 -1
  235. package/dist/__tests__/utils/set.test.d.ts +0 -2
  236. package/dist/__tests__/utils/set.test.d.ts.map +0 -1
  237. package/dist/__tests__/utils/stringToPath.test.d.ts +0 -2
  238. package/dist/__tests__/utils/stringToPath.test.d.ts.map +0 -1
  239. package/dist/__tests__/utils/swap.test.d.ts +0 -2
  240. package/dist/__tests__/utils/swap.test.d.ts.map +0 -1
  241. package/dist/__tests__/utils/unset.test.d.ts +0 -2
  242. package/dist/__tests__/utils/unset.test.d.ts.map +0 -1
  243. package/dist/__tests__/utils/update.test.d.ts +0 -2
  244. package/dist/__tests__/utils/update.test.d.ts.map +0 -1
  245. package/dist/__tests__/utils/validationModeChecker.test.d.ts +0 -2
  246. package/dist/__tests__/utils/validationModeChecker.test.d.ts.map +0 -1
  247. package/dist/__tests__/watch.server.test.d.ts +0 -2
  248. package/dist/__tests__/watch.server.test.d.ts.map +0 -1
  249. package/dist/__tests__/watch.test.d.ts +0 -2
  250. package/dist/__tests__/watch.test.d.ts.map +0 -1
@@ -143,9 +143,7 @@ HookFormControlContext.displayName = 'HookFormControlContext';
143
143
  const useFormControlContext = () => React.useContext(HookFormControlContext);
144
144
 
145
145
  var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
146
- const result = {
147
- defaultValues: control._defaultValues,
148
- };
146
+ const result = {};
149
147
  for (const key in formState) {
150
148
  Object.defineProperty(result, key, {
151
149
  get: () => {
@@ -196,7 +194,10 @@ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayou
196
194
  function useFormState(props) {
197
195
  const formControl = useFormControlContext();
198
196
  const { control = formControl, disabled, name, exact } = props || {};
199
- const [formState, updateFormState] = React.useState(control._formState);
197
+ const [formState, updateFormState] = React.useState(() => ({
198
+ ...control._formState,
199
+ defaultValues: control._defaultValues,
200
+ }));
200
201
  const _localProxyFormState = React.useRef({
201
202
  isDirty: false,
202
203
  isLoading: false,
@@ -216,6 +217,7 @@ function useFormState(props) {
216
217
  updateFormState({
217
218
  ...control._formState,
218
219
  ...formState,
220
+ defaultValues: control._defaultValues,
219
221
  });
220
222
  },
221
223
  }), [name, disabled, exact]);
@@ -408,7 +410,6 @@ function useController(props) {
408
410
  exact,
409
411
  });
410
412
  const _props = React.useRef(props);
411
- const _previousNameRef = React.useRef(undefined);
412
413
  const _registerProps = React.useRef(control.register(name, {
413
414
  ...props.rules,
414
415
  value,
@@ -474,10 +475,6 @@ function useController(props) {
474
475
  }), [name, disabled, formState.disabled, onChange, onBlur, ref, value]);
475
476
  React.useEffect(() => {
476
477
  const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
477
- const previousName = _previousNameRef.current;
478
- if (previousName && previousName !== name && !isArrayField) {
479
- control.unregister(previousName);
480
- }
481
478
  control.register(name, {
482
479
  ..._props.current.rules,
483
480
  ...(isBoolean(_props.current.disabled)
@@ -499,7 +496,6 @@ function useController(props) {
499
496
  }
500
497
  }
501
498
  !isArrayField && control.register(name);
502
- _previousNameRef.current = name;
503
499
  return () => {
504
500
  (isArrayField
505
501
  ? _shouldUnregisterField && !control._state.action
@@ -645,7 +641,7 @@ const useFormContext = () => React.useContext(HookFormContext);
645
641
  * ```
646
642
  */
647
643
  const FormProvider = (props) => {
648
- const { children, watch, getValues, getFieldState, setError, clearErrors, setValue, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, } = props;
644
+ const { children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, } = props;
649
645
  const memoizedValue = React.useMemo(() => ({
650
646
  watch,
651
647
  getValues,
@@ -653,6 +649,7 @@ const FormProvider = (props) => {
653
649
  setError,
654
650
  clearErrors,
655
651
  setValue,
652
+ setValues,
656
653
  trigger,
657
654
  formState,
658
655
  resetField,
@@ -676,6 +673,7 @@ const FormProvider = (props) => {
676
673
  setError,
677
674
  setFocus,
678
675
  setValue,
676
+ setValues,
679
677
  subscribe,
680
678
  trigger,
681
679
  unregister,
@@ -883,7 +881,12 @@ function baseGet(object, updatePath) {
883
881
  const length = updatePath.slice(0, -1).length;
884
882
  let index = 0;
885
883
  while (index < length) {
886
- object = isUndefined(object) ? index++ : object[updatePath[index++]];
884
+ if (isNullOrUndefined(object)) {
885
+ object = undefined;
886
+ break;
887
+ }
888
+ object = object[updatePath[index]];
889
+ index++;
887
890
  }
888
891
  return object;
889
892
  }
@@ -944,6 +947,29 @@ function markFieldsDirty(data, fields = {}) {
944
947
  }
945
948
  return fields;
946
949
  }
950
+ function pruneDirtyFields(value) {
951
+ if (value === false) {
952
+ return undefined;
953
+ }
954
+ if (value === true) {
955
+ return true;
956
+ }
957
+ if (Array.isArray(value)) {
958
+ const result = value.map((value) => pruneDirtyFields(value));
959
+ return (result.some((value) => value !== undefined) ? result : undefined);
960
+ }
961
+ if (isObject(value)) {
962
+ const result = {};
963
+ for (const key in value) {
964
+ const pruned = pruneDirtyFields(value[key]);
965
+ if (!isUndefined(pruned)) {
966
+ result[key] = pruned;
967
+ }
968
+ }
969
+ return (Object.keys(result).length ? result : undefined);
970
+ }
971
+ return undefined;
972
+ }
947
973
  function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
948
974
  if (!dirtyFieldsFromValues) {
949
975
  dirtyFieldsFromValues = markFieldsDirty(formValues);
@@ -963,7 +989,7 @@ function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
963
989
  dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
964
990
  }
965
991
  }
966
- return dirtyFieldsFromValues;
992
+ return pruneDirtyFields(dirtyFieldsFromValues) || {};
967
993
  }
968
994
 
969
995
  const defaultResult = {
@@ -1035,8 +1061,6 @@ function getFieldValue(_f) {
1035
1061
  return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f);
1036
1062
  }
1037
1063
 
1038
- var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
1039
-
1040
1064
  var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
1041
1065
  const fields = {};
1042
1066
  for (const name of fieldsNames) {
@@ -1161,7 +1185,8 @@ var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, is
1161
1185
  updateFormState(formStateData);
1162
1186
  const { name, ...formState } = formStateData;
1163
1187
  return (isEmptyObject(formState) ||
1164
- Object.keys(formState).length >= Object.keys(_proxyFormState).length ||
1188
+ (isRoot &&
1189
+ Object.keys(formState).length >= Object.keys(_proxyFormState).length) ||
1165
1190
  Object.keys(formState).find((key) => _proxyFormState[key] ===
1166
1191
  (!isRoot || VALIDATION_MODE.all)));
1167
1192
  };
@@ -1241,7 +1266,8 @@ var validateField = async (field, disabledFieldNames, formValues, validateAllFie
1241
1266
  isUndefined(inputValue)) ||
1242
1267
  (isHTMLElement(ref) && ref.value === '') ||
1243
1268
  inputValue === '' ||
1244
- (Array.isArray(inputValue) && !inputValue.length);
1269
+ (Array.isArray(inputValue) && !inputValue.length) ||
1270
+ (valueAsNumber && typeof inputValue === 'number' && isNaN(inputValue));
1245
1271
  const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
1246
1272
  const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
1247
1273
  const message = exceedMax ? maxLengthMessage : minLengthMessage;
@@ -1403,24 +1429,27 @@ const defaultOptions = {
1403
1429
  reValidateMode: VALIDATION_MODE.onChange,
1404
1430
  shouldFocusError: true,
1405
1431
  };
1432
+ const DEFAULT_FORM_STATE = {
1433
+ submitCount: 0,
1434
+ isDirty: false,
1435
+ isReady: false,
1436
+ isValidating: false,
1437
+ isSubmitted: false,
1438
+ isSubmitting: false,
1439
+ isSubmitSuccessful: false,
1440
+ isValid: false,
1441
+ touchedFields: {},
1442
+ dirtyFields: {},
1443
+ validatingFields: {},
1444
+ };
1406
1445
  function createFormControl(props = {}) {
1407
1446
  let _options = {
1408
1447
  ...defaultOptions,
1409
1448
  ...props,
1410
1449
  };
1411
1450
  let _formState = {
1412
- submitCount: 0,
1413
- isDirty: false,
1414
- isReady: false,
1451
+ ...cloneObject(DEFAULT_FORM_STATE),
1415
1452
  isLoading: isFunction(_options.defaultValues),
1416
- isValidating: false,
1417
- isSubmitted: false,
1418
- isSubmitting: false,
1419
- isSubmitSuccessful: false,
1420
- isValid: false,
1421
- touchedFields: {},
1422
- dirtyFields: {},
1423
- validatingFields: {},
1424
1453
  errors: _options.errors || {},
1425
1454
  disabled: _options.disabled || false,
1426
1455
  };
@@ -1517,10 +1546,8 @@ function createFormControl(props = {}) {
1517
1546
  });
1518
1547
  }
1519
1548
  };
1520
- const _updateDirtyFields = (name) => {
1521
- const fullDirtyFields = getDirtyFields(_defaultValues, _formValues);
1522
- const rootName = getNodeParentName(name);
1523
- set(_formState.dirtyFields, rootName, get(fullDirtyFields, rootName));
1549
+ const _updateDirtyFields = () => {
1550
+ _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1524
1551
  };
1525
1552
  const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
1526
1553
  if (args && method && !_options.disabled) {
@@ -1543,7 +1570,7 @@ function createFormControl(props = {}) {
1543
1570
  shouldSetValues && set(_formState.touchedFields, name, touchedFields);
1544
1571
  }
1545
1572
  if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
1546
- _updateDirtyFields(name);
1573
+ _updateDirtyFields();
1547
1574
  }
1548
1575
  _subjects.state.next({
1549
1576
  name,
@@ -1573,13 +1600,31 @@ function createFormControl(props = {}) {
1573
1600
  const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
1574
1601
  const field = get(_fields, name);
1575
1602
  if (field) {
1603
+ const wasUnsetInFormValues = isUndefined(get(_formValues, name));
1576
1604
  const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
1577
1605
  isUndefined(defaultValue) ||
1578
1606
  (ref && ref.defaultChecked) ||
1579
1607
  shouldSkipSetValueAs
1580
1608
  ? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
1581
1609
  : setFieldValue(name, defaultValue);
1582
- _state.mount && !_state.action && _setValid();
1610
+ if (_state.mount && !_state.action) {
1611
+ _setValid();
1612
+ // Re-registering a field after a prior unregister puts its key back
1613
+ // into _formValues, which can flip isDirty back to false (#13397).
1614
+ // Only run when we are currently dirty, otherwise an initial register
1615
+ // for a field with no defaultValue would flip isDirty to true. Reset
1616
+ // paths repopulate _formValues before re-register, so the key is
1617
+ // present then and this branch is skipped (preserves keepDirty).
1618
+ if (wasUnsetInFormValues &&
1619
+ _formState.isDirty &&
1620
+ (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty)) {
1621
+ const isDirty = _getDirty();
1622
+ if (!isDirty) {
1623
+ _formState.isDirty = false;
1624
+ _subjects.state.next({ ..._formState });
1625
+ }
1626
+ }
1627
+ }
1583
1628
  }
1584
1629
  };
1585
1630
  const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
@@ -1841,7 +1886,7 @@ function createFormControl(props = {}) {
1841
1886
  updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1842
1887
  options.shouldValidate && trigger(name);
1843
1888
  };
1844
- const setValues = (name, value, options) => {
1889
+ const setFieldValues = (name, value, options) => {
1845
1890
  for (const fieldKey in value) {
1846
1891
  if (!value.hasOwnProperty(fieldKey)) {
1847
1892
  return;
@@ -1853,7 +1898,7 @@ function createFormControl(props = {}) {
1853
1898
  isObject(fieldValue) ||
1854
1899
  (field && !field._f)) &&
1855
1900
  !isDateObject(fieldValue)
1856
- ? setValues(fieldName, fieldValue, options)
1901
+ ? setFieldValues(fieldName, fieldValue, options)
1857
1902
  : setFieldValue(fieldName, fieldValue, options);
1858
1903
  }
1859
1904
  };
@@ -1869,8 +1914,12 @@ function createFormControl(props = {}) {
1869
1914
  name,
1870
1915
  values: cloneObject(_formValues),
1871
1916
  });
1872
- if (options.shouldDirty) {
1873
- _updateDirtyFields(name);
1917
+ if ((_proxyFormState.isDirty ||
1918
+ _proxyFormState.dirtyFields ||
1919
+ _proxySubscribeFormState.isDirty ||
1920
+ _proxySubscribeFormState.dirtyFields) &&
1921
+ options.shouldDirty) {
1922
+ _updateDirtyFields();
1874
1923
  _subjects.state.next({
1875
1924
  name,
1876
1925
  dirtyFields: _formState.dirtyFields,
@@ -1885,23 +1934,28 @@ function createFormControl(props = {}) {
1885
1934
  setFieldValue(name, cloneValue, options);
1886
1935
  }
1887
1936
  else {
1888
- setValues(name, cloneValue, options);
1937
+ setFieldValues(name, cloneValue, options);
1889
1938
  }
1890
1939
  }
1891
1940
  if (!isValueUnchanged) {
1892
- if (isWatched(name, _names)) {
1893
- _subjects.state.next({
1894
- ..._formState,
1895
- name,
1896
- values: cloneObject(_formValues),
1897
- });
1898
- }
1899
- else {
1900
- _subjects.state.next({
1901
- name: _state.mount ? name : undefined,
1902
- values: cloneObject(_formValues),
1903
- });
1904
- }
1941
+ const watched = isWatched(name, _names);
1942
+ _subjects.state.next({
1943
+ ...(watched && _formState),
1944
+ name: _state.mount || watched ? name : undefined,
1945
+ values: cloneObject(_formValues),
1946
+ });
1947
+ }
1948
+ };
1949
+ const setValues = (formValues) => {
1950
+ const updatedFormValues = isFunction(formValues)
1951
+ ? formValues(_formValues)
1952
+ : formValues;
1953
+ if (!deepEqual(_formValues, updatedFormValues)) {
1954
+ _formValues = {
1955
+ ..._formValues,
1956
+ ...updatedFormValues,
1957
+ };
1958
+ _subjects.state.next({ ..._formState, values: _formValues });
1905
1959
  }
1906
1960
  };
1907
1961
  const onChange = async (event) => {
@@ -2601,6 +2655,7 @@ function createFormControl(props = {}) {
2601
2655
  handleSubmit,
2602
2656
  watch,
2603
2657
  setValue,
2658
+ setValues,
2604
2659
  getValues,
2605
2660
  reset,
2606
2661
  resetField,
@@ -2897,15 +2952,22 @@ function useFieldArray(props) {
2897
2952
  React.useEffect(() => {
2898
2953
  !get(control._formValues, name) && control._setFieldArray(name);
2899
2954
  return () => {
2955
+ const shouldKeepFieldArrayValues = !(control._options.shouldUnregister || shouldUnregister);
2900
2956
  const updateMounted = (name, value) => {
2901
2957
  const field = get(control._fields, name);
2902
2958
  if (field && field._f) {
2903
2959
  field._f.mount = value;
2904
2960
  }
2905
2961
  };
2906
- control._options.shouldUnregister || shouldUnregister
2907
- ? control.unregister(name)
2908
- : updateMounted(name, false);
2962
+ if (_actioned.current && shouldKeepFieldArrayValues) {
2963
+ control._subjects.state.next({
2964
+ name,
2965
+ values: cloneObject(control._formValues),
2966
+ });
2967
+ }
2968
+ shouldKeepFieldArrayValues
2969
+ ? updateMounted(name, false)
2970
+ : control.unregister(name);
2909
2971
  };
2910
2972
  }, [name, control, keyName, shouldUnregister]);
2911
2973
  return {
@@ -2956,25 +3018,15 @@ function useFieldArray(props) {
2956
3018
  function useForm(props = {}) {
2957
3019
  const _formControl = React.useRef(undefined);
2958
3020
  const _values = React.useRef(undefined);
2959
- const [formState, updateFormState] = React.useState({
2960
- isDirty: false,
2961
- isValidating: false,
3021
+ const [formState, updateFormState] = React.useState(() => ({
3022
+ ...cloneObject(DEFAULT_FORM_STATE),
2962
3023
  isLoading: isFunction(props.defaultValues),
2963
- isSubmitted: false,
2964
- isSubmitting: false,
2965
- isSubmitSuccessful: false,
2966
- isValid: false,
2967
- submitCount: 0,
2968
- dirtyFields: {},
2969
- touchedFields: {},
2970
- validatingFields: {},
2971
3024
  errors: props.errors || {},
2972
3025
  disabled: props.disabled || false,
2973
- isReady: false,
2974
3026
  defaultValues: isFunction(props.defaultValues)
2975
3027
  ? undefined
2976
3028
  : props.defaultValues,
2977
- });
3029
+ }));
2978
3030
  if (!_formControl.current) {
2979
3031
  if (props.formControl) {
2980
3032
  _formControl.current = {