@depup/react-hook-form 7.72.0-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 (298) 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 +2455 -2019
  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/isNameInFieldArray.d.ts.map +1 -1
  31. package/dist/logic/isWatched.d.ts.map +1 -1
  32. package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
  33. package/dist/logic/skipValidation.d.ts +1 -4
  34. package/dist/logic/skipValidation.d.ts.map +1 -1
  35. package/dist/logic/updateFieldArrayRootError.d.ts.map +1 -1
  36. package/dist/logic/validateField.d.ts.map +1 -1
  37. package/dist/react-server.esm.mjs +491 -179
  38. package/dist/react-server.esm.mjs.map +1 -1
  39. package/dist/types/errors.d.ts +2 -2
  40. package/dist/types/errors.d.ts.map +1 -1
  41. package/dist/types/fieldArray.d.ts +25 -1
  42. package/dist/types/fieldArray.d.ts.map +1 -1
  43. package/dist/types/form.d.ts +81 -56
  44. package/dist/types/form.d.ts.map +1 -1
  45. package/dist/types/path/common.d.ts +6 -0
  46. package/dist/types/path/common.d.ts.map +1 -1
  47. package/dist/types/path/eager.d.ts +15 -11
  48. package/dist/types/path/eager.d.ts.map +1 -1
  49. package/dist/types/utils.d.ts +4 -4
  50. package/dist/types/utils.d.ts.map +1 -1
  51. package/dist/types/validator.d.ts +1 -1
  52. package/dist/types/validator.d.ts.map +1 -1
  53. package/dist/types/watch.d.ts +1 -1
  54. package/dist/types/watch.d.ts.map +1 -1
  55. package/dist/useController.d.ts.map +1 -1
  56. package/dist/useFieldArray.d.ts.map +1 -1
  57. package/dist/useForm.d.ts.map +1 -1
  58. package/dist/useFormContext.d.ts +1 -1
  59. package/dist/useFormContext.d.ts.map +1 -1
  60. package/dist/useFormState.d.ts +2 -2
  61. package/dist/useFormState.d.ts.map +1 -1
  62. package/dist/useIsomorphicLayoutEffect.d.ts.map +1 -1
  63. package/dist/useWatch.d.ts +14 -14
  64. package/dist/utils/deepEqual.d.ts +1 -1
  65. package/dist/utils/deepEqual.d.ts.map +1 -1
  66. package/dist/utils/flatten.d.ts.map +1 -1
  67. package/dist/utils/get.d.ts.map +1 -1
  68. package/dist/utils/index.d.ts +2 -3
  69. package/dist/utils/index.d.ts.map +1 -1
  70. package/dist/utils/isKey.d.ts.map +1 -1
  71. package/dist/utils/set.d.ts.map +1 -1
  72. package/dist/utils/stringToPath.d.ts.map +1 -1
  73. package/dist/utils/unset.d.ts.map +1 -1
  74. package/dist/watch.d.ts +1 -1
  75. package/dist/watch.d.ts.map +1 -1
  76. package/package.json +34 -31
  77. package/dist/__tests__/controller.server.test.d.ts +0 -2
  78. package/dist/__tests__/controller.server.test.d.ts.map +0 -1
  79. package/dist/__tests__/controller.test.d.ts +0 -2
  80. package/dist/__tests__/controller.test.d.ts.map +0 -1
  81. package/dist/__tests__/form.test.d.ts +0 -2
  82. package/dist/__tests__/form.test.d.ts.map +0 -1
  83. package/dist/__tests__/formStateSubscribe.server.test.d.ts +0 -2
  84. package/dist/__tests__/formStateSubscribe.server.test.d.ts.map +0 -1
  85. package/dist/__tests__/formStateSubscribe.test.d.ts +0 -2
  86. package/dist/__tests__/formStateSubscribe.test.d.ts.map +0 -1
  87. package/dist/__tests__/isPlainObject.test.d.ts +0 -2
  88. package/dist/__tests__/isPlainObject.test.d.ts.map +0 -1
  89. package/dist/__tests__/logic/appendErrors.test.d.ts +0 -2
  90. package/dist/__tests__/logic/appendErrors.test.d.ts.map +0 -1
  91. package/dist/__tests__/logic/createFormControl.test.d.ts +0 -2
  92. package/dist/__tests__/logic/createFormControl.test.d.ts.map +0 -1
  93. package/dist/__tests__/logic/generateId.test.d.ts +0 -2
  94. package/dist/__tests__/logic/generateId.test.d.ts.map +0 -1
  95. package/dist/__tests__/logic/getCheckboxValue.test.d.ts +0 -2
  96. package/dist/__tests__/logic/getCheckboxValue.test.d.ts.map +0 -1
  97. package/dist/__tests__/logic/getDirtyFields.test.d.ts +0 -2
  98. package/dist/__tests__/logic/getDirtyFields.test.d.ts.map +0 -1
  99. package/dist/__tests__/logic/getEventValue.test.d.ts +0 -2
  100. package/dist/__tests__/logic/getEventValue.test.d.ts.map +0 -1
  101. package/dist/__tests__/logic/getFieldValue.test.d.ts +0 -2
  102. package/dist/__tests__/logic/getFieldValue.test.d.ts.map +0 -1
  103. package/dist/__tests__/logic/getFieldValueAs.test.d.ts +0 -2
  104. package/dist/__tests__/logic/getFieldValueAs.test.d.ts.map +0 -1
  105. package/dist/__tests__/logic/getFocusFieldName.test.d.ts +0 -2
  106. package/dist/__tests__/logic/getFocusFieldName.test.d.ts.map +0 -1
  107. package/dist/__tests__/logic/getNodeParentName.test.d.ts +0 -2
  108. package/dist/__tests__/logic/getNodeParentName.test.d.ts.map +0 -1
  109. package/dist/__tests__/logic/getRadioValue.test.d.ts +0 -2
  110. package/dist/__tests__/logic/getRadioValue.test.d.ts.map +0 -1
  111. package/dist/__tests__/logic/getResolverOptions.test.d.ts +0 -2
  112. package/dist/__tests__/logic/getResolverOptions.test.d.ts.map +0 -1
  113. package/dist/__tests__/logic/getRuleValue.test.d.ts +0 -2
  114. package/dist/__tests__/logic/getRuleValue.test.d.ts.map +0 -1
  115. package/dist/__tests__/logic/getValidateError.test.d.ts +0 -2
  116. package/dist/__tests__/logic/getValidateError.test.d.ts.map +0 -1
  117. package/dist/__tests__/logic/getValidationModes.test.d.ts +0 -2
  118. package/dist/__tests__/logic/getValidationModes.test.d.ts.map +0 -1
  119. package/dist/__tests__/logic/getValueAndMessage.test.d.ts +0 -2
  120. package/dist/__tests__/logic/getValueAndMessage.test.d.ts.map +0 -1
  121. package/dist/__tests__/logic/hasPromiseValidation.test.d.ts +0 -2
  122. package/dist/__tests__/logic/hasPromiseValidation.test.d.ts.map +0 -1
  123. package/dist/__tests__/logic/hasValidation.test.d.ts +0 -2
  124. package/dist/__tests__/logic/hasValidation.test.d.ts.map +0 -1
  125. package/dist/__tests__/logic/isNameInFieldArray.test.d.ts +0 -2
  126. package/dist/__tests__/logic/isNameInFieldArray.test.d.ts.map +0 -1
  127. package/dist/__tests__/logic/isWatched.test.d.ts +0 -2
  128. package/dist/__tests__/logic/isWatched.test.d.ts.map +0 -1
  129. package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts +0 -2
  130. package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts.map +0 -1
  131. package/dist/__tests__/logic/schemaErrorLookup.test.d.ts +0 -2
  132. package/dist/__tests__/logic/schemaErrorLookup.test.d.ts.map +0 -1
  133. package/dist/__tests__/logic/shouldRenderFormState.test.d.ts +0 -2
  134. package/dist/__tests__/logic/shouldRenderFormState.test.d.ts.map +0 -1
  135. package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts +0 -2
  136. package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts.map +0 -1
  137. package/dist/__tests__/logic/skipValidation.test.d.ts +0 -2
  138. package/dist/__tests__/logic/skipValidation.test.d.ts.map +0 -1
  139. package/dist/__tests__/logic/unsetEmptyArray.test.d.ts +0 -2
  140. package/dist/__tests__/logic/unsetEmptyArray.test.d.ts.map +0 -1
  141. package/dist/__tests__/logic/validateField.test.d.ts +0 -2
  142. package/dist/__tests__/logic/validateField.test.d.ts.map +0 -1
  143. package/dist/__tests__/type.test.d.ts +0 -2
  144. package/dist/__tests__/type.test.d.ts.map +0 -1
  145. package/dist/__tests__/useController.test.d.ts +0 -2
  146. package/dist/__tests__/useController.test.d.ts.map +0 -1
  147. package/dist/__tests__/useFieldArray/append.test.d.ts +0 -2
  148. package/dist/__tests__/useFieldArray/append.test.d.ts.map +0 -1
  149. package/dist/__tests__/useFieldArray/dirtyFields.test.d.ts +0 -2
  150. package/dist/__tests__/useFieldArray/dirtyFields.test.d.ts.map +0 -1
  151. package/dist/__tests__/useFieldArray/focus.test.d.ts +0 -2
  152. package/dist/__tests__/useFieldArray/focus.test.d.ts.map +0 -1
  153. package/dist/__tests__/useFieldArray/insert.test.d.ts +0 -2
  154. package/dist/__tests__/useFieldArray/insert.test.d.ts.map +0 -1
  155. package/dist/__tests__/useFieldArray/move.test.d.ts +0 -2
  156. package/dist/__tests__/useFieldArray/move.test.d.ts.map +0 -1
  157. package/dist/__tests__/useFieldArray/prepend.test.d.ts +0 -2
  158. package/dist/__tests__/useFieldArray/prepend.test.d.ts.map +0 -1
  159. package/dist/__tests__/useFieldArray/remove.test.d.ts +0 -2
  160. package/dist/__tests__/useFieldArray/remove.test.d.ts.map +0 -1
  161. package/dist/__tests__/useFieldArray/replace.test.d.ts +0 -2
  162. package/dist/__tests__/useFieldArray/replace.test.d.ts.map +0 -1
  163. package/dist/__tests__/useFieldArray/swap.test.d.ts +0 -2
  164. package/dist/__tests__/useFieldArray/swap.test.d.ts.map +0 -1
  165. package/dist/__tests__/useFieldArray/update.test.d.ts +0 -2
  166. package/dist/__tests__/useFieldArray/update.test.d.ts.map +0 -1
  167. package/dist/__tests__/useFieldArray.test.d.ts +0 -2
  168. package/dist/__tests__/useFieldArray.test.d.ts.map +0 -1
  169. package/dist/__tests__/useForm/clearErrors.test.d.ts +0 -2
  170. package/dist/__tests__/useForm/clearErrors.test.d.ts.map +0 -1
  171. package/dist/__tests__/useForm/formState.test.d.ts +0 -2
  172. package/dist/__tests__/useForm/formState.test.d.ts.map +0 -1
  173. package/dist/__tests__/useForm/getFieldState.test.d.ts +0 -2
  174. package/dist/__tests__/useForm/getFieldState.test.d.ts.map +0 -1
  175. package/dist/__tests__/useForm/getValues.test.d.ts +0 -2
  176. package/dist/__tests__/useForm/getValues.test.d.ts.map +0 -1
  177. package/dist/__tests__/useForm/handleSubmit.test.d.ts +0 -2
  178. package/dist/__tests__/useForm/handleSubmit.test.d.ts.map +0 -1
  179. package/dist/__tests__/useForm/register.test.d.ts +0 -2
  180. package/dist/__tests__/useForm/register.test.d.ts.map +0 -1
  181. package/dist/__tests__/useForm/reset.test.d.ts +0 -2
  182. package/dist/__tests__/useForm/reset.test.d.ts.map +0 -1
  183. package/dist/__tests__/useForm/resetField.test.d.ts +0 -2
  184. package/dist/__tests__/useForm/resetField.test.d.ts.map +0 -1
  185. package/dist/__tests__/useForm/resolver.test.d.ts +0 -2
  186. package/dist/__tests__/useForm/resolver.test.d.ts.map +0 -1
  187. package/dist/__tests__/useForm/setError.test.d.ts +0 -2
  188. package/dist/__tests__/useForm/setError.test.d.ts.map +0 -1
  189. package/dist/__tests__/useForm/setFocus.test.d.ts +0 -2
  190. package/dist/__tests__/useForm/setFocus.test.d.ts.map +0 -1
  191. package/dist/__tests__/useForm/setValue.test.d.ts +0 -2
  192. package/dist/__tests__/useForm/setValue.test.d.ts.map +0 -1
  193. package/dist/__tests__/useForm/subscribe.test.d.ts +0 -2
  194. package/dist/__tests__/useForm/subscribe.test.d.ts.map +0 -1
  195. package/dist/__tests__/useForm/trigger.test.d.ts +0 -2
  196. package/dist/__tests__/useForm/trigger.test.d.ts.map +0 -1
  197. package/dist/__tests__/useForm/unregister.test.d.ts +0 -2
  198. package/dist/__tests__/useForm/unregister.test.d.ts.map +0 -1
  199. package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts +0 -2
  200. package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts.map +0 -1
  201. package/dist/__tests__/useForm/watch.test.d.ts +0 -2
  202. package/dist/__tests__/useForm/watch.test.d.ts.map +0 -1
  203. package/dist/__tests__/useForm.server.test.d.ts +0 -2
  204. package/dist/__tests__/useForm.server.test.d.ts.map +0 -1
  205. package/dist/__tests__/useForm.test.d.ts +0 -2
  206. package/dist/__tests__/useForm.test.d.ts.map +0 -1
  207. package/dist/__tests__/useFormContext.server.test.d.ts +0 -2
  208. package/dist/__tests__/useFormContext.server.test.d.ts.map +0 -1
  209. package/dist/__tests__/useFormContext.test.d.ts +0 -2
  210. package/dist/__tests__/useFormContext.test.d.ts.map +0 -1
  211. package/dist/__tests__/useFormState.test.d.ts +0 -2
  212. package/dist/__tests__/useFormState.test.d.ts.map +0 -1
  213. package/dist/__tests__/useWatch.test.d.ts +0 -2
  214. package/dist/__tests__/useWatch.test.d.ts.map +0 -1
  215. package/dist/__tests__/utils/append.test.d.ts +0 -2
  216. package/dist/__tests__/utils/append.test.d.ts.map +0 -1
  217. package/dist/__tests__/utils/cloneObject.test.d.ts +0 -2
  218. package/dist/__tests__/utils/cloneObject.test.d.ts.map +0 -1
  219. package/dist/__tests__/utils/compact.test.d.ts +0 -2
  220. package/dist/__tests__/utils/compact.test.d.ts.map +0 -1
  221. package/dist/__tests__/utils/convertToArrayPayload.test.d.ts +0 -2
  222. package/dist/__tests__/utils/convertToArrayPayload.test.d.ts.map +0 -1
  223. package/dist/__tests__/utils/createSubject.test.d.ts +0 -2
  224. package/dist/__tests__/utils/createSubject.test.d.ts.map +0 -1
  225. package/dist/__tests__/utils/deepEqual.test.d.ts +0 -2
  226. package/dist/__tests__/utils/deepEqual.test.d.ts.map +0 -1
  227. package/dist/__tests__/utils/deepMerge.test.d.ts +0 -2
  228. package/dist/__tests__/utils/deepMerge.test.d.ts.map +0 -1
  229. package/dist/__tests__/utils/extractFormValues.test.d.ts +0 -2
  230. package/dist/__tests__/utils/extractFormValues.test.d.ts.map +0 -1
  231. package/dist/__tests__/utils/fillEmptyArray.test.d.ts +0 -2
  232. package/dist/__tests__/utils/fillEmptyArray.test.d.ts.map +0 -1
  233. package/dist/__tests__/utils/flatten.test.d.ts +0 -2
  234. package/dist/__tests__/utils/flatten.test.d.ts.map +0 -1
  235. package/dist/__tests__/utils/get.test.d.ts +0 -2
  236. package/dist/__tests__/utils/get.test.d.ts.map +0 -1
  237. package/dist/__tests__/utils/insert.test.d.ts +0 -2
  238. package/dist/__tests__/utils/insert.test.d.ts.map +0 -1
  239. package/dist/__tests__/utils/isBoolean.test.d.ts +0 -2
  240. package/dist/__tests__/utils/isBoolean.test.d.ts.map +0 -1
  241. package/dist/__tests__/utils/isCheckBoxInput.test.d.ts +0 -2
  242. package/dist/__tests__/utils/isCheckBoxInput.test.d.ts.map +0 -1
  243. package/dist/__tests__/utils/isEmptyObject.test.d.ts +0 -2
  244. package/dist/__tests__/utils/isEmptyObject.test.d.ts.map +0 -1
  245. package/dist/__tests__/utils/isFileInput.test.d.ts +0 -2
  246. package/dist/__tests__/utils/isFileInput.test.d.ts.map +0 -1
  247. package/dist/__tests__/utils/isFunction.test.d.ts +0 -2
  248. package/dist/__tests__/utils/isFunction.test.d.ts.map +0 -1
  249. package/dist/__tests__/utils/isHTMLElement.test.d.ts +0 -2
  250. package/dist/__tests__/utils/isHTMLElement.test.d.ts.map +0 -1
  251. package/dist/__tests__/utils/isKey.test.d.ts +0 -2
  252. package/dist/__tests__/utils/isKey.test.d.ts.map +0 -1
  253. package/dist/__tests__/utils/isMultipleSelect.test.d.ts +0 -2
  254. package/dist/__tests__/utils/isMultipleSelect.test.d.ts.map +0 -1
  255. package/dist/__tests__/utils/isNullOrUndefined.test.d.ts +0 -2
  256. package/dist/__tests__/utils/isNullOrUndefined.test.d.ts.map +0 -1
  257. package/dist/__tests__/utils/isObject.test.d.ts +0 -2
  258. package/dist/__tests__/utils/isObject.test.d.ts.map +0 -1
  259. package/dist/__tests__/utils/isPrimitive.test.d.ts +0 -2
  260. package/dist/__tests__/utils/isPrimitive.test.d.ts.map +0 -1
  261. package/dist/__tests__/utils/isRadioInput.test.d.ts +0 -2
  262. package/dist/__tests__/utils/isRadioInput.test.d.ts.map +0 -1
  263. package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts +0 -2
  264. package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts.map +0 -1
  265. package/dist/__tests__/utils/isRegex.test.d.ts +0 -2
  266. package/dist/__tests__/utils/isRegex.test.d.ts.map +0 -1
  267. package/dist/__tests__/utils/isString.test.d.ts +0 -2
  268. package/dist/__tests__/utils/isString.test.d.ts.map +0 -1
  269. package/dist/__tests__/utils/isUndefined.test.d.ts +0 -2
  270. package/dist/__tests__/utils/isUndefined.test.d.ts.map +0 -1
  271. package/dist/__tests__/utils/live.test.d.ts +0 -2
  272. package/dist/__tests__/utils/live.test.d.ts.map +0 -1
  273. package/dist/__tests__/utils/move.test.d.ts +0 -2
  274. package/dist/__tests__/utils/move.test.d.ts.map +0 -1
  275. package/dist/__tests__/utils/noop.test.d.ts +0 -2
  276. package/dist/__tests__/utils/noop.test.d.ts.map +0 -1
  277. package/dist/__tests__/utils/objectHasFunction.test.d.ts +0 -2
  278. package/dist/__tests__/utils/objectHasFunction.test.d.ts.map +0 -1
  279. package/dist/__tests__/utils/prepend.test.d.ts +0 -2
  280. package/dist/__tests__/utils/prepend.test.d.ts.map +0 -1
  281. package/dist/__tests__/utils/remove.test.d.ts +0 -2
  282. package/dist/__tests__/utils/remove.test.d.ts.map +0 -1
  283. package/dist/__tests__/utils/set.test.d.ts +0 -2
  284. package/dist/__tests__/utils/set.test.d.ts.map +0 -1
  285. package/dist/__tests__/utils/stringToPath.test.d.ts +0 -2
  286. package/dist/__tests__/utils/stringToPath.test.d.ts.map +0 -1
  287. package/dist/__tests__/utils/swap.test.d.ts +0 -2
  288. package/dist/__tests__/utils/swap.test.d.ts.map +0 -1
  289. package/dist/__tests__/utils/unset.test.d.ts +0 -2
  290. package/dist/__tests__/utils/unset.test.d.ts.map +0 -1
  291. package/dist/__tests__/utils/update.test.d.ts +0 -2
  292. package/dist/__tests__/utils/update.test.d.ts.map +0 -1
  293. package/dist/__tests__/utils/validationModeChecker.test.d.ts +0 -2
  294. package/dist/__tests__/utils/validationModeChecker.test.d.ts.map +0 -1
  295. package/dist/__tests__/watch.server.test.d.ts +0 -2
  296. package/dist/__tests__/watch.server.test.d.ts.map +0 -1
  297. package/dist/__tests__/watch.test.d.ts +0 -2
  298. 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,22 +124,36 @@ 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') {
