@depup/react-hook-form 7.72.1-depup.0 → 7.83.0-depup.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 (297) hide show
  1. package/README.md +2 -2
  2. package/changes.json +1 -1
  3. package/dist/constants.d.ts +1 -1
  4. package/dist/constants.d.ts.map +1 -1
  5. package/dist/fieldArray.d.ts +36 -0
  6. package/dist/fieldArray.d.ts.map +1 -0
  7. package/dist/form.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 +1 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.esm.mjs +2271 -1847
  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/createFormControl.d.ts +13 -0
  17. package/dist/logic/createFormControl.d.ts.map +1 -1
  18. package/dist/logic/getDirtyFields.d.ts +3 -2
  19. package/dist/logic/getDirtyFields.d.ts.map +1 -1
  20. package/dist/logic/getEventValue.d.ts.map +1 -1
  21. package/dist/logic/getNodeParentName.d.ts.map +1 -1
  22. package/dist/logic/getProxyFormState.d.ts.map +1 -1
  23. package/dist/logic/getResolverOptions.d.ts +2 -2
  24. package/dist/logic/getValueAndMessage.d.ts +1 -4
  25. package/dist/logic/getValueAndMessage.d.ts.map +1 -1
  26. package/dist/logic/hasPromiseValidation.d.ts.map +1 -1
  27. package/dist/logic/hasValidation.d.ts +1 -1
  28. package/dist/logic/index.d.ts +2 -3
  29. package/dist/logic/index.d.ts.map +1 -1
  30. package/dist/logic/isWatched.d.ts.map +1 -1
  31. package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
  32. package/dist/logic/skipValidation.d.ts +1 -4
  33. package/dist/logic/skipValidation.d.ts.map +1 -1
  34. package/dist/logic/updateFieldArrayRootError.d.ts.map +1 -1
  35. package/dist/logic/validateField.d.ts.map +1 -1
  36. package/dist/react-server.esm.mjs +480 -179
  37. package/dist/react-server.esm.mjs.map +1 -1
  38. package/dist/types/errors.d.ts +2 -2
  39. package/dist/types/errors.d.ts.map +1 -1
  40. package/dist/types/fieldArray.d.ts +25 -1
  41. package/dist/types/fieldArray.d.ts.map +1 -1
  42. package/dist/types/form.d.ts +80 -56
  43. package/dist/types/form.d.ts.map +1 -1
  44. package/dist/types/path/common.d.ts +6 -0
  45. package/dist/types/path/common.d.ts.map +1 -1
  46. package/dist/types/path/eager.d.ts +15 -11
  47. package/dist/types/path/eager.d.ts.map +1 -1
  48. package/dist/types/utils.d.ts +4 -4
  49. package/dist/types/utils.d.ts.map +1 -1
  50. package/dist/types/validator.d.ts +1 -1
  51. package/dist/types/validator.d.ts.map +1 -1
  52. package/dist/types/watch.d.ts +1 -1
  53. package/dist/types/watch.d.ts.map +1 -1
  54. package/dist/useController.d.ts.map +1 -1
  55. package/dist/useFieldArray.d.ts.map +1 -1
  56. package/dist/useForm.d.ts.map +1 -1
  57. package/dist/useFormContext.d.ts +1 -1
  58. package/dist/useFormContext.d.ts.map +1 -1
  59. package/dist/useFormState.d.ts +2 -2
  60. package/dist/useFormState.d.ts.map +1 -1
  61. package/dist/useIsomorphicLayoutEffect.d.ts.map +1 -1
  62. package/dist/useWatch.d.ts +14 -14
  63. package/dist/utils/deepEqual.d.ts +1 -1
  64. package/dist/utils/deepEqual.d.ts.map +1 -1
  65. package/dist/utils/flatten.d.ts.map +1 -1
  66. package/dist/utils/get.d.ts.map +1 -1
  67. package/dist/utils/index.d.ts +2 -3
  68. package/dist/utils/index.d.ts.map +1 -1
  69. package/dist/utils/isKey.d.ts.map +1 -1
  70. package/dist/utils/set.d.ts.map +1 -1
  71. package/dist/utils/stringToPath.d.ts.map +1 -1
  72. package/dist/utils/unset.d.ts.map +1 -1
  73. package/dist/watch.d.ts +1 -1
  74. package/dist/watch.d.ts.map +1 -1
  75. package/package.json +29 -26
  76. package/dist/__tests__/controller.server.test.d.ts +0 -2
  77. package/dist/__tests__/controller.server.test.d.ts.map +0 -1
  78. package/dist/__tests__/controller.test.d.ts +0 -2
  79. package/dist/__tests__/controller.test.d.ts.map +0 -1
  80. package/dist/__tests__/form.test.d.ts +0 -2
  81. package/dist/__tests__/form.test.d.ts.map +0 -1
  82. package/dist/__tests__/formStateSubscribe.server.test.d.ts +0 -2
  83. package/dist/__tests__/formStateSubscribe.server.test.d.ts.map +0 -1
  84. package/dist/__tests__/formStateSubscribe.test.d.ts +0 -2
  85. package/dist/__tests__/formStateSubscribe.test.d.ts.map +0 -1
  86. package/dist/__tests__/isPlainObject.test.d.ts +0 -2
  87. package/dist/__tests__/isPlainObject.test.d.ts.map +0 -1
  88. package/dist/__tests__/logic/appendErrors.test.d.ts +0 -2
  89. package/dist/__tests__/logic/appendErrors.test.d.ts.map +0 -1
  90. package/dist/__tests__/logic/createFormControl.test.d.ts +0 -2
  91. package/dist/__tests__/logic/createFormControl.test.d.ts.map +0 -1
  92. package/dist/__tests__/logic/generateId.test.d.ts +0 -2
  93. package/dist/__tests__/logic/generateId.test.d.ts.map +0 -1
  94. package/dist/__tests__/logic/getCheckboxValue.test.d.ts +0 -2
  95. package/dist/__tests__/logic/getCheckboxValue.test.d.ts.map +0 -1
  96. package/dist/__tests__/logic/getDirtyFields.test.d.ts +0 -2
  97. package/dist/__tests__/logic/getDirtyFields.test.d.ts.map +0 -1
  98. package/dist/__tests__/logic/getEventValue.test.d.ts +0 -2
  99. package/dist/__tests__/logic/getEventValue.test.d.ts.map +0 -1
  100. package/dist/__tests__/logic/getFieldValue.test.d.ts +0 -2
  101. package/dist/__tests__/logic/getFieldValue.test.d.ts.map +0 -1
  102. package/dist/__tests__/logic/getFieldValueAs.test.d.ts +0 -2
  103. package/dist/__tests__/logic/getFieldValueAs.test.d.ts.map +0 -1
  104. package/dist/__tests__/logic/getFocusFieldName.test.d.ts +0 -2
  105. package/dist/__tests__/logic/getFocusFieldName.test.d.ts.map +0 -1
  106. package/dist/__tests__/logic/getNodeParentName.test.d.ts +0 -2
  107. package/dist/__tests__/logic/getNodeParentName.test.d.ts.map +0 -1
  108. package/dist/__tests__/logic/getRadioValue.test.d.ts +0 -2
  109. package/dist/__tests__/logic/getRadioValue.test.d.ts.map +0 -1
  110. package/dist/__tests__/logic/getResolverOptions.test.d.ts +0 -2
  111. package/dist/__tests__/logic/getResolverOptions.test.d.ts.map +0 -1
  112. package/dist/__tests__/logic/getRuleValue.test.d.ts +0 -2
  113. package/dist/__tests__/logic/getRuleValue.test.d.ts.map +0 -1
  114. package/dist/__tests__/logic/getValidateError.test.d.ts +0 -2
  115. package/dist/__tests__/logic/getValidateError.test.d.ts.map +0 -1
  116. package/dist/__tests__/logic/getValidationModes.test.d.ts +0 -2
  117. package/dist/__tests__/logic/getValidationModes.test.d.ts.map +0 -1
  118. package/dist/__tests__/logic/getValueAndMessage.test.d.ts +0 -2
  119. package/dist/__tests__/logic/getValueAndMessage.test.d.ts.map +0 -1
  120. package/dist/__tests__/logic/hasPromiseValidation.test.d.ts +0 -2
  121. package/dist/__tests__/logic/hasPromiseValidation.test.d.ts.map +0 -1
  122. package/dist/__tests__/logic/hasValidation.test.d.ts +0 -2
  123. package/dist/__tests__/logic/hasValidation.test.d.ts.map +0 -1
  124. package/dist/__tests__/logic/isNameInFieldArray.test.d.ts +0 -2
  125. package/dist/__tests__/logic/isNameInFieldArray.test.d.ts.map +0 -1
  126. package/dist/__tests__/logic/isWatched.test.d.ts +0 -2
  127. package/dist/__tests__/logic/isWatched.test.d.ts.map +0 -1
  128. package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts +0 -2
  129. package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts.map +0 -1
  130. package/dist/__tests__/logic/schemaErrorLookup.test.d.ts +0 -2
  131. package/dist/__tests__/logic/schemaErrorLookup.test.d.ts.map +0 -1
  132. package/dist/__tests__/logic/shouldRenderFormState.test.d.ts +0 -2
  133. package/dist/__tests__/logic/shouldRenderFormState.test.d.ts.map +0 -1
  134. package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts +0 -2
  135. package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts.map +0 -1
  136. package/dist/__tests__/logic/skipValidation.test.d.ts +0 -2
  137. package/dist/__tests__/logic/skipValidation.test.d.ts.map +0 -1
  138. package/dist/__tests__/logic/unsetEmptyArray.test.d.ts +0 -2
  139. package/dist/__tests__/logic/unsetEmptyArray.test.d.ts.map +0 -1
  140. package/dist/__tests__/logic/validateField.test.d.ts +0 -2
  141. package/dist/__tests__/logic/validateField.test.d.ts.map +0 -1
  142. package/dist/__tests__/type.test.d.ts +0 -2
  143. package/dist/__tests__/type.test.d.ts.map +0 -1
  144. package/dist/__tests__/useController.test.d.ts +0 -2
  145. package/dist/__tests__/useController.test.d.ts.map +0 -1
  146. package/dist/__tests__/useFieldArray/append.test.d.ts +0 -2
  147. package/dist/__tests__/useFieldArray/append.test.d.ts.map +0 -1
  148. package/dist/__tests__/useFieldArray/dirtyFields.test.d.ts +0 -2
  149. package/dist/__tests__/useFieldArray/dirtyFields.test.d.ts.map +0 -1
  150. package/dist/__tests__/useFieldArray/focus.test.d.ts +0 -2
  151. package/dist/__tests__/useFieldArray/focus.test.d.ts.map +0 -1
  152. package/dist/__tests__/useFieldArray/insert.test.d.ts +0 -2
  153. package/dist/__tests__/useFieldArray/insert.test.d.ts.map +0 -1
  154. package/dist/__tests__/useFieldArray/move.test.d.ts +0 -2
  155. package/dist/__tests__/useFieldArray/move.test.d.ts.map +0 -1
  156. package/dist/__tests__/useFieldArray/prepend.test.d.ts +0 -2
  157. package/dist/__tests__/useFieldArray/prepend.test.d.ts.map +0 -1
  158. package/dist/__tests__/useFieldArray/remove.test.d.ts +0 -2
  159. package/dist/__tests__/useFieldArray/remove.test.d.ts.map +0 -1
  160. package/dist/__tests__/useFieldArray/replace.test.d.ts +0 -2
  161. package/dist/__tests__/useFieldArray/replace.test.d.ts.map +0 -1
  162. package/dist/__tests__/useFieldArray/swap.test.d.ts +0 -2
  163. package/dist/__tests__/useFieldArray/swap.test.d.ts.map +0 -1
  164. package/dist/__tests__/useFieldArray/update.test.d.ts +0 -2
  165. package/dist/__tests__/useFieldArray/update.test.d.ts.map +0 -1
  166. package/dist/__tests__/useFieldArray.test.d.ts +0 -2
  167. package/dist/__tests__/useFieldArray.test.d.ts.map +0 -1
  168. package/dist/__tests__/useForm/clearErrors.test.d.ts +0 -2
  169. package/dist/__tests__/useForm/clearErrors.test.d.ts.map +0 -1
  170. package/dist/__tests__/useForm/formState.test.d.ts +0 -2
  171. package/dist/__tests__/useForm/formState.test.d.ts.map +0 -1
  172. package/dist/__tests__/useForm/getFieldState.test.d.ts +0 -2
  173. package/dist/__tests__/useForm/getFieldState.test.d.ts.map +0 -1
  174. package/dist/__tests__/useForm/getValues.test.d.ts +0 -2
  175. package/dist/__tests__/useForm/getValues.test.d.ts.map +0 -1
  176. package/dist/__tests__/useForm/handleSubmit.test.d.ts +0 -2
  177. package/dist/__tests__/useForm/handleSubmit.test.d.ts.map +0 -1
  178. package/dist/__tests__/useForm/register.test.d.ts +0 -2
  179. package/dist/__tests__/useForm/register.test.d.ts.map +0 -1
  180. package/dist/__tests__/useForm/reset.test.d.ts +0 -2
  181. package/dist/__tests__/useForm/reset.test.d.ts.map +0 -1
  182. package/dist/__tests__/useForm/resetField.test.d.ts +0 -2
  183. package/dist/__tests__/useForm/resetField.test.d.ts.map +0 -1
  184. package/dist/__tests__/useForm/resolver.test.d.ts +0 -2
  185. package/dist/__tests__/useForm/resolver.test.d.ts.map +0 -1
  186. package/dist/__tests__/useForm/setError.test.d.ts +0 -2
  187. package/dist/__tests__/useForm/setError.test.d.ts.map +0 -1
  188. package/dist/__tests__/useForm/setFocus.test.d.ts +0 -2
  189. package/dist/__tests__/useForm/setFocus.test.d.ts.map +0 -1
  190. package/dist/__tests__/useForm/setValue.test.d.ts +0 -2
  191. package/dist/__tests__/useForm/setValue.test.d.ts.map +0 -1
  192. package/dist/__tests__/useForm/subscribe.test.d.ts +0 -2
  193. package/dist/__tests__/useForm/subscribe.test.d.ts.map +0 -1
  194. package/dist/__tests__/useForm/trigger.test.d.ts +0 -2
  195. package/dist/__tests__/useForm/trigger.test.d.ts.map +0 -1
  196. package/dist/__tests__/useForm/unregister.test.d.ts +0 -2
  197. package/dist/__tests__/useForm/unregister.test.d.ts.map +0 -1
  198. package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts +0 -2
  199. package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts.map +0 -1
  200. package/dist/__tests__/useForm/watch.test.d.ts +0 -2
  201. package/dist/__tests__/useForm/watch.test.d.ts.map +0 -1
  202. package/dist/__tests__/useForm.server.test.d.ts +0 -2
  203. package/dist/__tests__/useForm.server.test.d.ts.map +0 -1
  204. package/dist/__tests__/useForm.test.d.ts +0 -2
  205. package/dist/__tests__/useForm.test.d.ts.map +0 -1
  206. package/dist/__tests__/useFormContext.server.test.d.ts +0 -2
  207. package/dist/__tests__/useFormContext.server.test.d.ts.map +0 -1
  208. package/dist/__tests__/useFormContext.test.d.ts +0 -2
  209. package/dist/__tests__/useFormContext.test.d.ts.map +0 -1
  210. package/dist/__tests__/useFormState.test.d.ts +0 -2
  211. package/dist/__tests__/useFormState.test.d.ts.map +0 -1
  212. package/dist/__tests__/useWatch.test.d.ts +0 -2
  213. package/dist/__tests__/useWatch.test.d.ts.map +0 -1
  214. package/dist/__tests__/utils/append.test.d.ts +0 -2
  215. package/dist/__tests__/utils/append.test.d.ts.map +0 -1
  216. package/dist/__tests__/utils/cloneObject.test.d.ts +0 -2
  217. package/dist/__tests__/utils/cloneObject.test.d.ts.map +0 -1
  218. package/dist/__tests__/utils/compact.test.d.ts +0 -2
  219. package/dist/__tests__/utils/compact.test.d.ts.map +0 -1
  220. package/dist/__tests__/utils/convertToArrayPayload.test.d.ts +0 -2
  221. package/dist/__tests__/utils/convertToArrayPayload.test.d.ts.map +0 -1
  222. package/dist/__tests__/utils/createSubject.test.d.ts +0 -2
  223. package/dist/__tests__/utils/createSubject.test.d.ts.map +0 -1
  224. package/dist/__tests__/utils/deepEqual.test.d.ts +0 -2
  225. package/dist/__tests__/utils/deepEqual.test.d.ts.map +0 -1
  226. package/dist/__tests__/utils/deepMerge.test.d.ts +0 -2
  227. package/dist/__tests__/utils/deepMerge.test.d.ts.map +0 -1
  228. package/dist/__tests__/utils/extractFormValues.test.d.ts +0 -2
  229. package/dist/__tests__/utils/extractFormValues.test.d.ts.map +0 -1
  230. package/dist/__tests__/utils/fillEmptyArray.test.d.ts +0 -2
  231. package/dist/__tests__/utils/fillEmptyArray.test.d.ts.map +0 -1
  232. package/dist/__tests__/utils/flatten.test.d.ts +0 -2
  233. package/dist/__tests__/utils/flatten.test.d.ts.map +0 -1
  234. package/dist/__tests__/utils/get.test.d.ts +0 -2
  235. package/dist/__tests__/utils/get.test.d.ts.map +0 -1
  236. package/dist/__tests__/utils/insert.test.d.ts +0 -2
  237. package/dist/__tests__/utils/insert.test.d.ts.map +0 -1
  238. package/dist/__tests__/utils/isBoolean.test.d.ts +0 -2
  239. package/dist/__tests__/utils/isBoolean.test.d.ts.map +0 -1
  240. package/dist/__tests__/utils/isCheckBoxInput.test.d.ts +0 -2
  241. package/dist/__tests__/utils/isCheckBoxInput.test.d.ts.map +0 -1
  242. package/dist/__tests__/utils/isEmptyObject.test.d.ts +0 -2
  243. package/dist/__tests__/utils/isEmptyObject.test.d.ts.map +0 -1
  244. package/dist/__tests__/utils/isFileInput.test.d.ts +0 -2
  245. package/dist/__tests__/utils/isFileInput.test.d.ts.map +0 -1
  246. package/dist/__tests__/utils/isFunction.test.d.ts +0 -2
  247. package/dist/__tests__/utils/isFunction.test.d.ts.map +0 -1
  248. package/dist/__tests__/utils/isHTMLElement.test.d.ts +0 -2
  249. package/dist/__tests__/utils/isHTMLElement.test.d.ts.map +0 -1
  250. package/dist/__tests__/utils/isKey.test.d.ts +0 -2
  251. package/dist/__tests__/utils/isKey.test.d.ts.map +0 -1
  252. package/dist/__tests__/utils/isMultipleSelect.test.d.ts +0 -2
  253. package/dist/__tests__/utils/isMultipleSelect.test.d.ts.map +0 -1
  254. package/dist/__tests__/utils/isNullOrUndefined.test.d.ts +0 -2
  255. package/dist/__tests__/utils/isNullOrUndefined.test.d.ts.map +0 -1
  256. package/dist/__tests__/utils/isObject.test.d.ts +0 -2
  257. package/dist/__tests__/utils/isObject.test.d.ts.map +0 -1
  258. package/dist/__tests__/utils/isPrimitive.test.d.ts +0 -2
  259. package/dist/__tests__/utils/isPrimitive.test.d.ts.map +0 -1
  260. package/dist/__tests__/utils/isRadioInput.test.d.ts +0 -2
  261. package/dist/__tests__/utils/isRadioInput.test.d.ts.map +0 -1
  262. package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts +0 -2
  263. package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts.map +0 -1
  264. package/dist/__tests__/utils/isRegex.test.d.ts +0 -2
  265. package/dist/__tests__/utils/isRegex.test.d.ts.map +0 -1
  266. package/dist/__tests__/utils/isString.test.d.ts +0 -2
  267. package/dist/__tests__/utils/isString.test.d.ts.map +0 -1
  268. package/dist/__tests__/utils/isUndefined.test.d.ts +0 -2
  269. package/dist/__tests__/utils/isUndefined.test.d.ts.map +0 -1
  270. package/dist/__tests__/utils/live.test.d.ts +0 -2
  271. package/dist/__tests__/utils/live.test.d.ts.map +0 -1
  272. package/dist/__tests__/utils/move.test.d.ts +0 -2
  273. package/dist/__tests__/utils/move.test.d.ts.map +0 -1
  274. package/dist/__tests__/utils/noop.test.d.ts +0 -2
  275. package/dist/__tests__/utils/noop.test.d.ts.map +0 -1
  276. package/dist/__tests__/utils/objectHasFunction.test.d.ts +0 -2
  277. package/dist/__tests__/utils/objectHasFunction.test.d.ts.map +0 -1
  278. package/dist/__tests__/utils/prepend.test.d.ts +0 -2
  279. package/dist/__tests__/utils/prepend.test.d.ts.map +0 -1
  280. package/dist/__tests__/utils/remove.test.d.ts +0 -2
  281. package/dist/__tests__/utils/remove.test.d.ts.map +0 -1
  282. package/dist/__tests__/utils/set.test.d.ts +0 -2
  283. package/dist/__tests__/utils/set.test.d.ts.map +0 -1
  284. package/dist/__tests__/utils/stringToPath.test.d.ts +0 -2
  285. package/dist/__tests__/utils/stringToPath.test.d.ts.map +0 -1
  286. package/dist/__tests__/utils/swap.test.d.ts +0 -2
  287. package/dist/__tests__/utils/swap.test.d.ts.map +0 -1
  288. package/dist/__tests__/utils/unset.test.d.ts +0 -2
  289. package/dist/__tests__/utils/unset.test.d.ts.map +0 -1
  290. package/dist/__tests__/utils/update.test.d.ts +0 -2
  291. package/dist/__tests__/utils/update.test.d.ts.map +0 -1
  292. package/dist/__tests__/utils/validationModeChecker.test.d.ts +0 -2
  293. package/dist/__tests__/utils/validationModeChecker.test.d.ts.map +0 -1
  294. package/dist/__tests__/watch.server.test.d.ts +0 -2
  295. package/dist/__tests__/watch.server.test.d.ts.map +0 -1
  296. package/dist/__tests__/watch.test.d.ts +0 -2
  297. package/dist/__tests__/watch.test.d.ts.map +0 -1