134
152
  const val2 = object2[key];
135
153
  if ((isDateObject(val1) && isDateObject(val2)) ||
136
- (isObject(val1) && isObject(val2)) ||
137
- (Array.isArray(val1) && Array.isArray(val2))
138
- ? !deepEqual(val1, val2, _internal_visited)
154
+ ((isObject(val1) || Array.isArray(val1)) &&
155
+ (isObject(val2) || Array.isArray(val2)))
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 ||
@@ -460,13 +554,21 @@ var hasValidation = (options) => options.mount &&
460
554
  options.pattern ||
461
555
  options.validate);
462
556
 
463
- var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
557
+ var isNameInFieldArray = (names, name) => name
558
+ .split('.')
559
+ .some((part, index, arr) => !isNaN(Number(part)) && names.has(arr.slice(0, index).join('.')));
464
560
 
465
- var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
466
- (_names.watchAll ||
467
- _names.watch.has(name) ||
468
- [..._names.watch].some((watchName) => name.startsWith(watchName) &&
469
- /^\.\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
+ };
470
572
 
471
573
  const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
472
574
  for (const key of fieldsNames || Object.keys(fields)) {
@@ -534,9 +636,10 @@ function schemaErrorLookup(errors, _fields, name) {
534
636
  var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
535
637
  updateFormState(formStateData);
536
638
  const { name, ...formState } = formStateData;
537
- return (isEmptyObject(formState) ||
538
- Object.keys(formState).length >= Object.keys(_proxyFormState).length ||
539
- 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] ===
540
643
  (!isRoot || VALIDATION_MODE.all)));
541
644
  };
542
645
 
@@ -545,7 +648,7 @@ var shouldSubscribeByName = (name, signalName, exact) => !name ||
545
648
  name === signalName ||
546
649
  convertToArrayPayload(name).some((currentName) => currentName &&
547
650
  (exact
548
- ? currentName === signalName
651
+ ? currentName === signalName || currentName.startsWith(signalName + '.')
549
652
  : currentName.startsWith(signalName) ||
550
653
  signalName.startsWith(currentName)));
551
654
 
@@ -568,7 +671,8 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
568
671
  var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
569
672
 
570
673
  var updateFieldArrayRootError = (errors, error, name) => {
571
- const fieldArrayErrors = convertToArrayPayload(get(errors, name));
674
+ const existingErrors = get(errors, name);
675
+ const fieldArrayErrors = Array.isArray(existingErrors) ? existingErrors : [];
572
676
  set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
573
677
  set(errors, name, fieldArrayErrors);
574
678
  return errors;
@@ -602,7 +706,13 @@ var validateField = async (field, disabledFieldNames, formValues, validateAllFie
602
706
  const inputRef = refs ? refs[0] : ref;
603
707
  const setCustomValidity = (message) => {
604
708
  if (shouldUseNativeValidation && inputRef.reportValidity) {
605
- 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
+ }
606
716
  inputRef.reportValidity();
607
717
  }
608
718
  };
@@ -777,24 +887,36 @@ const defaultOptions = {
777
887
  reValidateMode: VALIDATION_MODE.onChange,
778
888
  shouldFocusError: true,
779
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
+ };
780
912
  function createFormControl(props = {}) {
781
913
  let _options = {
782
914
  ...defaultOptions,
783
915
  ...props,
784
916
  };
785
917
  let _formState = {
786
- submitCount: 0,
787
- isDirty: false,
788
- isReady: false,
918
+ ...cloneObject(DEFAULT_FORM_STATE),
789
919
  isLoading: isFunction(_options.defaultValues),
790
- isValidating: false,
791
- isSubmitted: false,
792
- isSubmitting: false,
793
- isSubmitSuccessful: false,
794
- isValid: false,
795
- touchedFields: {},
796
- dirtyFields: {},
797
- validatingFields: {},
798
920
  errors: _options.errors || {},
799
921
  disabled: _options.disabled || false,
800
922
  };
@@ -817,9 +939,13 @@ function createFormControl(props = {}) {
817
939
  unMount: new Set(),
818
940
  array: new Set(),
819
941
  watch: new Set(),
942
+ registerName: new Set(),
820
943
  };
821
- let delayErrorCallback;
822
- 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);
823
949
  const defaultProxyFormState = {
824
950
  isDirty: false,
825
951
  dirtyFields: false,
@@ -839,10 +965,11 @@ function createFormControl(props = {}) {
839
965
  array: createSubject(),
840
966
  state: createSubject(),
841
967
  };
968
+ let _setValidCallId = 0;
842
969
  const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
843
- const debounce = (callback) => (wait) => {
844
- clearTimeout(timer);
845
- timer = setTimeout(callback, wait);
970
+ const debounce = (name, callback) => (wait) => {
971
+ clearTimeout(timers[name]);
972
+ timers[name] = setTimeout(callback, wait);
846
973
  };
847
974
  const _setValid = async (shouldUpdateValid) => {
848
975
  if (_state.keepIsValid) {
@@ -852,10 +979,11 @@ function createFormControl(props = {}) {
852
979
  (_proxyFormState.isValid ||
853
980
  _proxySubscribeFormState.isValid ||
854
981
  shouldUpdateValid)) {
982
+ const callId = ++_setValidCallId;
855
983
  let isValid;
856
984
  if (_options.resolver) {
857
985
  isValid = isEmptyObject((await _runSchema()).errors);
858
- _updateIsValidating();
986
+ callId === _setValidCallId && _updateIsValidating();
859
987
  }
860
988
  else {
861
989
  isValid = await executeBuiltInValidation({
@@ -864,7 +992,7 @@ function createFormControl(props = {}) {
864
992
  eventType: EVENTS.VALID,
865
993
  });
866
994
  }
867
- if (isValid !== _formState.isValid) {
995
+ if (callId === _setValidCallId && isValid !== _formState.isValid) {
868
996
  _subjects.state.next({
869
997
  isValid,
870
998
  });
@@ -890,6 +1018,9 @@ function createFormControl(props = {}) {
890
1018
  });
891
1019
  }
892
1020
  };
1021
+ const _updateDirtyFields = () => {
1022
+ _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
1023
+ };
893
1024
  const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
894
1025
  if (args && method && !_options.disabled) {
895
1026
  _state.action = true;
@@ -911,9 +1042,7 @@ function createFormControl(props = {}) {
911
1042
  shouldSetValues && set(_formState.touchedFields, name, touchedFields);
912
1043
  }
913
1044
  if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
914
- const fullDirtyFields = getDirtyFields(_defaultValues, _formValues);
915
- const rootName = getNodeParentName(name);
916
- set(_formState.dirtyFields, rootName, get(fullDirtyFields, rootName));
1045
+ _updateDirtyFields();
917
1046
  }
918
1047
  _subjects.state.next({
919
1048
  name,
@@ -929,6 +1058,7 @@ function createFormControl(props = {}) {
929
1058
  };
930
1059
  const updateErrors = (name, error) => {
931
1060
  set(_formState.errors, name, error);
1061
+ _formState.errors = { ..._formState.errors };
932
1062
  _subjects.state.next({
933
1063
  errors: _formState.errors,
934
1064
  });
@@ -940,16 +1070,53 @@ function createFormControl(props = {}) {
940
1070
  isValid: false,
941
1071
  });
942
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
+ };
943
1089
  const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
944
1090
  const field = get(_fields, name);
945
1091
  if (field) {
1092
+ if (hasExplicitNullIntermediate(name)) {
1093
+ return;
1094
+ }
1095
+ const wasUnsetInFormValues = isUndefined(get(_formValues, name));
946
1096
  const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
947
1097
  isUndefined(defaultValue) ||
948
1098
  (ref && ref.defaultChecked) ||
949
1099
  shouldSkipSetValueAs
950
1100
  ? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
951
1101
  : setFieldValue(name, defaultValue);
952
- _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
+ }
953
1120
  }
954
1121
  };
955
1122
  const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
@@ -958,18 +1125,26 @@ function createFormControl(props = {}) {
958
1125
  const output = {
959
1126
  name,
960
1127
  };
961
- 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) {
962
1131
  if (!isBlurEvent || shouldDirty) {
1132
+ const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
963
1133
  if (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty) {
964
1134
  isPreviousDirty = _formState.isDirty;
965
- _formState.isDirty = output.isDirty = _getDirty();
1135
+ _formState.isDirty = output.isDirty =
1136
+ !isCurrentFieldPristine || _getDirty();
966
1137
  shouldUpdateField = isPreviousDirty !== output.isDirty;
967
1138
  }
968
- const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
969
1139
  isPreviousDirty = !!get(_formState.dirtyFields, name);
970
- isCurrentFieldPristine
971
- ? unset(_formState.dirtyFields, name)
972
- : 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
+ }
973
1148
  output.dirtyFields = _formState.dirtyFields;
974
1149
  shouldUpdateField =
975
1150
  shouldUpdateField ||
@@ -999,15 +1174,16 @@ function createFormControl(props = {}) {
999
1174
  isBoolean(isValid) &&
1000
1175
  _formState.isValid !== isValid;
1001
1176
  if (_options.delayError && error) {
1002
- delayErrorCallback = debounce(() => updateErrors(name, error));
1003
- delayErrorCallback(_options.delayError);
1177
+ delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
1178
+ delayErrorCallbacks[name](_options.delayError);
1004
1179
  }
1005
1180
  else {
1006
- clearTimeout(timer);
1007
- delayErrorCallback = null;
1181
+ clearTimeout(timers[name]);
1182
+ delete delayErrorCallbacks[name];
1008
1183
  error
1009
1184
  ? set(_formState.errors, name, error)
1010
1185
  : unset(_formState.errors, name);
1186
+ _formState.errors = { ..._formState.errors };
1011
1187
  }
1012
1188
  if ((error ? !deepEqual(previousFieldError, error) : previousFieldError) ||
1013
1189
  !isEmptyObject(fieldState) ||
@@ -1036,9 +1212,14 @@ function createFormControl(props = {}) {
1036
1212
  for (const name of names) {
1037
1213
  const error = get(errors, name);
1038
1214
  error
1039
- ? 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)
1040
1220
  : unset(_formState.errors, name);
1041
1221
  }
1222
+ _formState.errors = { ..._formState.errors };
1042
1223
  }
1043
1224
  else {
1044
1225
  _formState.errors = errors;
@@ -1058,8 +1239,8 @@ function createFormControl(props = {}) {
1058
1239
  const error = result[key];
1059
1240
  if (error) {
1060
1241
  setError(`${FORM_ERROR_TYPE}.${key}`, {
1061
- message: isString(result.message) ? result.message : '',
1062
- type: INPUT_VALIDATION_RULES.validate,
1242
+ message: isString(error.message) ? error.message : '',
1243
+ type: error.type || INPUT_VALIDATION_RULES.validate,
1063
1244
  });
1064
1245
  }
1065
1246
  }
@@ -1101,11 +1282,15 @@ function createFormControl(props = {}) {
1101
1282
  if (_f) {
1102
1283
  const isFieldArrayRoot = _names.array.has(_f.name);
1103
1284
  const isPromiseFunction = field._f && hasPromiseValidation(field._f);
1104
- if (isPromiseFunction && _proxyFormState.validatingFields) {
1285
+ const shouldTrackIsValidatingState = _proxyFormState.validatingFields ||
1286
+ _proxyFormState.isValidating ||
1287
+ _proxySubscribeFormState.validatingFields ||
1288
+ _proxySubscribeFormState.isValidating;
1289
+ if (isPromiseFunction && shouldTrackIsValidatingState) {
1105
1290
  _updateIsValidating([_f.name], true);
1106
1291
  }
1107
1292
  const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
1108
- if (isPromiseFunction && _proxyFormState.validatingFields) {
1293
+ if (isPromiseFunction && shouldTrackIsValidatingState) {
1109
1294
  _updateIsValidating([_f.name]);
1110
1295
  }
1111
1296
  if (fieldError[_f.name]) {
@@ -1147,9 +1332,8 @@ function createFormControl(props = {}) {
1147
1332
  }
1148
1333
  _names.unMount = new Set();
1149
1334
  };
1150
- const _getDirty = (name, data) => !_options.disabled &&
1151
- (name && data && set(_formValues, name, data),
1152
- !deepEqual(getValues(), _defaultValues));
1335
+ const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
1336
+ !deepEqual(_state.mount ? _formValues : _defaultValues, _defaultValues));
1153
1337
  const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
1154
1338
  ...(_state.mount
1155
1339
  ? _formValues
@@ -1160,7 +1344,7 @@ function createFormControl(props = {}) {
1160
1344
  : defaultValue),
1161
1345
  }, isGlobal, defaultValue);
1162
1346
  const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
1163
- const setFieldValue = (name, value, options = {}) => {
1347
+ const setFieldValue = (name, value, options = {}, skipClone = false, skipRender = false) => {
1164
1348
  const field = get(_fields, name);
1165
1349
  let fieldValue = value;
1166
1350
  if (field) {
@@ -1198,20 +1382,23 @@ function createFormControl(props = {}) {
1198
1382
  }
1199
1383
  else {
1200
1384
  fieldReference.ref.value = fieldValue;
1201
- if (!fieldReference.ref.type) {
1385
+ if (!fieldReference.ref.type && !skipRender) {
1202
1386
  _subjects.state.next({
1203
1387
  name,
1204
- values: cloneObject(_formValues),
1388
+ values: skipClone ? _formValues : cloneObject(_formValues),
1205
1389
  });
1206
1390
  }
1207
1391
  }
1208
1392
  }
1209
1393
  }
1210
1394
  (options.shouldDirty || options.shouldTouch) &&
1211
- updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1212
- options.shouldValidate && trigger(name);
1395
+ updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, !skipRender);
1396
+ options.shouldValidate &&
1397
+ trigger(name, {
1398
+ delayError: options.delayError,
1399
+ });
1213
1400
  };
1214
- const setValues = (name, value, options) => {
1401
+ const setFieldValues = (name, value, options, skipClone = false, skipRender = false) => {
1215
1402
  for (const fieldKey in value) {
1216
1403
  if (!value.hasOwnProperty(fieldKey)) {
1217
1404
  return;
@@ -1223,49 +1410,84 @@ function createFormControl(props = {}) {
1223
1410
  isObject(fieldValue) ||
1224
1411
  (field && !field._f)) &&
1225
1412
  !isDateObject(fieldValue)
1226
- ? setValues(fieldName, fieldValue, options)
1227
- : setFieldValue(fieldName, fieldValue, options);
1413
+ ? setFieldValues(fieldName, fieldValue, options, skipClone, skipRender)
1414
+ : setFieldValue(fieldName, fieldValue, options, skipClone, skipRender);
1228
1415
  }
1229
1416
  };
1230
- const setValue = (name, value, options = {}) => {
1417
+ const _setValue = (name, value, options, skipClone, skipStateEmit = false) => {
1231
1418
  const field = get(_fields, name);
1232
1419
  const isFieldArray = _names.array.has(name);
1233
- const cloneValue = cloneObject(value);
1234
- 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
+ }
1235
1426
  if (isFieldArray) {
1236
1427
  _subjects.array.next({
1237
1428
  name,
1238
- values: cloneObject(_formValues),
1429
+ values: skipClone ? _formValues : cloneObject(_formValues),
1239
1430
  });
1240
1431
  if ((_proxyFormState.isDirty ||
1241
1432
  _proxyFormState.dirtyFields ||
1242
1433
  _proxySubscribeFormState.isDirty ||
1243
1434
  _proxySubscribeFormState.dirtyFields) &&
1244
1435
  options.shouldDirty) {
1245
- _subjects.state.next({
1246
- name,
1247
- dirtyFields: getDirtyFields(_defaultValues, _formValues),
1248
- isDirty: _getDirty(name, cloneValue),
1249
- });
1436
+ _updateDirtyFields();
1437
+ if (!skipStateEmit) {
1438
+ _subjects.state.next({
1439
+ name,
1440
+ dirtyFields: _formState.dirtyFields,
1441
+ isDirty: _getDirty(name, cloneValue),
1442
+ });
1443
+ }
1250
1444
  }
1251
1445
  }
1252
1446
  else {
1253
- field && !field._f && !isNullOrUndefined(cloneValue)
1254
- ? setValues(name, cloneValue, options)
1255
- : 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
+ }
1256
1455
  }
1257
- if (isWatched(name, _names)) {
1456
+ if (!isValueUnchanged && !skipStateEmit) {
1457
+ const watched = isWatched(name, _names);
1458
+ const values = skipClone ? _formValues : cloneObject(_formValues);
1258
1459
  _subjects.state.next({
1259
- ..._formState,
1260
- name,
1261
- values: cloneObject(_formValues),
1460
+ ...(watched && _formState),
1461
+ name: _state.mount || watched ? name : undefined,
1462
+ values,
1262
1463
  });
1263
1464
  }
1264
- 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
+ }
1265
1482
  _subjects.state.next({
1266
- name: _state.mount ? name : undefined,
1267
- values: cloneObject(_formValues),
1483
+ ..._formState,
1484
+ name: undefined,
1485
+ type: undefined,
1486
+ ...(_valuesSubscriberCount ? { values: _formValues } : {}),
1268
1487
  });
1488
+ if (options.shouldValidate) {
1489
+ _setValid();
1490
+ }
1269
1491
  }
1270
1492
  };
1271
1493
  const onChange = async (event) => {
@@ -1280,8 +1502,6 @@ function createFormControl(props = {}) {
1280
1502
  (isDateObject(fieldValue) && isNaN(fieldValue.getTime())) ||
1281
1503
  deepEqual(fieldValue, get(_formValues, name, fieldValue));
1282
1504
  };
1283
- const validationModeBeforeSubmit = getValidationModes(_options.mode);
1284
- const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1285
1505
  if (field) {
1286
1506
  let error;
1287
1507
  let isValid;
@@ -1289,18 +1509,20 @@ function createFormControl(props = {}) {
1289
1509
  ? getFieldValue(field._f)
1290
1510
  : getEventValue(event);
1291
1511
  const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
1292
- const shouldSkipValidation = (!hasValidation(field._f) &&
1512
+ const hasNoValidationEffect = !hasValidation(field._f) &&
1293
1513
  !props.validate &&
1294
1514
  !_options.resolver &&
1295
1515
  !get(_formState.errors, name) &&
1296
- !field._f.deps) ||
1297
- 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);
1298
1519
  const watched = isWatched(name, _names, isBlurEvent);
1299
1520
  set(_formValues, name, fieldValue);
1300
1521
  if (isBlurEvent) {
1301
1522
  if (!target || !target.readOnly) {
1302
1523
  field._f.onBlur && field._f.onBlur(event);
1303
- delayErrorCallback && delayErrorCallback(0);
1524
+ const pendingDelayError = delayErrorCallbacks[name];
1525
+ pendingDelayError && pendingDelayError(0);
1304
1526
  }
1305
1527
  }
1306
1528
  else if (field._f.onChange) {
@@ -1312,10 +1534,13 @@ function createFormControl(props = {}) {
1312
1534
  _subjects.state.next({
1313
1535
  name,
1314
1536
  type: event.type,
1315
- values: cloneObject(_formValues),
1537
+ ...(_valuesSubscriberCount
1538
+ ? { values: cloneObject(_formValues) }
1539
+ : {}),
1316
1540
  });
1317
1541
  if (shouldSkipValidation) {
1318
- if (_proxyFormState.isValid || _proxySubscribeFormState.isValid) {
1542
+ if ((!hasNoValidationEffect || !_formState.isValid) &&
1543
+ (_proxyFormState.isValid || _proxySubscribeFormState.isValid)) {
1319
1544
  if (_options.mode === 'onBlur') {
1320
1545
  if (isBlurEvent) {
1321
1546
  _setValid();
@@ -1339,13 +1564,15 @@ function createFormControl(props = {}) {
1339
1564
  const { errors } = await _runSchema([name]);
1340
1565
  _updateIsValidating([name]);
1341
1566
  _updateIsFieldValueUpdated(fieldValue);
1342
- if (isFieldValueUpdated) {
1343
- const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
1344
- const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
1345
- error = errorLookupResult.error;
1346
- name = errorLookupResult.name;
1347
- isValid = isEmptyObject(errors);
1567
+ if (!isFieldValueUpdated) {
1568
+ !isEmptyObject(fieldState) && _subjects.state.next(fieldState);
1569
+ return;
1348
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);
1349
1576
  }
1350
1577
  else {
1351
1578
  _updateIsValidating([name], true);
@@ -1410,6 +1637,18 @@ function createFormControl(props = {}) {
1410
1637
  eventType: EVENTS.TRIGGER,
1411
1638
  });
1412
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
+ }
1413
1652
  _subjects.state.next({
1414
1653
  ...(!isString(name) ||
1415
1654
  ((_proxyFormState.isValid || _proxySubscribeFormState.isValid) &&
@@ -1448,8 +1687,6 @@ function createFormControl(props = {}) {
1448
1687
  const names = name ? convertToArrayPayload(name) : undefined;
1449
1688
  names === null || names === void 0 ? void 0 : names.forEach((inputName) => unset(_formState.errors, inputName));
1450
1689
  if (names) {
1451
- // Emit for each cleared field with the field name so that
1452
- // shouldSubscribeByName can filter and avoid broad re-renders
1453
1690
  names.forEach((inputName) => {
1454
1691
  _subjects.state.next({
1455
1692
  name: inputName,
@@ -1458,16 +1695,15 @@ function createFormControl(props = {}) {
1458
1695
  });
1459
1696
  }
1460
1697
  else {
1461
- // Clear all errors - emit without name to notify all subscribers
1698
+ _formState.errors = {};
1462
1699
  _subjects.state.next({
1463
- errors: {},
1700
+ errors: _formState.errors,
1464
1701
  });
1465
1702
  }
1466
1703
  };
1467
1704
  const setError = (name, error, options) => {
1468
1705
  const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
1469
1706
  const currentError = get(_formState.errors, name) || {};
1470
- // Don't override existing error messages elsewhere in the object tree.
1471
1707
  const { ref: currentRef, message, type, ...restOfErrorTree } = currentError;
1472
1708
  set(_formState.errors, name, {
1473
1709
  ...restOfErrorTree,
@@ -1481,25 +1717,60 @@ function createFormControl(props = {}) {
1481
1717
  });
1482
1718
  options && options.shouldFocus && ref && ref.focus && ref.focus();
1483
1719
  };
1484
- const watch = (name, defaultValue) => isFunction(name)
1485
- ? _subjects.state.subscribe({
1486
- next: (payload) => 'values' in payload &&
1487
- name(_getWatch(undefined, defaultValue), payload),
1488
- })
1489
- : _getWatch(name, defaultValue, true);
1490
- const _subscribe = (props) => _subjects.state.subscribe({
1491
- next: (formState) => {
1492
- if (shouldSubscribeByName(props.name, formState.name, props.exact) &&
1493
- shouldRenderFormState(formState, props.formState || _proxyFormState, _setFormState, props.reRenderRoot)) {
1494
- props.callback({
1495
- values: { ..._formValues },
1496
- ..._formState,
1497
- ...formState,
1498
- defaultValues: _defaultValues,
1499
- });
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;
1500
1768
  }
1501
- },
1502
- }).unsubscribe;
1769
+ called = true;
1770
+ _valuesSubscriberCount--;
1771
+ unsubscribe();
1772
+ };
1773
+ };
1503
1774
  const subscribe = (props) => {
1504
1775
  _state.mount = true;
1505
1776
  _proxySubscribeFormState = {
@@ -1554,6 +1825,7 @@ function createFormControl(props = {}) {
1554
1825
  const register = (name, options = {}) => {
1555
1826
  let field = get(_fields, name);
1556
1827
  const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
1828
+ const shouldRevalidateRemount = !_names.registerName.has(name) && field && field._f && !field._f.mount;
1557
1829
  set(_fields, name, {
1558
1830
  ...(field || {}),
1559
1831
  _f: {
@@ -1564,7 +1836,7 @@ function createFormControl(props = {}) {
1564
1836
  },
1565
1837
  });
1566
1838
  _names.mount.add(name);
1567
- if (field) {
1839
+ if (field && !shouldRevalidateRemount) {
1568
1840
  _setDisabledField({
1569
1841
  disabled: isBoolean(options.disabled)
1570
1842
  ? options.disabled
@@ -1594,7 +1866,9 @@ function createFormControl(props = {}) {
1594
1866
  onBlur: onChange,
1595
1867
  ref: (ref) => {
1596
1868
  if (ref) {
1869
+ _names.registerName.add(name);
1597
1870
  register(name, options);
1871
+ _names.registerName.delete(name);
1598
1872
  field = get(_fields, name);
1599
1873
  const fieldRef = isUndefined(ref.value)
1600
1874
  ? ref.querySelectorAll
@@ -1608,20 +1882,23 @@ function createFormControl(props = {}) {
1608
1882
  : fieldRef === field._f.ref) {
1609
1883
  return;
1610
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
+ }
1611
1900
  set(_fields, name, {
1612
- _f: {
1613
- ...field._f,
1614
- ...(radioOrCheckbox
1615
- ? {
1616
- refs: [
1617
- ...refs.filter(live),
1618
- fieldRef,
1619
- ...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
1620
- ],
1621
- ref: { type: fieldRef.type, name },
1622
- }
1623
- : { ref: fieldRef }),
1624
- },
1901
+ _f: newField,
1625
1902
  });
1626
1903
  updateValidAndValue(name, false, undefined, fieldRef);
1627
1904
  }
@@ -1638,6 +1915,7 @@ function createFormControl(props = {}) {
1638
1915
  };
1639
1916
  };
1640
1917
  const _focusError = () => _options.shouldFocusError &&
1918
+ !_options.shouldUseNativeValidation &&
1641
1919
  iterateFieldsByAction(_fields, _focusInput, _names.mount);
1642
1920
  const _disableForm = (disabled) => {
1643
1921
  if (isBoolean(disabled)) {
@@ -1742,7 +2020,8 @@ function createFormControl(props = {}) {
1742
2020
  const updatedValues = formValues ? cloneObject(formValues) : _defaultValues;
1743
2021
  const cloneUpdatedValues = cloneObject(updatedValues);
1744
2022
  const isEmptyResetValues = isEmptyObject(formValues);
1745
- const values = isEmptyResetValues ? _defaultValues : cloneUpdatedValues;
2023
+ const values = cloneUpdatedValues;
2024
+ const fieldRefs = _fields;
1746
2025
  if (!keepStateOptions.keepDefaultValues) {
1747
2026
  _defaultValues = updatedValues;
1748
2027
  }
@@ -1750,7 +2029,7 @@ function createFormControl(props = {}) {
1750
2029
  if (keepStateOptions.keepDirtyValues) {
1751
2030
  const fieldsToCheck = new Set([
1752
2031
  ..._names.mount,
1753
- ...Object.keys(getDirtyFields(_defaultValues, _formValues)),
2032
+ ...Object.keys(getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs)),
1754
2033
  ]);
1755
2034
  for (const fieldName of Array.from(fieldsToCheck)) {
1756
2035
  const isDirty = get(_formState.dirtyFields, fieldName);
@@ -1791,15 +2070,25 @@ function createFormControl(props = {}) {
1791
2070
  _fields = {};
1792
2071
  }
1793
2072
  }
1794
- _formValues = _options.shouldUnregister
1795
- ? keepStateOptions.keepDefaultValues
2073
+ if (_options.shouldUnregister) {
2074
+ _formValues = keepStateOptions.keepDefaultValues
1796
2075
  ? cloneObject(_defaultValues)
1797
- : {}
1798
- : 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
+ }
1799
2086
  _subjects.array.next({
1800
2087
  values: { ...values },
1801
2088
  });
1802
2089
  _subjects.state.next({
2090
+ name: undefined,
2091
+ type: undefined,
1803
2092
  values: { ...values },
1804
2093
  });
1805
2094
  }
@@ -1807,6 +2096,7 @@ function createFormControl(props = {}) {
1807
2096
  mount: keepStateOptions.keepDirtyValues ? _names.mount : new Set(),
1808
2097
  unMount: new Set(),
1809
2098
  array: new Set(),
2099
+ registerName: new Set(),
1810
2100
  disabled: new Set(),
1811
2101
  watch: new Set(),
1812
2102
  watchAll: false,
@@ -1820,9 +2110,6 @@ function createFormControl(props = {}) {
1820
2110
  _state.watch = !!_options.shouldUnregister;
1821
2111
  _state.keepIsValid = !!keepStateOptions.keepIsValid;
1822
2112
  _state.action = false;
1823
- // Clear errors synchronously to prevent validation errors on subsequent submissions
1824
- // This fixes the issue where form.reset() causes validation errors on subsequent
1825
- // submissions in Next.js 16 with Server Actions
1826
2113
  if (!keepStateOptions.keepErrors) {
1827
2114
  _formState.errors = {};
1828
2115
  }
@@ -1834,8 +2121,10 @@ function createFormControl(props = {}) {
1834
2121
  ? false
1835
2122
  : keepStateOptions.keepDirty
1836
2123
  ? _formState.isDirty
1837
- : !!(keepStateOptions.keepDefaultValues &&
1838
- !deepEqual(formValues, _defaultValues)),
2124
+ : keepStateOptions.keepValues
2125
+ ? _getDirty()
2126
+ : !!(keepStateOptions.keepDefaultValues &&
2127
+ !deepEqual(formValues, _defaultValues)),
1839
2128
  isSubmitted: keepStateOptions.keepIsSubmitted
1840
2129
  ? _formState.isSubmitted
1841
2130
  : false,
@@ -1843,10 +2132,10 @@ function createFormControl(props = {}) {
1843
2132
  ? {}
1844
2133
  : keepStateOptions.keepDirtyValues
1845
2134
  ? keepStateOptions.keepDefaultValues && _formValues
1846
- ? getDirtyFields(_defaultValues, _formValues)
2135
+ ? getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs)
1847
2136
  : _formState.dirtyFields
1848
2137
  : keepStateOptions.keepDefaultValues && formValues
1849
- ? getDirtyFields(_defaultValues, formValues)
2138
+ ? getDirtyFields(_defaultValues, formValues, undefined, fieldRefs)
1850
2139
  : keepStateOptions.keepDirty
1851
2140
  ? _formState.dirtyFields
1852
2141
  : {},
@@ -1872,8 +2161,6 @@ function createFormControl(props = {}) {
1872
2161
  ? fieldReference.refs[0]
1873
2162
  : fieldReference.ref;
1874
2163
  if (fieldRef.focus) {
1875
- // Use setTimeout to ensure focus happens after any pending state updates
1876
- // This fixes the issue where setFocus doesn't work immediately after setError
1877
2164
  setTimeout(() => {
1878
2165
  fieldRef.focus();
1879
2166
  options.shouldSelect &&
@@ -1884,9 +2171,15 @@ function createFormControl(props = {}) {
1884
2171
  }
1885
2172
  };
1886
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;
1887
2180
  _formState = {
1888
2181
  ..._formState,
1889
- ...updatedFormState,
2182
+ ...formState,
1890
2183
  };
1891
2184
  };
1892
2185
  const _resetDefaultValues = () => isFunction(_options.defaultValues) &&
@@ -1896,6 +2189,21 @@ function createFormControl(props = {}) {
1896
2189
  isLoading: false,
1897
2190
  });
1898
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
+ };
1899
2207
  const methods = {
1900
2208
  control: {
1901
2209
  register,
@@ -1952,6 +2260,8 @@ function createFormControl(props = {}) {
1952
2260
  ..._options,
1953
2261
  ...value,
1954
2262
  };
2263
+ _validationModeBeforeSubmit = getValidationModes(_options.mode);
2264
+ _validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1955
2265
  },
1956
2266
  },
1957
2267
  subscribe,
@@ -1960,9 +2270,11 @@ function createFormControl(props = {}) {
1960
2270
  handleSubmit,
1961
2271
  watch,
1962
2272
  setValue,
2273
+ setValues,
1963
2274
  getValues,
1964
2275
  reset,
1965
2276
  resetField,
2277
+ resetDefaultValues,
1966
2278
  clearErrors,
1967
2279
  unregister,
1968
2280
  setError,