@@ -31,8 +31,8 @@ const INPUT_VALIDATION_RULES = {
31
31
  required: 'required',
32
32
  validate: 'validate',
33
33
  };
34
- const FORM_ERROR_TYPE = 'form';
35
34
  const ROOT_ERROR_TYPE = 'root';
35
+ const PROTOTYPE_KEYWORDS = ['__proto__', 'constructor', 'prototype'];
36
36
 
37
37
  var isDateObject = (value) => value instanceof Date;
38
38
 
@@ -108,7 +108,11 @@ var createSubject = () => {
108
108
 
109
109
  var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
110
110
 
111
- function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
111
+ const isEmptyObjectWithCustomPrototype = (object, keys) => keys.length === 0 && !Array.isArray(object) && !isPlainObject(object);
112
+ function deepEqual(object1, object2, visited = new WeakMap()) {
113
+ if (object1 === object2) {
114
+ return true;
115
+ }
112
116
  if (isPrimitive(object1) || isPrimitive(object2)) {
113
117
  return Object.is(object1, object2);
114
118
  }
@@ -120,14 +124,28 @@ function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
120
124
  if (keys1.length !== keys2.length) {
121
125
  return false;
122
126
  }
123
- if (_internal_visited.has(object1) || _internal_visited.has(object2)) {
127
+ if (isEmptyObjectWithCustomPrototype(object1, keys1) ||
128
+ isEmptyObjectWithCustomPrototype(object2, keys2)) {
129
+ return Object.is(object1, object2);
130
+ }
131
+ if (!keys1.length && Array.isArray(object1) !== Array.isArray(object2)) {
132
+ return false;
133
+ }
134
+ const visitedPairs = visited.get(object1);
135
+ if (visitedPairs && visitedPairs.has(object2)) {
124
136
  return true;
125
137
  }
126
- _internal_visited.add(object1);
127
- _internal_visited.add(object2);
138
+ if (visitedPairs) {
139
+ visitedPairs.add(object2);
140
+ }
141
+ else {
142
+ const ws = new WeakSet();
143
+ ws.add(object2);
144
+ visited.set(object1, ws);
145
+ }
128
146
  for (const key of keys1) {
129
147
  const val1 = object1[key];
130
- if (!keys2.includes(key)) {
148
+ if (!(key in object2)) {
131
149
  return false;
132
150
  }
133
151
  if (key !== 'ref') {
@@ -135,7 +153,7 @@ function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
135
153
  if ((isDateObject(val1) && isDateObject(val2)) ||
136
154
  ((isObject(val1) || Array.isArray(val1)) &&
137
155
  (isObject(val2) || Array.isArray(val2)))
138
- ? !deepEqual(val1, val2, _internal_visited)
156
+ ? !deepEqual(val1, val2, visited)
139
157
  : !Object.is(val1, val2)) {
140
158
  return false;
141
159
  }
@@ -164,17 +182,43 @@ function extractFormValues(fieldsState, formValues) {
164
182
  return values;
165
183
  }
166
184
 
167
- var isKey = (value) => /^\w*$/.test(value);
185
+ const flatten = (obj) => {
186
+ const output = {};
187
+ for (const key of Object.keys(obj)) {
188
+ if (isObjectType(obj[key]) &&
189
+ obj[key] !== null &&
190
+ !isDateObject(obj[key])) {
191
+ const nested = flatten(obj[key]);
192
+ for (const nestedKey of Object.keys(nested)) {
193
+ output[`${key}.${nestedKey}`] = nested[nestedKey];
194
+ }
195
+ }
196
+ else {
197
+ output[key] = obj[key];
198
+ }
199
+ }
200
+ return output;
201
+ };
202
+
203
+ const IS_KEY_RE = /^\w*$/;
204
+ var isKey = (value) => IS_KEY_RE.test(value);
168
205
 
169
206
  var isUndefined = (val) => val === undefined;
170
207
 
171
- var stringToPath = (input) => compact(input.replace(/["|']|\]/g, '').split(/\.|\[/));
208
+ const FIELD_PATH_RE = /[.[\]'"]/;
209
+ var stringToPath = (input) => input.split(FIELD_PATH_RE).filter(Boolean);
172
210
 
173
211
  var get = (object, path, defaultValue) => {
174
212
  if (!path || !isObject(object)) {
175
213
  return defaultValue;
176
214
  }
177
- const result = (isKey(path) ? [path] : stringToPath(path)).reduce((result, key) => isNullOrUndefined(result) ? result : result[key], object);
215
+ const paths = isKey(path) ? [path] : stringToPath(path);
216
+ if (paths.some((key) => PROTOTYPE_KEYWORDS.includes(key))) {
217
+ return defaultValue;
218
+ }
219
+ const result = paths.reduce((result, key) => {
220
+ return isNullOrUndefined(result) ? undefined : result[key];
221
+ }, object);
178
222
  return isUndefined(result) || result === object
179
223
  ? isUndefined(object[path])
180
224
  ? defaultValue
@@ -228,7 +272,7 @@ var set = (object, path, value) => {
228
272
  ? []
229
273
  : {};
230
274
  }
231
- if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
275
+ if (PROTOTYPE_KEYWORDS.includes(key)) {
232
276
  return;
233
277
  }
234
278
  object[key] = newValue;
@@ -240,7 +284,12 @@ function baseGet(object, updatePath) {
240
284
  const length = updatePath.slice(0, -1).length;
241
285
  let index = 0;
242
286
  while (index < length) {
243
- object = isUndefined(object) ? index++ : object[updatePath[index++]];
287
+ if (isNullOrUndefined(object)) {
288
+ object = undefined;
289
+ break;
290
+ }
291
+ object = object[updatePath[index]];
292
+ index++;
244
293
  }
245
294
  return object;
246
295
  }
@@ -253,11 +302,18 @@ function isEmptyArray(obj) {
253
302
  return true;
254
303
  }
255
304
  function unset(object, path) {
305
+ if (isString(path) && Object.prototype.hasOwnProperty.call(object, path)) {
306
+ delete object[path];
307
+ return object;
308
+ }
256
309
  const paths = Array.isArray(path)
257
310
  ? path
258
311
  : isKey(path)
259
312
  ? [path]
260
313
  : stringToPath(path);
314
+ if (paths.some((segment) => PROTOTYPE_KEYWORDS.includes(String(segment)))) {
315
+ return object;
316
+ }
261
317
  const childObject = paths.length === 1 ? object : baseGet(object, paths);
262
318
  const index = paths.length - 1;
263
319
  const key = paths[index];
@@ -297,12 +353,33 @@ var objectHasFunction = (data) => {
297
353
  function isTraversable(value) {
298
354
  return Array.isArray(value) || (isObject(value) && !objectHasFunction(value));
299
355
  }
300
- function markFieldsDirty(data, fields = {}) {
356
+ function isRegisteredLeaf(fieldRef) {
357
+ return !!(fieldRef && '_f' in fieldRef);
358
+ }
359
+ function isEmptyDirtyContainer(value) {
360
+ return Array.isArray(value)
361
+ ? !value.some((item) => !isUndefined(item))
362
+ : !Object.keys(value).length;
363
+ }
364
+ function clearDirtyField(container, key) {
365
+ if (Array.isArray(container)) {
366
+ container[key] = undefined;
367
+ }
368
+ else {
369
+ delete container[key];
370
+ }
371
+ }
372
+ function markFieldsDirty(data, fields = {}, fieldRefs) {
301
373
  for (const key in data) {
302
374
  const value = data[key];
303
- if (isTraversable(value)) {
375
+ const fieldRef = fieldRefs && fieldRefs[key];
376
+ if (isTraversable(value) &&
377
+ (!Array.isArray(value) || !isRegisteredLeaf(fieldRef))) {
304
378
  fields[key] = Array.isArray(value) ? [] : {};
305
- markFieldsDirty(value, fields[key]);
379
+ markFieldsDirty(value, fields[key], fieldRef);
380
+ if (isEmptyDirtyContainer(fields[key])) {
381
+ clearDirtyField(fields, key);
382
+ }
306
383
  }
307
384
  else if (!isUndefined(value)) {
308
385
  fields[key] = true;
@@ -310,23 +387,30 @@ function markFieldsDirty(data, fields = {}) {
310
387
  }
311
388
  return fields;
312
389
  }
313
- function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
390
+ function getDirtyFields(data, formValues, dirtyFieldsFromValues, fieldRefs) {
314
391
  if (!dirtyFieldsFromValues) {
315
- dirtyFieldsFromValues = markFieldsDirty(formValues);
392
+ dirtyFieldsFromValues = markFieldsDirty(formValues, {}, fieldRefs);
316
393
  }
317
394
  for (const key in data) {
318
395
  const value = data[key];
319
- if (isTraversable(value)) {
396
+ const fieldRef = fieldRefs && fieldRefs[key];
397
+ if (isTraversable(value) &&
398
+ (!Array.isArray(value) || !isRegisteredLeaf(fieldRef))) {
320
399
  if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) {
321
- dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {});
400
+ dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {}, fieldRef);
322
401
  }
323
402
  else {
324
- getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
403
+ getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key], fieldRef);
404
+ }
405
+ if (isEmptyDirtyContainer(dirtyFieldsFromValues[key])) {
406
+ clearDirtyField(dirtyFieldsFromValues, key);
325
407
  }
326
408
  }
409
+ else if (deepEqual(value, formValues[key])) {
410
+ clearDirtyField(dirtyFieldsFromValues, key);
411
+ }
327
412
  else {
328
- const formValue = formValues[key];
329
- dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
413
+ dirtyFieldsFromValues[key] = true;
330
414
  }
331
415
  }
332
416
  return dirtyFieldsFromValues;
@@ -335,7 +419,9 @@ function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
335
419
  var getEventValue = (event) => isObject(event) && event.target
336
420
  ? isCheckBoxInput(event.target)
337
421
  ? event.target.checked
338
- : event.target.value
422
+ : isFileInput(event.target)
423
+ ? event.target.files
424
+ : event.target.value
339
425
  : event;
340
426
 
341
427
  const defaultResult = {
@@ -407,8 +493,6 @@ function getFieldValue(_f) {
407
493
  return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f);
408
494
  }
409
495
 
410
- var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
411
-
412
496
  var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
413
497
  const fields = {};
414
498
  for (const name of fieldsNames) {
@@ -444,12 +528,22 @@ var getValidationModes = (mode) => ({
444
528
  });
445
529
 
446
530
  const ASYNC_FUNCTION = 'AsyncFunction';
447
- var hasPromiseValidation = (fieldReference) => !!fieldReference &&
448
- !!fieldReference.validate &&
449
- !!((isFunction(fieldReference.validate) &&
450
- fieldReference.validate.constructor.name === ASYNC_FUNCTION) ||
451
- (isObject(fieldReference.validate) &&
452
- Object.values(fieldReference.validate).find((validateFunction) => validateFunction.constructor.name === ASYNC_FUNCTION)));
531
+ var hasPromiseValidation = (fieldReference) => {
532
+ if (!fieldReference || !fieldReference.validate)
533
+ return false;
534
+ if (isFunction(fieldReference.validate)) {
535
+ return fieldReference.validate.constructor.name === ASYNC_FUNCTION;
536
+ }
537
+ if (isObject(fieldReference.validate)) {
538
+ for (const key in fieldReference.validate) {
539
+ if (fieldReference.validate[key].constructor
540
+ .name === ASYNC_FUNCTION) {
541
+ return true;
542
+ }
543
+ }
544
+ }
545
+ return false;
546
+ };
453
547
 
454
548
  var hasValidation = (options) => options.mount &&
455
549
  (options.required ||
@@ -464,11 +558,17 @@ var isNameInFieldArray = (names, name) => name
464
558
  .split('.')
465
559
  .some((part, index, arr) => !isNaN(Number(part)) && names.has(arr.slice(0, index).join('.')));
466
560
 
467
- var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
468
- (_names.watchAll ||
469
- _names.watch.has(name) ||
470
- [..._names.watch].some((watchName) => name.startsWith(watchName) &&
471
- /^\.\w+/.test(name.slice(watchName.length))));
561
+ var isWatched = (name, _names, isBlurEvent) => {
562
+ if (isBlurEvent)
563
+ return false;
564
+ if (_names.watchAll || _names.watch.has(name))
565
+ return true;
566
+ for (const watchName of _names.watch) {
567
+ if (name.startsWith(watchName) && name.charAt(watchName.length) === '.')
568
+ return true;
569
+ }
570
+ return false;
571
+ };
472
572
 
473
573
  const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
474
574
  for (const key of fieldsNames || Object.keys(fields)) {
@@ -536,9 +636,10 @@ function schemaErrorLookup(errors, _fields, name) {
536
636
  var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
537
637
  updateFormState(formStateData);
538
638
  const { name, ...formState } = formStateData;
539
- return (isEmptyObject(formState) ||
540
- Object.keys(formState).length >= Object.keys(_proxyFormState).length ||
541
- Object.keys(formState).find((key) => _proxyFormState[key] ===
639
+ const keys = Object.keys(formState);
640
+ return (!keys.length ||
641
+ (isRoot && keys.length >= Object.keys(_proxyFormState).length) ||
642
+ keys.find((key) => _proxyFormState[key] ===
542
643
  (!isRoot || VALIDATION_MODE.all)));
543
644
  };
544
645
 
@@ -547,7 +648,7 @@ var shouldSubscribeByName = (name, signalName, exact) => !name ||
547
648
  name === signalName ||
548
649
  convertToArrayPayload(name).some((currentName) => currentName &&
549
650
  (exact
550
- ? currentName === signalName
651
+ ? currentName === signalName || currentName.startsWith(signalName + '.')
551
652
  : currentName.startsWith(signalName) ||
552
653
  signalName.startsWith(currentName)));
553
654
 
@@ -570,7 +671,8 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
570
671
  var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
571
672
 
572
673
  var updateFieldArrayRootError = (errors, error, name) => {
573
- const fieldArrayErrors = convertToArrayPayload(get(errors, name));
674
+ const existingErrors = get(errors, name);
675
+ const fieldArrayErrors = Array.isArray(existingErrors) ? existingErrors : [];
574
676
  set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
575
677
  set(errors, name, fieldArrayErrors);
576
678
  return errors;
@@ -604,7 +706,13 @@ var validateField = async (field, disabledFieldNames, formValues, validateAllFie
604
706
  const inputRef = refs ? refs[0] : ref;
605
707
  const setCustomValidity = (message) => {
606
708
  if (shouldUseNativeValidation && inputRef.reportValidity) {
607
- inputRef.setCustomValidity(isBoolean(message) ? '' : message || '');
709
+ const validityMessage = isBoolean(message) ? '' : message || '';
710
+ if (refs) {
711
+ refs.forEach((ref) => ref.setCustomValidity(validityMessage));
712
+ }
713
+ else {
714
+ inputRef.setCustomValidity(validityMessage);
715
+ }
608
716
  inputRef.reportValidity();
609
717
  }
610
718
  };
@@ -779,24 +887,36 @@ const defaultOptions = {
779
887
  reValidateMode: VALIDATION_MODE.onChange,
780
888
  shouldFocusError: true,
781
889
  };
890
+ const FORM_ERROR_TYPE = 'form';
891
+ const updateDirtyFields = (dirtyFields, nextDirtyFields) => {
892
+ for (const key in dirtyFields) {
893
+ if (!(key in nextDirtyFields)) {
894
+ delete dirtyFields[key];
895
+ }
896
+ }
897
+ Object.assign(dirtyFields, nextDirtyFields);
898
+ };
899
+ const DEFAULT_FORM_STATE = {
900
+ submitCount: 0,
901
+ isDirty: false,
902
+ isReady: false,
903
+ isValidating: false,
904
+ isSubmitted: false,
905
+ isSubmitting: false,
906
+ isSubmitSuccessful: false,
907
+ isValid: false,
908
+ touchedFields: {},
909
+ dirtyFields: {},
910
+ validatingFields: {},
911
+ };
782
912
  function createFormControl(props = {}) {
783
913
  let _options = {
784
914
  ...defaultOptions,
785
915
  ...props,
786
916
  };
787
917
  let _formState = {
788
- submitCount: 0,
789
- isDirty: false,
790
- isReady: false,
918
+ ...cloneObject(DEFAULT_FORM_STATE),
791
919
  isLoading: isFunction(_options.defaultValues),
792
- isValidating: false,
793
- isSubmitted: false,
794
- isSubmitting: false,
795
- isSubmitSuccessful: false,
796
- isValid: false,
797
- touchedFields: {},
798
- dirtyFields: {},
799
- validatingFields: {},
800
920
  errors: _options.errors || {},
801
921
  disabled: _options.disabled || false,
802
922
  };
@@ -821,8 +941,11 @@ function createFormControl(props = {}) {
821
941
  watch: new Set(),
822
942
  registerName: new Set(),
823
943
  };
824
- let delayErrorCallback;
825
- let timer = 0;
944
+ const delayErrorCallbacks = {};
945
+ const timers = {};
946
+ let _valuesSubscriberCount = 0;
947
+ let _validationModeBeforeSubmit = getValidationModes(_options.mode);
948
+ let _validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
826
949
  const defaultProxyFormState = {
827
950
  isDirty: false,
828
951
  dirtyFields: false,
@@ -842,10 +965,11 @@ function createFormControl(props = {}) {
842
965
  array: createSubject(),
843
966
  state: createSubject(),
844
967
  };
968
+ let _setValidCallId = 0;
845
969
  const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
846
- const debounce = (callback) => (wait) => {
847
- clearTimeout(timer);
848
- timer = setTimeout(callback, wait);
970
+ const debounce = (name, callback) => (wait) => {
971
+ clearTimeout(timers[name]);
972
+ timers[name] = setTimeout(callback, wait);
849
973
  };
850
974
  const _setValid = async (shouldUpdateValid) => {
851
975
  if (_state.keepIsValid) {
@@ -855,10 +979,11 @@ function createFormControl(props = {}) {
855
979
  (_proxyFormState.isValid ||
856
980
  _proxySubscribeFormState.isValid ||
857
981
  shouldUpdateValid)) {
982
+ const callId = ++_setValidCallId;
858
983
  let isValid;
859
984
  if (_options.resolver) {
860
985
  isValid = isEmptyObject((await _runSchema()).errors);
861
- _updateIsValidating();
986
+ callId === _setValidCallId && _updateIsValidating();
862
987
  }
863
988
  else {
864
989
  isValid = await executeBuiltInValidation({
@@ -867,7 +992,7 @@ function createFormControl(props = {}) {
867
992
  eventType: EVENTS.VALID,
868
993
  });
869
994
  }
870
- if (isValid !== _formState.isValid) {
995
+ if (callId === _setValidCallId && isValid !== _formState.isValid) {
871
996
  _subjects.state.next({
872
997
  isValid,
873
998
  });
@@ -893,10 +1018,8 @@ function createFormControl(props = {}) {
893
1018
  });
894
1019
  }
895
1020
  };
896
- const _updateDirtyFields = (name) => {
897
- const fullDirtyFields = getDirtyFields(_defaultValues, _formValues);
898
- const rootName = getNodeParentName(name);
899
- set(_formState.dirtyFields, rootName, get(fullDirtyFields, rootName));
1021
+ const _updateDirtyFields = () => {
1022
+ _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
900
1023
  };
901
1024
  const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
902
1025
  if (args && method && !_options.disabled) {
@@ -919,7 +1042,7 @@ function createFormControl(props = {}) {
919
1042
  shouldSetValues && set(_formState.touchedFields, name, touchedFields);
920
1043
  }
921
1044
  if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
922
- _updateDirtyFields(name);
1045
+ _updateDirtyFields();
923
1046
  }
924
1047
  _subjects.state.next({
925
1048
  name,
@@ -935,6 +1058,7 @@ function createFormControl(props = {}) {
935
1058
  };
936
1059
  const updateErrors = (name, error) => {
937
1060
  set(_formState.errors, name, error);
1061
+ _formState.errors = { ..._formState.errors };
938
1062
  _subjects.state.next({
939
1063
  errors: _formState.errors,
940
1064
  });
@@ -946,16 +1070,53 @@ function createFormControl(props = {}) {
946
1070
  isValid: false,
947
1071
  });
948
1072
  };
1073
+ const hasExplicitNullIntermediate = (name) => {
1074
+ const segments = isKey(name) ? [name] : stringToPath(name);
1075
+ let formValues = _formValues;
1076
+ let defaultValues = _defaultValues;
1077
+ for (let i = 0; i < segments.length - 1; i++) {
1078
+ const key = segments[i];
1079
+ formValues = isNullOrUndefined(formValues) ? formValues : formValues[key];
1080
+ defaultValues = isNullOrUndefined(defaultValues)
1081
+ ? defaultValues
1082
+ : defaultValues[key];
1083
+ if (formValues === null && defaultValues !== null) {
1084
+ return true;
1085
+ }
1086
+ }
1087
+ return false;
1088
+ };
949
1089
  const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
950
1090
  const field = get(_fields, name);
951
1091
  if (field) {
1092
+ if (hasExplicitNullIntermediate(name)) {
1093
+ return;
1094
+ }
1095
+ const wasUnsetInFormValues = isUndefined(get(_formValues, name));
952
1096
  const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
953
1097
  isUndefined(defaultValue) ||
954
1098
  (ref && ref.defaultChecked) ||
955
1099
  shouldSkipSetValueAs
956
1100
  ? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
957
1101
  : setFieldValue(name, defaultValue);
958
- _state.mount && !_state.action && _setValid();
1102
+ if (_state.mount && !_state.action) {
1103
+ _setValid();
1104
+ if (wasUnsetInFormValues &&
1105
+ _formState.isDirty &&
1106
+ (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty)) {
1107
+ const isDirty = _getDirty();
1108
+ if (!isDirty) {
1109
+ _formState.isDirty = false;
1110
+ _subjects.state.next({ ..._formState });
1111
+ }
1112
+ }
1113
+ if (props.shouldUnregister &&
1114
+ wasUnsetInFormValues &&
1115
+ !isUndefined(get(_formValues, name)) &&
1116
+ isWatched(name, _names)) {
1117
+ _state.watch = true;
1118
+ }
1119
+ }
959
1120
  }
960
1121
  };
961
1122
  const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
@@ -964,18 +1125,26 @@ function createFormControl(props = {}) {
964
1125
  const output = {
965
1126
  name,
966
1127
  };
967
- if (!_options.disabled) {
1128
+ // an explicit programmatic update (e.g. setValue with shouldDirty: true)
1129
+ // opts into dirty tracking even when the form is disabled
1130
+ if (!_options.disabled || shouldDirty === true) {
968
1131
  if (!isBlurEvent || shouldDirty) {
1132
+ const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
969
1133
  if (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty) {
970
1134
  isPreviousDirty = _formState.isDirty;
971
- _formState.isDirty = output.isDirty = _getDirty();
1135
+ _formState.isDirty = output.isDirty =
1136
+ !isCurrentFieldPristine || _getDirty();
972
1137
  shouldUpdateField = isPreviousDirty !== output.isDirty;
973
1138
  }
974
- const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
975
1139
  isPreviousDirty = !!get(_formState.dirtyFields, name);
976
- isCurrentFieldPristine
977
- ? unset(_formState.dirtyFields, name)
978
- : set(_formState.dirtyFields, name, true);
1140
+ if (isCurrentFieldPristine !== _formState.isDirty) {
1141
+ updateDirtyFields(_formState.dirtyFields, getDirtyFields(_defaultValues, _formValues, undefined, _fields));
1142
+ }
1143
+ else {
1144
+ isCurrentFieldPristine
1145
+ ? unset(_formState.dirtyFields, name)
1146
+ : set(_formState.dirtyFields, name, true);
1147
+ }
979
1148
  output.dirtyFields = _formState.dirtyFields;
980
1149
  shouldUpdateField =
981
1150
  shouldUpdateField ||
@@ -1005,15 +1174,16 @@ function createFormControl(props = {}) {
1005
1174
  isBoolean(isValid) &&
1006
1175
  _formState.isValid !== isValid;
1007
1176
  if (_options.delayError && error) {
1008
- delayErrorCallback = debounce(() => updateErrors(name, error));
1009
- delayErrorCallback(_options.delayError);
1177
+ delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
1178
+ delayErrorCallbacks[name](_options.delayError);
1010
1179
  }
1011
1180
  else {
1012
- clearTimeout(timer);
1013
- delayErrorCallback = null;
1181
+ clearTimeout(timers[name]);
1182
+ delete delayErrorCallbacks[name];
1014
1183
  error
1015
1184
  ? set(_formState.errors, name, error)
1016
1185
  : unset(_formState.errors, name);
1186
+ _formState.errors = { ..._formState.errors };
1017
1187
  }
1018
1188
  if ((error ? !deepEqual(previousFieldError, error) : previousFieldError) ||
1019
1189
  !isEmptyObject(fieldState) ||
@@ -1042,9 +1212,14 @@ function createFormControl(props = {}) {
1042
1212
  for (const name of names) {
1043
1213
  const error = get(errors, name);
1044
1214
  error
1045
- ? set(_formState.errors, name, error)
1215
+ ? _names.array.has(name) &&
1216
+ isObject(error) &&
1217
+ !Object.keys(error).some((key) => !Number.isNaN(Number(key)))
1218
+ ? updateFieldArrayRootError(_formState.errors, { [name]: error }, name)
1219
+ : set(_formState.errors, name, error)
1046
1220
  : unset(_formState.errors, name);
1047
1221
  }
1222
+ _formState.errors = { ..._formState.errors };
1048
1223
  }
1049
1224
  else {
1050
1225
  _formState.errors = errors;
@@ -1064,8 +1239,8 @@ function createFormControl(props = {}) {
1064
1239
  const error = result[key];
1065
1240
  if (error) {
1066
1241
  setError(`${FORM_ERROR_TYPE}.${key}`, {
1067
- message: isString(result.message) ? result.message : '',
1068
- type: INPUT_VALIDATION_RULES.validate,
1242
+ message: isString(error.message) ? error.message : '',
1243
+ type: error.type || INPUT_VALIDATION_RULES.validate,
1069
1244
  });
1070
1245
  }
1071
1246
  }
@@ -1107,11 +1282,15 @@ function createFormControl(props = {}) {
1107
1282
  if (_f) {
1108
1283
  const isFieldArrayRoot = _names.array.has(_f.name);
1109
1284
  const isPromiseFunction = field._f && hasPromiseValidation(field._f);
1110
- if (isPromiseFunction && _proxyFormState.validatingFields) {
1285
+ const shouldTrackIsValidatingState = _proxyFormState.validatingFields ||
1286
+ _proxyFormState.isValidating ||
1287
+ _proxySubscribeFormState.validatingFields ||
1288
+ _proxySubscribeFormState.isValidating;
1289
+ if (isPromiseFunction && shouldTrackIsValidatingState) {
1111
1290
  _updateIsValidating([_f.name], true);
1112
1291
  }
1113
1292
  const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
1114
- if (isPromiseFunction && _proxyFormState.validatingFields) {
1293
+ if (isPromiseFunction && shouldTrackIsValidatingState) {
1115
1294
  _updateIsValidating([_f.name]);
1116
1295
  }
1117
1296
  if (fieldError[_f.name]) {
@@ -1153,9 +1332,8 @@ function createFormControl(props = {}) {
1153
1332
  }
1154
1333
  _names.unMount = new Set();
1155
1334
  };
1156
- const _getDirty = (name, data) => !_options.disabled &&
1157
- (name && data && set(_formValues, name, data),
1158
- !deepEqual(getValues(), _defaultValues));
1335
+ const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
1336
+ !deepEqual(_state.mount ? _formValues : _defaultValues, _defaultValues));
1159
1337
  const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
1160
1338
  ...(_state.mount
1161
1339
  ? _formValues
@@ -1166,7 +1344,7 @@ function createFormControl(props = {}) {
1166
1344
  : defaultValue),
1167
1345
  }, isGlobal, defaultValue);
1168
1346
  const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
1169
- const setFieldValue = (name, value, options = {}) => {
1347
+ const setFieldValue = (name, value, options = {}, skipClone = false, skipRender = false) => {
1170
1348
  const field = get(_fields, name);
1171
1349
  let fieldValue = value;
1172
1350
  if (field) {
@@ -1204,20 +1382,23 @@ function createFormControl(props = {}) {
1204
1382
  }
1205
1383
  else {
1206
1384
  fieldReference.ref.value = fieldValue;
1207
- if (!fieldReference.ref.type) {
1385
+ if (!fieldReference.ref.type && !skipRender) {
1208
1386
  _subjects.state.next({
1209
1387
  name,
1210
- values: cloneObject(_formValues),
1388
+ values: skipClone ? _formValues : cloneObject(_formValues),
1211
1389
  });
1212
1390
  }
1213
1391
  }
1214
1392
  }
1215
1393
  }
1216
1394
  (options.shouldDirty || options.shouldTouch) &&
1217
- updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1218
- options.shouldValidate && trigger(name);
1395
+ updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, !skipRender);
1396
+ options.shouldValidate &&
1397
+ trigger(name, {
1398
+ delayError: options.delayError,
1399
+ });
1219
1400
  };
1220
- const setValues = (name, value, options) => {
1401
+ const setFieldValues = (name, value, options, skipClone = false, skipRender = false) => {
1221
1402
  for (const fieldKey in value) {
1222
1403
  if (!value.hasOwnProperty(fieldKey)) {
1223
1404
  return;
@@ -1229,50 +1410,84 @@ function createFormControl(props = {}) {
1229
1410
  isObject(fieldValue) ||
1230
1411
  (field && !field._f)) &&
1231
1412
  !isDateObject(fieldValue)
1232
- ? setValues(fieldName, fieldValue, options)
1233
- : setFieldValue(fieldName, fieldValue, options);
1413
+ ? setFieldValues(fieldName, fieldValue, options, skipClone, skipRender)
1414
+ : setFieldValue(fieldName, fieldValue, options, skipClone, skipRender);
1234
1415
  }
1235
1416
  };
1236
- const setValue = (name, value, options = {}) => {
1417
+ const _setValue = (name, value, options, skipClone, skipStateEmit = false) => {
1237
1418
  const field = get(_fields, name);
1238
1419
  const isFieldArray = _names.array.has(name);
1239
- const cloneValue = cloneObject(value);
1240
- set(_formValues, name, cloneValue);
1420
+ const cloneValue = skipClone ? value : cloneObject(value);
1421
+ const previousValue = get(_formValues, name);
1422
+ const isValueUnchanged = deepEqual(previousValue, cloneValue);
1423
+ if (!isValueUnchanged) {
1424
+ set(_formValues, name, cloneValue);
1425
+ }
1241
1426
  if (isFieldArray) {
1242
1427
  _subjects.array.next({
1243
1428
  name,
1244
- values: cloneObject(_formValues),
1429
+ values: skipClone ? _formValues : cloneObject(_formValues),
1245
1430
  });
1246
1431
  if ((_proxyFormState.isDirty ||
1247
1432
  _proxyFormState.dirtyFields ||
1248
1433
  _proxySubscribeFormState.isDirty ||
1249
1434
  _proxySubscribeFormState.dirtyFields) &&
1250
1435
  options.shouldDirty) {
1251
- _updateDirtyFields(name);
1252
- _subjects.state.next({
1253
- name,
1254
- dirtyFields: _formState.dirtyFields,
1255
- isDirty: _getDirty(name, cloneValue),
1256
- });
1436
+ _updateDirtyFields();
1437
+ if (!skipStateEmit) {
1438
+ _subjects.state.next({
1439
+ name,
1440
+ dirtyFields: _formState.dirtyFields,
1441
+ isDirty: _getDirty(name, cloneValue),
1442
+ });
1443
+ }
1257
1444
  }
1258
1445
  }
1259
1446
  else {
1260
- field && !field._f && !isNullOrUndefined(cloneValue)
1261
- ? setValues(name, cloneValue, options)
1262
- : setFieldValue(name, cloneValue, options);
1447
+ const isEmpty = (Array.isArray(cloneValue) && !cloneValue.length) ||
1448
+ isEmptyObject(cloneValue);
1449
+ if (!field || field._f || isNullOrUndefined(cloneValue) || isEmpty) {
1450
+ setFieldValue(name, cloneValue, options, skipClone, skipStateEmit);
1451
+ }
1452
+ else {
1453
+ setFieldValues(name, cloneValue, options, skipClone, skipStateEmit);
1454
+ }
1263
1455
  }
1264
- if (isWatched(name, _names)) {
1456
+ if (!isValueUnchanged && !skipStateEmit) {
1457
+ const watched = isWatched(name, _names);
1458
+ const values = skipClone ? _formValues : cloneObject(_formValues);
1265
1459
  _subjects.state.next({
1266
- ..._formState,
1267
- name,
1268
- values: cloneObject(_formValues),
1460
+ ...(watched && _formState),
1461
+ name: _state.mount || watched ? name : undefined,
1462
+ values,
1269
1463
  });
1270
1464
  }
1271
- else {
1465
+ };
1466
+ const setValue = (name, value, options = {}) => _setValue(name, value, options, false);
1467
+ const setValues = (formValues, options = {}) => {
1468
+ const updatedFormValues = isFunction(formValues)
1469
+ ? formValues(_formValues)
1470
+ : formValues;
1471
+ if (!deepEqual(_formValues, updatedFormValues)) {
1472
+ _formValues = {
1473
+ ..._formValues,
1474
+ ...updatedFormValues,
1475
+ };
1476
+ const flattenedUpdates = flatten(updatedFormValues);
1477
+ for (const fieldName of _names.mount) {
1478
+ if (fieldName in flattenedUpdates) {
1479
+ _setValue(fieldName, flattenedUpdates[fieldName], options, true, true);
1480
+ }
1481
+ }
1272
1482
  _subjects.state.next({
1273
- name: _state.mount ? name : undefined,
1274
- values: cloneObject(_formValues),
1483
+ ..._formState,
1484
+ name: undefined,
1485
+ type: undefined,
1486
+ ...(_valuesSubscriberCount ? { values: _formValues } : {}),
1275
1487
  });
1488
+ if (options.shouldValidate) {
1489
+ _setValid();
1490
+ }
1276
1491
  }
1277
1492
  };
1278
1493
  const onChange = async (event) => {
@@ -1287,8 +1502,6 @@ function createFormControl(props = {}) {
1287
1502
  (isDateObject(fieldValue) && isNaN(fieldValue.getTime())) ||
1288
1503
  deepEqual(fieldValue, get(_formValues, name, fieldValue));
1289
1504
  };
1290
- const validationModeBeforeSubmit = getValidationModes(_options.mode);
1291
- const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1292
1505
  if (field) {
1293
1506
  let error;
1294
1507
  let isValid;
@@ -1296,18 +1509,20 @@ function createFormControl(props = {}) {
1296
1509
  ? getFieldValue(field._f)
1297
1510
  : getEventValue(event);
1298
1511
  const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
1299
- const shouldSkipValidation = (!hasValidation(field._f) &&
1512
+ const hasNoValidationEffect = !hasValidation(field._f) &&
1300
1513
  !props.validate &&
1301
1514
  !_options.resolver &&
1302
1515
  !get(_formState.errors, name) &&
1303
- !field._f.deps) ||
1304
- skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
1516
+ !field._f.deps;
1517
+ const shouldSkipValidation = hasNoValidationEffect ||
1518
+ skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, _validationModeAfterSubmit, _validationModeBeforeSubmit);
1305
1519
  const watched = isWatched(name, _names, isBlurEvent);
1306
1520
  set(_formValues, name, fieldValue);
1307
1521
  if (isBlurEvent) {
1308
1522
  if (!target || !target.readOnly) {
1309
1523
  field._f.onBlur && field._f.onBlur(event);
1310
- delayErrorCallback && delayErrorCallback(0);
1524
+ const pendingDelayError = delayErrorCallbacks[name];
1525
+ pendingDelayError && pendingDelayError(0);
1311
1526
  }
1312
1527
  }
1313
1528
  else if (field._f.onChange) {
@@ -1319,10 +1534,13 @@ function createFormControl(props = {}) {
1319
1534
  _subjects.state.next({
1320
1535
  name,
1321
1536
  type: event.type,
1322
- values: cloneObject(_formValues),
1537
+ ...(_valuesSubscriberCount
1538
+ ? { values: cloneObject(_formValues) }
1539
+ : {}),
1323
1540
  });
1324
1541
  if (shouldSkipValidation) {
1325
- if (_proxyFormState.isValid || _proxySubscribeFormState.isValid) {
1542
+ if ((!hasNoValidationEffect || !_formState.isValid) &&
1543
+ (_proxyFormState.isValid || _proxySubscribeFormState.isValid)) {
1326
1544
  if (_options.mode === 'onBlur') {
1327
1545
  if (isBlurEvent) {
1328
1546
  _setValid();
@@ -1346,13 +1564,15 @@ function createFormControl(props = {}) {
1346
1564
  const { errors } = await _runSchema([name]);
1347
1565
  _updateIsValidating([name]);
1348
1566
  _updateIsFieldValueUpdated(fieldValue);
1349
- if (isFieldValueUpdated) {
1350
- const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
1351
- const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
1352
- error = errorLookupResult.error;
1353
- name = errorLookupResult.name;
1354
- isValid = isEmptyObject(errors);
1567
+ if (!isFieldValueUpdated) {
1568
+ !isEmptyObject(fieldState) && _subjects.state.next(fieldState);
1569
+ return;
1355
1570
  }
1571
+ const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
1572
+ const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
1573
+ error = errorLookupResult.error;
1574
+ name = errorLookupResult.name;
1575
+ isValid = isEmptyObject(errors);
1356
1576
  }
1357
1577
  else {
1358
1578
  _updateIsValidating([name], true);
@@ -1417,6 +1637,18 @@ function createFormControl(props = {}) {
1417
1637
  eventType: EVENTS.TRIGGER,
1418
1638
  });
1419
1639
  }
1640
+ if (options.delayError && _options.delayError && isString(name)) {
1641
+ const error = get(_formState.errors, name);
1642
+ if (error) {
1643
+ unset(_formState.errors, name);
1644
+ delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
1645
+ delayErrorCallbacks[name](_options.delayError);
1646
+ }
1647
+ else {
1648
+ clearTimeout(timers[name]);
1649
+ delete delayErrorCallbacks[name];
1650
+ }
1651
+ }
1420
1652
  _subjects.state.next({
1421
1653
  ...(!isString(name) ||
1422
1654
  ((_proxyFormState.isValid || _proxySubscribeFormState.isValid) &&
@@ -1455,8 +1687,6 @@ function createFormControl(props = {}) {
1455
1687
  const names = name ? convertToArrayPayload(name) : undefined;
1456
1688
  names === null || names === void 0 ? void 0 : names.forEach((inputName) => unset(_formState.errors, inputName));
1457
1689
  if (names) {
1458
- // Emit for each cleared field with the field name so that
1459
- // shouldSubscribeByName can filter and avoid broad re-renders
1460
1690
  names.forEach((inputName) => {
1461
1691
  _subjects.state.next({
1462
1692
  name: inputName,
@@ -1465,16 +1695,15 @@ function createFormControl(props = {}) {
1465
1695
  });
1466
1696
  }
1467
1697
  else {
1468
- // Clear all errors - emit without name to notify all subscribers
1698
+ _formState.errors = {};
1469
1699
  _subjects.state.next({
1470
- errors: {},
1700
+ errors: _formState.errors,
1471
1701
  });
1472
1702
  }
1473
1703
  };
1474
1704
  const setError = (name, error, options) => {
1475
1705
  const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
1476
1706
  const currentError = get(_formState.errors, name) || {};
1477
- // Don't override existing error messages elsewhere in the object tree.
1478
1707
  const { ref: currentRef, message, type, ...restOfErrorTree } = currentError;
1479
1708
  set(_formState.errors, name, {
1480
1709
  ...restOfErrorTree,
@@ -1488,25 +1717,60 @@ function createFormControl(props = {}) {
1488
1717
  });
1489
1718
  options && options.shouldFocus && ref && ref.focus && ref.focus();
1490
1719
  };
1491
- const watch = (name, defaultValue) => isFunction(name)
1492
- ? _subjects.state.subscribe({
1493
- next: (payload) => 'values' in payload &&
1494
- name(_getWatch(undefined, defaultValue), payload),
1495
- })
1496
- : _getWatch(name, defaultValue, true);
1497
- const _subscribe = (props) => _subjects.state.subscribe({
1498
- next: (formState) => {
1499
- if (shouldSubscribeByName(props.name, formState.name, props.exact) &&
1500
- shouldRenderFormState(formState, props.formState || _proxyFormState, _setFormState, props.reRenderRoot)) {
1501
- props.callback({
1502
- values: { ..._formValues },
1503
- ..._formState,
1504
- ...formState,
1505
- defaultValues: _defaultValues,
1506
- });
1720
+ const watch = (name, defaultValue) => {
1721
+ if (isFunction(name)) {
1722
+ _valuesSubscriberCount++;
1723
+ const { unsubscribe } = _subjects.state.subscribe({
1724
+ next: (payload) => 'values' in payload &&
1725
+ name(payload.values || _getWatch(undefined, defaultValue), payload),
1726
+ });
1727
+ let called = false;
1728
+ return {
1729
+ unsubscribe: () => {
1730
+ if (called) {
1731
+ return;
1732
+ }
1733
+ called = true;
1734
+ _valuesSubscriberCount--;
1735
+ unsubscribe();
1736
+ },
1737
+ };
1738
+ }
1739
+ return _getWatch(name, defaultValue, true);
1740
+ };
1741
+ const _subscribe = (props) => {
1742
+ var _a;
1743
+ const needsValues = !!((_a = props.formState) === null || _a === void 0 ? void 0 : _a.values);
1744
+ if (needsValues) {
1745
+ _valuesSubscriberCount++;
1746
+ }
1747
+ const { unsubscribe } = _subjects.state.subscribe({
1748
+ next: (formState) => {
1749
+ if (shouldSubscribeByName(props.name, formState.name, props.exact) &&
1750
+ shouldRenderFormState(formState, props.formState || _proxyFormState, _setFormState, props.reRenderRoot)) {
1751
+ const snapshot = { ..._formValues };
1752
+ props.callback({
1753
+ values: snapshot,
1754
+ ..._formState,
1755
+ ...formState,
1756
+ defaultValues: _defaultValues,
1757
+ });
1758
+ }
1759
+ },
1760
+ });
1761
+ if (!needsValues) {
1762
+ return unsubscribe;
1763
+ }
1764
+ let called = false;
1765
+ return () => {
1766
+ if (called) {
1767
+ return;
1507
1768
  }
1508
- },
1509
- }).unsubscribe;
1769
+ called = true;
1770
+ _valuesSubscriberCount--;
1771
+ unsubscribe();
1772
+ };
1773
+ };
1510
1774
  const subscribe = (props) => {
1511
1775
  _state.mount = true;
1512
1776
  _proxySubscribeFormState = {
@@ -1561,7 +1825,7 @@ function createFormControl(props = {}) {
1561
1825
  const register = (name, options = {}) => {
1562
1826
  let field = get(_fields, name);
1563
1827
  const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
1564
- const shouldRevalidateRemount = !_names.registerName.has(name) && field && !field._f.mount;
1828
+ const shouldRevalidateRemount = !_names.registerName.has(name) && field && field._f && !field._f.mount;
1565
1829
  set(_fields, name, {
1566
1830
  ...(field || {}),
1567
1831
  _f: {
@@ -1618,20 +1882,23 @@ function createFormControl(props = {}) {
1618
1882
  : fieldRef === field._f.ref) {
1619
1883
  return;
1620
1884
  }
1885
+ const newField = {
1886
+ ...field._f,
1887
+ };
1888
+ if (radioOrCheckbox) {
1889
+ newField.refs = [
1890
+ ...refs.filter(live),
1891
+ fieldRef,
1892
+ ...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
1893
+ ];
1894
+ newField.ref = { type: fieldRef.type, name };
1895
+ }
1896
+ else {
1897
+ newField.ref = fieldRef;
1898
+ delete newField.refs;
1899
+ }
1621
1900
  set(_fields, name, {
1622
- _f: {
1623
- ...field._f,
1624
- ...(radioOrCheckbox
1625
- ? {
1626
- refs: [
1627
- ...refs.filter(live),
1628
- fieldRef,
1629
- ...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
1630
- ],
1631
- ref: { type: fieldRef.type, name },
1632
- }
1633
- : { ref: fieldRef }),
1634
- },
1901
+ _f: newField,
1635
1902
  });
1636
1903
  updateValidAndValue(name, false, undefined, fieldRef);
1637
1904
  }
@@ -1648,6 +1915,7 @@ function createFormControl(props = {}) {
1648
1915
  };
1649
1916
  };
1650
1917
  const _focusError = () => _options.shouldFocusError &&
1918
+ !_options.shouldUseNativeValidation &&
1651
1919
  iterateFieldsByAction(_fields, _focusInput, _names.mount);
1652
1920
  const _disableForm = (disabled) => {
1653
1921
  if (isBoolean(disabled)) {
@@ -1752,7 +2020,8 @@ function createFormControl(props = {}) {
1752
2020
  const updatedValues = formValues ? cloneObject(formValues) : _defaultValues;
1753
2021
  const cloneUpdatedValues = cloneObject(updatedValues);
1754
2022
  const isEmptyResetValues = isEmptyObject(formValues);
1755
- const values = isEmptyResetValues ? _defaultValues : cloneUpdatedValues;
2023
+ const values = cloneUpdatedValues;
2024
+ const fieldRefs = _fields;
1756
2025
  if (!keepStateOptions.keepDefaultValues) {
1757
2026
  _defaultValues = updatedValues;
1758
2027
  }
@@ -1760,7 +2029,7 @@ function createFormControl(props = {}) {
1760
2029
  if (keepStateOptions.keepDirtyValues) {
1761
2030
  const fieldsToCheck = new Set([
1762
2031
  ..._names.mount,
1763
- ...Object.keys(getDirtyFields(_defaultValues, _formValues)),
2032
+ ...Object.keys(getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs)),
1764
2033
  ]);
1765
2034
  for (const fieldName of Array.from(fieldsToCheck)) {
1766
2035
  const isDirty = get(_formState.dirtyFields, fieldName);
@@ -1801,15 +2070,25 @@ function createFormControl(props = {}) {
1801
2070
  _fields = {};
1802
2071
  }
1803
2072
  }
1804
- _formValues = _options.shouldUnregister
1805
- ? keepStateOptions.keepDefaultValues
2073
+ if (_options.shouldUnregister) {
2074
+ _formValues = keepStateOptions.keepDefaultValues
1806
2075
  ? cloneObject(_defaultValues)
1807
- : {}
1808
- : cloneObject(values);
2076
+ : {};
2077
+ if (keepStateOptions.keepFieldsRef) {
2078
+ for (const fieldName of _names.mount) {
2079
+ set(_formValues, fieldName, get(values, fieldName));
2080
+ }
2081
+ }
2082
+ }
2083
+ else {
2084
+ _formValues = cloneObject(values);
2085
+ }
1809
2086
  _subjects.array.next({
1810
2087
  values: { ...values },
1811
2088
  });
1812
2089
  _subjects.state.next({
2090
+ name: undefined,
2091
+ type: undefined,
1813
2092
  values: { ...values },
1814
2093
  });
1815
2094
  }
@@ -1831,9 +2110,6 @@ function createFormControl(props = {}) {
1831
2110
  _state.watch = !!_options.shouldUnregister;
1832
2111
  _state.keepIsValid = !!keepStateOptions.keepIsValid;
1833
2112
  _state.action = false;
1834
- // Clear errors synchronously to prevent validation errors on subsequent submissions
1835
- // This fixes the issue where form.reset() causes validation errors on subsequent
1836
- // submissions in Next.js 16 with Server Actions
1837
2113
  if (!keepStateOptions.keepErrors) {
1838
2114
  _formState.errors = {};
1839
2115
  }
@@ -1845,8 +2121,10 @@ function createFormControl(props = {}) {
1845
2121
  ? false
1846
2122
  : keepStateOptions.keepDirty
1847
2123
  ? _formState.isDirty
1848
- : !!(keepStateOptions.keepDefaultValues &&
1849
- !deepEqual(formValues, _defaultValues)),
2124
+ : keepStateOptions.keepValues
2125
+ ? _getDirty()
2126
+ : !!(keepStateOptions.keepDefaultValues &&
2127
+ !deepEqual(formValues, _defaultValues)),
1850
2128
  isSubmitted: keepStateOptions.keepIsSubmitted
1851
2129
  ? _formState.isSubmitted
1852
2130
  : false,
@@ -1854,10 +2132,10 @@ function createFormControl(props = {}) {
1854
2132
  ? {}
1855
2133
  : keepStateOptions.keepDirtyValues
1856
2134
  ? keepStateOptions.keepDefaultValues && _formValues
1857
- ? getDirtyFields(_defaultValues, _formValues)
2135
+ ? getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs)
1858
2136
  : _formState.dirtyFields
1859
2137
  : keepStateOptions.keepDefaultValues && formValues
1860
- ? getDirtyFields(_defaultValues, formValues)
2138
+ ? getDirtyFields(_defaultValues, formValues, undefined, fieldRefs)
1861
2139
  : keepStateOptions.keepDirty
1862
2140
  ? _formState.dirtyFields
1863
2141
  : {},
@@ -1883,8 +2161,6 @@ function createFormControl(props = {}) {
1883
2161
  ? fieldReference.refs[0]
1884
2162
  : fieldReference.ref;
1885
2163
  if (fieldRef.focus) {
1886
- // Use setTimeout to ensure focus happens after any pending state updates
1887
- // This fixes the issue where setFocus doesn't work immediately after setError
1888
2164
  setTimeout(() => {
1889
2165
  fieldRef.focus();
1890
2166
  options.shouldSelect &&
@@ -1895,9 +2171,15 @@ function createFormControl(props = {}) {
1895
2171
  }
1896
2172
  };
1897
2173
  const _setFormState = (updatedFormState) => {
2174
+ // `name`, `type`, and `values` describe the event that produced this
2175
+ // update, not the form's persisted state (they aren't part of
2176
+ // `FormState`). Merging them in would leak a stale `name`/`type` from
2177
+ // one event into a later, unrelated notification that doesn't specify
2178
+ // its own.
2179
+ const { name, type, values, ...formState } = updatedFormState;
1898
2180
  _formState = {
1899
2181
  ..._formState,
1900
- ...updatedFormState,
2182
+ ...formState,
1901
2183
  };
1902
2184
  };
1903
2185
  const _resetDefaultValues = () => isFunction(_options.defaultValues) &&
@@ -1907,6 +2189,21 @@ function createFormControl(props = {}) {
1907
2189
  isLoading: false,
1908
2190
  });
1909
2191
  });
2192
+ const resetDefaultValues = (values, options = {}) => {
2193
+ _defaultValues = cloneObject(values);
2194
+ if (!options.keepDirty) {
2195
+ const newDirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
2196
+ _formState.dirtyFields = newDirtyFields;
2197
+ _formState.isDirty = !isEmptyObject(newDirtyFields);
2198
+ }
2199
+ if (!options.keepIsValid) {
2200
+ _setValid();
2201
+ }
2202
+ _subjects.state.next({
2203
+ ..._formState,
2204
+ defaultValues: _defaultValues,
2205
+ });
2206
+ };
1910
2207
  const methods = {
1911
2208
  control: {
1912
2209
  register,
@@ -1963,6 +2260,8 @@ function createFormControl(props = {}) {
1963
2260
  ..._options,
1964
2261
  ...value,
1965
2262
  };
2263
+ _validationModeBeforeSubmit = getValidationModes(_options.mode);
2264
+ _validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1966
2265
  },
1967
2266
  },
1968
2267
  subscribe,
@@ -1971,9 +2270,11 @@ function createFormControl(props = {}) {
1971
2270
  handleSubmit,
1972
2271
  watch,
1973
2272
  setValue,
2273
+ setValues,
1974
2274
  getValues,
1975
2275
  reset,
1976
2276
  resetField,
2277
+ resetDefaultValues,
1977
2278
  clearErrors,
1978
2279
  unregister,
1979
2280
  setError,