react-hook-form 8.0.0-beta.1 → 8.0.0-beta.2

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 (261) hide show
  1. package/README.md +16 -29
  2. package/dist/constants.d.ts +5 -0
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/form.d.ts.map +1 -1
  5. package/dist/index.cjs.js +1 -1
  6. package/dist/index.cjs.js.map +1 -1
  7. package/dist/index.esm.mjs +395 -153
  8. package/dist/index.esm.mjs.map +1 -1
  9. package/dist/index.umd.js +1 -1
  10. package/dist/index.umd.js.map +1 -1
  11. package/dist/logic/createFormControl.d.ts +13 -0
  12. package/dist/logic/createFormControl.d.ts.map +1 -1
  13. package/dist/logic/getDirtyFields.d.ts.map +1 -1
  14. package/dist/logic/{isNameInFieldArray.d.ts → getFieldArrayParentNames.d.ts} +2 -2
  15. package/dist/logic/getFieldArrayParentNames.d.ts.map +1 -0
  16. package/dist/logic/getProxyFormState.d.ts.map +1 -1
  17. package/dist/logic/getResolverOptions.d.ts +2 -2
  18. package/dist/logic/hasValidation.d.ts +1 -1
  19. package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
  20. package/dist/logic/updateFieldArrayRootError.d.ts.map +1 -1
  21. package/dist/logic/validateField.d.ts.map +1 -1
  22. package/dist/react-server.esm.mjs +310 -76
  23. package/dist/react-server.esm.mjs.map +1 -1
  24. package/dist/types/errors.d.ts +1 -0
  25. package/dist/types/errors.d.ts.map +1 -1
  26. package/dist/types/form.d.ts +12 -5
  27. package/dist/types/form.d.ts.map +1 -1
  28. package/dist/types/path/eager.d.ts +1 -1
  29. package/dist/types/path/eager.d.ts.map +1 -1
  30. package/dist/types/utils.d.ts +2 -2
  31. package/dist/types/validator.d.ts +13 -1
  32. package/dist/types/validator.d.ts.map +1 -1
  33. package/dist/useFieldArray.d.ts.map +1 -1
  34. package/dist/useForm.d.ts.map +1 -1
  35. package/dist/useFormContext.d.ts.map +1 -1
  36. package/dist/useFormState.d.ts.map +1 -1
  37. package/dist/utils/deepEqual.d.ts +1 -1
  38. package/dist/utils/deepEqual.d.ts.map +1 -1
  39. package/dist/utils/unset.d.ts.map +1 -1
  40. package/dist/watch.d.ts +1 -1
  41. package/dist/watch.d.ts.map +1 -1
  42. package/package.json +25 -26
  43. package/dist/__tests__/controller.server.test.d.ts +0 -2
  44. package/dist/__tests__/controller.server.test.d.ts.map +0 -1
  45. package/dist/__tests__/controller.test.d.ts +0 -2
  46. package/dist/__tests__/controller.test.d.ts.map +0 -1
  47. package/dist/__tests__/form.test.d.ts +0 -2
  48. package/dist/__tests__/form.test.d.ts.map +0 -1
  49. package/dist/__tests__/formStateSubscribe.server.test.d.ts +0 -2
  50. package/dist/__tests__/formStateSubscribe.server.test.d.ts.map +0 -1
  51. package/dist/__tests__/formStateSubscribe.test.d.ts +0 -2
  52. package/dist/__tests__/formStateSubscribe.test.d.ts.map +0 -1
  53. package/dist/__tests__/isPlainObject.test.d.ts +0 -2
  54. package/dist/__tests__/isPlainObject.test.d.ts.map +0 -1
  55. package/dist/__tests__/logic/appendErrors.test.d.ts +0 -2
  56. package/dist/__tests__/logic/appendErrors.test.d.ts.map +0 -1
  57. package/dist/__tests__/logic/createFormControl.test.d.ts +0 -2
  58. package/dist/__tests__/logic/createFormControl.test.d.ts.map +0 -1
  59. package/dist/__tests__/logic/generateId.test.d.ts +0 -2
  60. package/dist/__tests__/logic/generateId.test.d.ts.map +0 -1
  61. package/dist/__tests__/logic/getCheckboxValue.test.d.ts +0 -2
  62. package/dist/__tests__/logic/getCheckboxValue.test.d.ts.map +0 -1
  63. package/dist/__tests__/logic/getDirtyFields.test.d.ts +0 -2
  64. package/dist/__tests__/logic/getDirtyFields.test.d.ts.map +0 -1
  65. package/dist/__tests__/logic/getEventValue.test.d.ts +0 -2
  66. package/dist/__tests__/logic/getEventValue.test.d.ts.map +0 -1
  67. package/dist/__tests__/logic/getFieldValue.test.d.ts +0 -2
  68. package/dist/__tests__/logic/getFieldValue.test.d.ts.map +0 -1
  69. package/dist/__tests__/logic/getFieldValueAs.test.d.ts +0 -2
  70. package/dist/__tests__/logic/getFieldValueAs.test.d.ts.map +0 -1
  71. package/dist/__tests__/logic/getFocusFieldName.test.d.ts +0 -2
  72. package/dist/__tests__/logic/getFocusFieldName.test.d.ts.map +0 -1
  73. package/dist/__tests__/logic/getNodeParentName.test.d.ts +0 -2
  74. package/dist/__tests__/logic/getNodeParentName.test.d.ts.map +0 -1
  75. package/dist/__tests__/logic/getRadioValue.test.d.ts +0 -2
  76. package/dist/__tests__/logic/getRadioValue.test.d.ts.map +0 -1
  77. package/dist/__tests__/logic/getResolverOptions.test.d.ts +0 -2
  78. package/dist/__tests__/logic/getResolverOptions.test.d.ts.map +0 -1
  79. package/dist/__tests__/logic/getRuleValue.test.d.ts +0 -2
  80. package/dist/__tests__/logic/getRuleValue.test.d.ts.map +0 -1
  81. package/dist/__tests__/logic/getValidateError.test.d.ts +0 -2
  82. package/dist/__tests__/logic/getValidateError.test.d.ts.map +0 -1
  83. package/dist/__tests__/logic/getValidationModes.test.d.ts +0 -2
  84. package/dist/__tests__/logic/getValidationModes.test.d.ts.map +0 -1
  85. package/dist/__tests__/logic/getValueAndMessage.test.d.ts +0 -2
  86. package/dist/__tests__/logic/getValueAndMessage.test.d.ts.map +0 -1
  87. package/dist/__tests__/logic/hasPromiseValidation.test.d.ts +0 -2
  88. package/dist/__tests__/logic/hasPromiseValidation.test.d.ts.map +0 -1
  89. package/dist/__tests__/logic/hasValidation.test.d.ts +0 -2
  90. package/dist/__tests__/logic/hasValidation.test.d.ts.map +0 -1
  91. package/dist/__tests__/logic/isNameInFieldArray.test.d.ts +0 -2
  92. package/dist/__tests__/logic/isNameInFieldArray.test.d.ts.map +0 -1
  93. package/dist/__tests__/logic/isWatched.test.d.ts +0 -2
  94. package/dist/__tests__/logic/isWatched.test.d.ts.map +0 -1
  95. package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts +0 -2
  96. package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts.map +0 -1
  97. package/dist/__tests__/logic/schemaErrorLookup.test.d.ts +0 -2
  98. package/dist/__tests__/logic/schemaErrorLookup.test.d.ts.map +0 -1
  99. package/dist/__tests__/logic/shouldRenderFormState.test.d.ts +0 -2
  100. package/dist/__tests__/logic/shouldRenderFormState.test.d.ts.map +0 -1
  101. package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts +0 -2
  102. package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts.map +0 -1
  103. package/dist/__tests__/logic/skipValidation.test.d.ts +0 -2
  104. package/dist/__tests__/logic/skipValidation.test.d.ts.map +0 -1
  105. package/dist/__tests__/logic/unsetEmptyArray.test.d.ts +0 -2
  106. package/dist/__tests__/logic/unsetEmptyArray.test.d.ts.map +0 -1
  107. package/dist/__tests__/logic/validateField.test.d.ts +0 -2
  108. package/dist/__tests__/logic/validateField.test.d.ts.map +0 -1
  109. package/dist/__tests__/type.test.d.ts +0 -2
  110. package/dist/__tests__/type.test.d.ts.map +0 -1
  111. package/dist/__tests__/useController.test.d.ts +0 -2
  112. package/dist/__tests__/useController.test.d.ts.map +0 -1
  113. package/dist/__tests__/useFieldArray/append.test.d.ts +0 -2
  114. package/dist/__tests__/useFieldArray/append.test.d.ts.map +0 -1
  115. package/dist/__tests__/useFieldArray/focus.test.d.ts +0 -2
  116. package/dist/__tests__/useFieldArray/focus.test.d.ts.map +0 -1
  117. package/dist/__tests__/useFieldArray/insert.test.d.ts +0 -2
  118. package/dist/__tests__/useFieldArray/insert.test.d.ts.map +0 -1
  119. package/dist/__tests__/useFieldArray/move.test.d.ts +0 -2
  120. package/dist/__tests__/useFieldArray/move.test.d.ts.map +0 -1
  121. package/dist/__tests__/useFieldArray/prepend.test.d.ts +0 -2
  122. package/dist/__tests__/useFieldArray/prepend.test.d.ts.map +0 -1
  123. package/dist/__tests__/useFieldArray/remove.test.d.ts +0 -2
  124. package/dist/__tests__/useFieldArray/remove.test.d.ts.map +0 -1
  125. package/dist/__tests__/useFieldArray/replace.test.d.ts +0 -2
  126. package/dist/__tests__/useFieldArray/replace.test.d.ts.map +0 -1
  127. package/dist/__tests__/useFieldArray/swap.test.d.ts +0 -2
  128. package/dist/__tests__/useFieldArray/swap.test.d.ts.map +0 -1
  129. package/dist/__tests__/useFieldArray/update.test.d.ts +0 -2
  130. package/dist/__tests__/useFieldArray/update.test.d.ts.map +0 -1
  131. package/dist/__tests__/useFieldArray.test.d.ts +0 -2
  132. package/dist/__tests__/useFieldArray.test.d.ts.map +0 -1
  133. package/dist/__tests__/useForm/clearErrors.test.d.ts +0 -2
  134. package/dist/__tests__/useForm/clearErrors.test.d.ts.map +0 -1
  135. package/dist/__tests__/useForm/formState.test.d.ts +0 -2
  136. package/dist/__tests__/useForm/formState.test.d.ts.map +0 -1
  137. package/dist/__tests__/useForm/getFieldState.test.d.ts +0 -2
  138. package/dist/__tests__/useForm/getFieldState.test.d.ts.map +0 -1
  139. package/dist/__tests__/useForm/getValues.test.d.ts +0 -2
  140. package/dist/__tests__/useForm/getValues.test.d.ts.map +0 -1
  141. package/dist/__tests__/useForm/handleSubmit.test.d.ts +0 -2
  142. package/dist/__tests__/useForm/handleSubmit.test.d.ts.map +0 -1
  143. package/dist/__tests__/useForm/register.test.d.ts +0 -2
  144. package/dist/__tests__/useForm/register.test.d.ts.map +0 -1
  145. package/dist/__tests__/useForm/reset.test.d.ts +0 -2
  146. package/dist/__tests__/useForm/reset.test.d.ts.map +0 -1
  147. package/dist/__tests__/useForm/resetField.test.d.ts +0 -2
  148. package/dist/__tests__/useForm/resetField.test.d.ts.map +0 -1
  149. package/dist/__tests__/useForm/resolver.test.d.ts +0 -2
  150. package/dist/__tests__/useForm/resolver.test.d.ts.map +0 -1
  151. package/dist/__tests__/useForm/setError.test.d.ts +0 -2
  152. package/dist/__tests__/useForm/setError.test.d.ts.map +0 -1
  153. package/dist/__tests__/useForm/setFocus.test.d.ts +0 -2
  154. package/dist/__tests__/useForm/setFocus.test.d.ts.map +0 -1
  155. package/dist/__tests__/useForm/setValue.test.d.ts +0 -2
  156. package/dist/__tests__/useForm/setValue.test.d.ts.map +0 -1
  157. package/dist/__tests__/useForm/subscribe.test.d.ts +0 -2
  158. package/dist/__tests__/useForm/subscribe.test.d.ts.map +0 -1
  159. package/dist/__tests__/useForm/trigger.test.d.ts +0 -2
  160. package/dist/__tests__/useForm/trigger.test.d.ts.map +0 -1
  161. package/dist/__tests__/useForm/unregister.test.d.ts +0 -2
  162. package/dist/__tests__/useForm/unregister.test.d.ts.map +0 -1
  163. package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts +0 -2
  164. package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts.map +0 -1
  165. package/dist/__tests__/useForm/watch.test.d.ts +0 -2
  166. package/dist/__tests__/useForm/watch.test.d.ts.map +0 -1
  167. package/dist/__tests__/useForm.server.test.d.ts +0 -2
  168. package/dist/__tests__/useForm.server.test.d.ts.map +0 -1
  169. package/dist/__tests__/useForm.test.d.ts +0 -2
  170. package/dist/__tests__/useForm.test.d.ts.map +0 -1
  171. package/dist/__tests__/useFormContext.server.test.d.ts +0 -2
  172. package/dist/__tests__/useFormContext.server.test.d.ts.map +0 -1
  173. package/dist/__tests__/useFormContext.test.d.ts +0 -2
  174. package/dist/__tests__/useFormContext.test.d.ts.map +0 -1
  175. package/dist/__tests__/useFormState.test.d.ts +0 -2
  176. package/dist/__tests__/useFormState.test.d.ts.map +0 -1
  177. package/dist/__tests__/useWatch.test.d.ts +0 -2
  178. package/dist/__tests__/useWatch.test.d.ts.map +0 -1
  179. package/dist/__tests__/utils/append.test.d.ts +0 -2
  180. package/dist/__tests__/utils/append.test.d.ts.map +0 -1
  181. package/dist/__tests__/utils/cloneObject.test.d.ts +0 -2
  182. package/dist/__tests__/utils/cloneObject.test.d.ts.map +0 -1
  183. package/dist/__tests__/utils/compact.test.d.ts +0 -2
  184. package/dist/__tests__/utils/compact.test.d.ts.map +0 -1
  185. package/dist/__tests__/utils/convertToArrayPayload.test.d.ts +0 -2
  186. package/dist/__tests__/utils/convertToArrayPayload.test.d.ts.map +0 -1
  187. package/dist/__tests__/utils/createSubject.test.d.ts +0 -2
  188. package/dist/__tests__/utils/createSubject.test.d.ts.map +0 -1
  189. package/dist/__tests__/utils/deepEqual.test.d.ts +0 -2
  190. package/dist/__tests__/utils/deepEqual.test.d.ts.map +0 -1
  191. package/dist/__tests__/utils/deepMerge.test.d.ts +0 -2
  192. package/dist/__tests__/utils/deepMerge.test.d.ts.map +0 -1
  193. package/dist/__tests__/utils/extractFormValues.test.d.ts +0 -2
  194. package/dist/__tests__/utils/extractFormValues.test.d.ts.map +0 -1
  195. package/dist/__tests__/utils/fillEmptyArray.test.d.ts +0 -2
  196. package/dist/__tests__/utils/fillEmptyArray.test.d.ts.map +0 -1
  197. package/dist/__tests__/utils/flatten.test.d.ts +0 -2
  198. package/dist/__tests__/utils/flatten.test.d.ts.map +0 -1
  199. package/dist/__tests__/utils/get.test.d.ts +0 -2
  200. package/dist/__tests__/utils/get.test.d.ts.map +0 -1
  201. package/dist/__tests__/utils/insert.test.d.ts +0 -2
  202. package/dist/__tests__/utils/insert.test.d.ts.map +0 -1
  203. package/dist/__tests__/utils/isBoolean.test.d.ts +0 -2
  204. package/dist/__tests__/utils/isBoolean.test.d.ts.map +0 -1
  205. package/dist/__tests__/utils/isCheckBoxInput.test.d.ts +0 -2
  206. package/dist/__tests__/utils/isCheckBoxInput.test.d.ts.map +0 -1
  207. package/dist/__tests__/utils/isEmptyObject.test.d.ts +0 -2
  208. package/dist/__tests__/utils/isEmptyObject.test.d.ts.map +0 -1
  209. package/dist/__tests__/utils/isFileInput.test.d.ts +0 -2
  210. package/dist/__tests__/utils/isFileInput.test.d.ts.map +0 -1
  211. package/dist/__tests__/utils/isFunction.test.d.ts +0 -2
  212. package/dist/__tests__/utils/isFunction.test.d.ts.map +0 -1
  213. package/dist/__tests__/utils/isHTMLElement.test.d.ts +0 -2
  214. package/dist/__tests__/utils/isHTMLElement.test.d.ts.map +0 -1
  215. package/dist/__tests__/utils/isKey.test.d.ts +0 -2
  216. package/dist/__tests__/utils/isKey.test.d.ts.map +0 -1
  217. package/dist/__tests__/utils/isMultipleSelect.test.d.ts +0 -2
  218. package/dist/__tests__/utils/isMultipleSelect.test.d.ts.map +0 -1
  219. package/dist/__tests__/utils/isNullOrUndefined.test.d.ts +0 -2
  220. package/dist/__tests__/utils/isNullOrUndefined.test.d.ts.map +0 -1
  221. package/dist/__tests__/utils/isObject.test.d.ts +0 -2
  222. package/dist/__tests__/utils/isObject.test.d.ts.map +0 -1
  223. package/dist/__tests__/utils/isPrimitive.test.d.ts +0 -2
  224. package/dist/__tests__/utils/isPrimitive.test.d.ts.map +0 -1
  225. package/dist/__tests__/utils/isRadioInput.test.d.ts +0 -2
  226. package/dist/__tests__/utils/isRadioInput.test.d.ts.map +0 -1
  227. package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts +0 -2
  228. package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts.map +0 -1
  229. package/dist/__tests__/utils/isRegex.test.d.ts +0 -2
  230. package/dist/__tests__/utils/isRegex.test.d.ts.map +0 -1
  231. package/dist/__tests__/utils/isString.test.d.ts +0 -2
  232. package/dist/__tests__/utils/isString.test.d.ts.map +0 -1
  233. package/dist/__tests__/utils/isUndefined.test.d.ts +0 -2
  234. package/dist/__tests__/utils/isUndefined.test.d.ts.map +0 -1
  235. package/dist/__tests__/utils/live.test.d.ts +0 -2
  236. package/dist/__tests__/utils/live.test.d.ts.map +0 -1
  237. package/dist/__tests__/utils/move.test.d.ts +0 -2
  238. package/dist/__tests__/utils/move.test.d.ts.map +0 -1
  239. package/dist/__tests__/utils/noop.test.d.ts +0 -2
  240. package/dist/__tests__/utils/noop.test.d.ts.map +0 -1
  241. package/dist/__tests__/utils/objectHasFunction.test.d.ts +0 -2
  242. package/dist/__tests__/utils/objectHasFunction.test.d.ts.map +0 -1
  243. package/dist/__tests__/utils/prepend.test.d.ts +0 -2
  244. package/dist/__tests__/utils/prepend.test.d.ts.map +0 -1
  245. package/dist/__tests__/utils/remove.test.d.ts +0 -2
  246. package/dist/__tests__/utils/remove.test.d.ts.map +0 -1
  247. package/dist/__tests__/utils/set.test.d.ts +0 -2
  248. package/dist/__tests__/utils/set.test.d.ts.map +0 -1
  249. package/dist/__tests__/utils/stringToPath.test.d.ts +0 -2
  250. package/dist/__tests__/utils/stringToPath.test.d.ts.map +0 -1
  251. package/dist/__tests__/utils/swap.test.d.ts +0 -2
  252. package/dist/__tests__/utils/swap.test.d.ts.map +0 -1
  253. package/dist/__tests__/utils/unset.test.d.ts +0 -2
  254. package/dist/__tests__/utils/unset.test.d.ts.map +0 -1
  255. package/dist/__tests__/utils/validationModeChecker.test.d.ts +0 -2
  256. package/dist/__tests__/utils/validationModeChecker.test.d.ts.map +0 -1
  257. package/dist/__tests__/watch.server.test.d.ts +0 -2
  258. package/dist/__tests__/watch.server.test.d.ts.map +0 -1
  259. package/dist/__tests__/watch.test.d.ts +0 -2
  260. package/dist/__tests__/watch.test.d.ts.map +0 -1
  261. package/dist/logic/isNameInFieldArray.d.ts.map +0 -1
@@ -10,7 +10,11 @@ var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => va
10
10
 
11
11
  const EVENTS = {
12
12
  BLUR: 'blur',
13
- FOCUS_OUT: 'focusout'};
13
+ FOCUS_OUT: 'focusout',
14
+ SUBMIT: 'submit',
15
+ TRIGGER: 'trigger',
16
+ VALID: 'valid',
17
+ };
14
18
  const VALIDATION_MODE = {
15
19
  onBlur: 'onBlur',
16
20
  onChange: 'onChange',
@@ -27,6 +31,8 @@ const INPUT_VALIDATION_RULES = {
27
31
  required: 'required',
28
32
  validate: 'validate',
29
33
  };
34
+ const FORM_ERROR_TYPE = 'form';
35
+ const ROOT_ERROR_TYPE = 'root';
30
36
 
31
37
  var isDateObject = (value) => value instanceof Date;
32
38
 
@@ -102,7 +108,10 @@ var createSubject = () => {
102
108
 
103
109
  var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
104
110
 
105
- function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
111
+ function deepEqual(object1, object2, visited = new WeakSet()) {
112
+ if (object1 === object2) {
113
+ return true;
114
+ }
106
115
  if (isPrimitive(object1) || isPrimitive(object2)) {
107
116
  return Object.is(object1, object2);
108
117
  }
@@ -114,22 +123,22 @@ function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
114
123
  if (keys1.length !== keys2.length) {
115
124
  return false;
116
125
  }
117
- if (_internal_visited.has(object1) || _internal_visited.has(object2)) {
126
+ if (visited.has(object1) || visited.has(object2)) {
118
127
  return true;
119
128
  }
120
- _internal_visited.add(object1);
121
- _internal_visited.add(object2);
129
+ visited.add(object1);
130
+ visited.add(object2);
122
131
  for (const key of keys1) {
123
132
  const val1 = object1[key];
124
- if (!keys2.includes(key)) {
133
+ if (!(key in object2)) {
125
134
  return false;
126
135
  }
127
136
  if (key !== 'ref') {
128
137
  const val2 = object2[key];
129
138
  if ((isDateObject(val1) && isDateObject(val2)) ||
130
- (isObject(val1) && isObject(val2)) ||
131
- (Array.isArray(val1) && Array.isArray(val2))
132
- ? !deepEqual(val1, val2, _internal_visited)
139
+ ((isObject(val1) || Array.isArray(val1)) &&
140
+ (isObject(val2) || Array.isArray(val2)))
141
+ ? !deepEqual(val1, val2, visited)
133
142
  : !Object.is(val1, val2)) {
134
143
  return false;
135
144
  }
@@ -168,7 +177,10 @@ var get = (object, path, defaultValue) => {
168
177
  if (!path || !isObject(object)) {
169
178
  return defaultValue;
170
179
  }
171
- const result = (isKey(path) ? [path] : stringToPath(path)).reduce((result, key) => isNullOrUndefined(result) ? result : result[key], object);
180
+ const paths = isKey(path) ? [path] : stringToPath(path);
181
+ const result = paths.reduce((result, key) => {
182
+ return isNullOrUndefined(result) ? undefined : result[key];
183
+ }, object);
172
184
  return isUndefined(result) || result === object
173
185
  ? isUndefined(object[path])
174
186
  ? defaultValue
@@ -234,7 +246,12 @@ function baseGet(object, updatePath) {
234
246
  const length = updatePath.slice(0, -1).length;
235
247
  let index = 0;
236
248
  while (index < length) {
237
- object = isUndefined(object) ? index++ : object[updatePath[index++]];
249
+ if (isNullOrUndefined(object)) {
250
+ object = undefined;
251
+ break;
252
+ }
253
+ object = object[updatePath[index]];
254
+ index++;
238
255
  }
239
256
  return object;
240
257
  }
@@ -247,6 +264,10 @@ function isEmptyArray(obj) {
247
264
  return true;
248
265
  }
249
266
  function unset(object, path) {
267
+ if (isString(path) && Object.prototype.hasOwnProperty.call(object, path)) {
268
+ delete object[path];
269
+ return object;
270
+ }
250
271
  const paths = Array.isArray(path)
251
272
  ? path
252
273
  : isKey(path)
@@ -304,6 +325,29 @@ function markFieldsDirty(data, fields = {}) {
304
325
  }
305
326
  return fields;
306
327
  }
328
+ function pruneDirtyFields(value) {
329
+ if (value === false) {
330
+ return undefined;
331
+ }
332
+ if (value === true) {
333
+ return true;
334
+ }
335
+ if (Array.isArray(value)) {
336
+ const result = value.map((value) => pruneDirtyFields(value));
337
+ return (result.some((value) => value !== undefined) ? result : undefined);
338
+ }
339
+ if (isObject(value)) {
340
+ const result = {};
341
+ for (const key in value) {
342
+ const pruned = pruneDirtyFields(value[key]);
343
+ if (!isUndefined(pruned)) {
344
+ result[key] = pruned;
345
+ }
346
+ }
347
+ return (Object.keys(result).length ? result : undefined);
348
+ }
349
+ return undefined;
350
+ }
307
351
  function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
308
352
  if (!dirtyFieldsFromValues) {
309
353
  dirtyFieldsFromValues = markFieldsDirty(formValues);
@@ -323,7 +367,7 @@ function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
323
367
  dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
324
368
  }
325
369
  }
326
- return dirtyFieldsFromValues;
370
+ return pruneDirtyFields(dirtyFieldsFromValues) || {};
327
371
  }
328
372
 
329
373
  var getEventValue = (event) => isObject(event) && event.target
@@ -332,6 +376,16 @@ var getEventValue = (event) => isObject(event) && event.target
332
376
  : event.target.value
333
377
  : event;
334
378
 
379
+ var getFieldArrayParentNames = (names, name) => {
380
+ const parts = name.split('.');
381
+ const matches = [];
382
+ let prefix = parts[0];
383
+ for (let i = 1; i < parts.length; prefix += '.' + parts[i++]) {
384
+ !isNaN(+parts[i]) && names.has(prefix) && matches.push(prefix);
385
+ }
386
+ return matches;
387
+ };
388
+
335
389
  const defaultResult = {
336
390
  value: false,
337
391
  isValid: false,
@@ -452,10 +506,6 @@ var hasValidation = (options) => options.mount &&
452
506
  options.pattern ||
453
507
  options.validate);
454
508
 
455
- var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
456
-
457
- var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
458
-
459
509
  var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
460
510
  (_names.watchAll ||
461
511
  _names.watch.has(name) ||
@@ -529,7 +579,8 @@ var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, is
529
579
  updateFormState(formStateData);
530
580
  const { name, ...formState } = formStateData;
531
581
  return (isEmptyObject(formState) ||
532
- Object.keys(formState).length >= Object.keys(_proxyFormState).length ||
582
+ (isRoot &&
583
+ Object.keys(formState).length >= Object.keys(_proxyFormState).length) ||
533
584
  Object.keys(formState).find((key) => _proxyFormState[key] ===
534
585
  (!isRoot || VALIDATION_MODE.all)));
535
586
  };
@@ -563,7 +614,7 @@ var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(re
563
614
 
564
615
  var updateFieldArrayRootError = (errors, error, name) => {
565
616
  const fieldArrayErrors = convertToArrayPayload(get(errors, name));
566
- set(fieldArrayErrors, 'root', error[name]);
617
+ set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
567
618
  set(errors, name, fieldArrayErrors);
568
619
  return errors;
569
620
  };
@@ -609,7 +660,8 @@ var validateField = async (field, disabledFieldNames, formValues, validateAllFie
609
660
  isUndefined(inputValue)) ||
610
661
  (isHTMLElement(ref) && ref.value === '') ||
611
662
  inputValue === '' ||
612
- (Array.isArray(inputValue) && !inputValue.length);
663
+ (Array.isArray(inputValue) && !inputValue.length) ||
664
+ (valueAsNumber && typeof inputValue === 'number' && isNaN(inputValue));
613
665
  const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
614
666
  const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
615
667
  const message = exceedMax ? maxLengthMessage : minLengthMessage;
@@ -771,24 +823,27 @@ const defaultOptions = {
771
823
  reValidateMode: VALIDATION_MODE.onChange,
772
824
  shouldFocusError: true,
773
825
  };
826
+ const DEFAULT_FORM_STATE = {
827
+ submitCount: 0,
828
+ isDirty: false,
829
+ isReady: false,
830
+ isValidating: false,
831
+ isSubmitted: false,
832
+ isSubmitting: false,
833
+ isSubmitSuccessful: false,
834
+ isValid: false,
835
+ touchedFields: {},
836
+ dirtyFields: {},
837
+ validatingFields: {},
838
+ };
774
839
  function createFormControl(props = {}) {
775
840
  let _options = {
776
841
  ...defaultOptions,
777
842
  ...props,
778
843
  };
779
844
  let _formState = {
780
- submitCount: 0,
781
- isDirty: false,
782
- isReady: false,
845
+ ...cloneObject(DEFAULT_FORM_STATE),
783
846
  isLoading: isFunction(_options.defaultValues),
784
- isValidating: false,
785
- isSubmitted: false,
786
- isSubmitting: false,
787
- isSubmitSuccessful: false,
788
- isValid: false,
789
- touchedFields: {},
790
- dirtyFields: {},
791
- validatingFields: {},
792
847
  errors: _options.errors || {},
793
848
  disabled: _options.disabled || false,
794
849
  };
@@ -811,6 +866,7 @@ function createFormControl(props = {}) {
811
866
  unMount: new Set(),
812
867
  array: new Set(),
813
868
  watch: new Set(),
869
+ registerName: new Set(),
814
870
  };
815
871
  let delayErrorCallback;
816
872
  let timer = 0;
@@ -852,7 +908,11 @@ function createFormControl(props = {}) {
852
908
  _updateIsValidating();
853
909
  }
854
910
  else {
855
- isValid = await executeBuiltInValidation(_fields, true);
911
+ isValid = await executeBuiltInValidation({
912
+ fields: _fields,
913
+ onlyCheckValid: true,
914
+ eventType: EVENTS.VALID,
915
+ });
856
916
  }
857
917
  if (isValid !== _formState.isValid) {
858
918
  _subjects.state.next({
@@ -880,6 +940,9 @@ function createFormControl(props = {}) {
880
940
  });
881
941
  }
882
942
  };
943
+ const _updateDirtyFields = () => {
944
+ _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
945
+ };
883
946
  const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
884
947
  if (args && method && !_options.disabled) {
885
948
  _state.action = true;
@@ -901,7 +964,7 @@ function createFormControl(props = {}) {
901
964
  shouldSetValues && set(_formState.touchedFields, name, touchedFields);
902
965
  }
903
966
  if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
904
- _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
967
+ _updateDirtyFields();
905
968
  }
906
969
  _subjects.state.next({
907
970
  name,
@@ -928,16 +991,53 @@ function createFormControl(props = {}) {
928
991
  isValid: false,
929
992
  });
930
993
  };
994
+ const hasExplicitNullIntermediate = (name) => {
995
+ const segments = isKey(name) ? [name] : stringToPath(name);
996
+ let formValues = _formValues;
997
+ let defaultValues = _defaultValues;
998
+ for (let i = 0; i < segments.length - 1; i++) {
999
+ const key = segments[i];
1000
+ formValues = isNullOrUndefined(formValues) ? formValues : formValues[key];
1001
+ defaultValues = isNullOrUndefined(defaultValues)
1002
+ ? defaultValues
1003
+ : defaultValues[key];
1004
+ if (formValues === null && defaultValues !== null) {
1005
+ return true;
1006
+ }
1007
+ }
1008
+ return false;
1009
+ };
931
1010
  const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
932
1011
  const field = get(_fields, name);
933
1012
  if (field) {
1013
+ if (hasExplicitNullIntermediate(name)) {
1014
+ return;
1015
+ }
1016
+ const wasUnsetInFormValues = isUndefined(get(_formValues, name));
934
1017
  const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
935
1018
  isUndefined(defaultValue) ||
936
1019
  (ref && ref.defaultChecked) ||
937
1020
  shouldSkipSetValueAs
938
1021
  ? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
939
1022
  : setFieldValue(name, defaultValue);
940
- _state.mount && !_state.action && _setValid();
1023
+ if (_state.mount && !_state.action) {
1024
+ _setValid();
1025
+ // Re-registering a field after a prior unregister puts its key back
1026
+ // into _formValues, which can flip isDirty back to false (#13397).
1027
+ // Only run when we are currently dirty, otherwise an initial register
1028
+ // for a field with no defaultValue would flip isDirty to true. Reset
1029
+ // paths repopulate _formValues before re-register, so the key is
1030
+ // present then and this branch is skipped (preserves keepDirty).
1031
+ if (wasUnsetInFormValues &&
1032
+ _formState.isDirty &&
1033
+ (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty)) {
1034
+ const isDirty = _getDirty();
1035
+ if (!isDirty) {
1036
+ _formState.isDirty = false;
1037
+ _subjects.state.next({ ..._formState });
1038
+ }
1039
+ }
1040
+ }
941
1041
  }
942
1042
  };
943
1043
  const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
@@ -955,9 +1055,14 @@ function createFormControl(props = {}) {
955
1055
  }
956
1056
  const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
957
1057
  isPreviousDirty = !!get(_formState.dirtyFields, name);
958
- isCurrentFieldPristine
959
- ? unset(_formState.dirtyFields, name)
960
- : set(_formState.dirtyFields, name, true);
1058
+ if (isCurrentFieldPristine !== _formState.isDirty) {
1059
+ _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1060
+ }
1061
+ else {
1062
+ isCurrentFieldPristine
1063
+ ? unset(_formState.dirtyFields, name)
1064
+ : set(_formState.dirtyFields, name, true);
1065
+ }
961
1066
  output.dirtyFields = _formState.dirtyFields;
962
1067
  shouldUpdateField =
963
1068
  shouldUpdateField ||
@@ -1015,8 +1120,7 @@ function createFormControl(props = {}) {
1015
1120
  };
1016
1121
  const _runSchema = async (name) => {
1017
1122
  _updateIsValidating(name, true);
1018
- const result = await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1019
- return result;
1123
+ return await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1020
1124
  };
1021
1125
  const executeSchemaAndUpdateState = async (names) => {
1022
1126
  const { errors } = await _runSchema(names);
@@ -1025,7 +1129,9 @@ function createFormControl(props = {}) {
1025
1129
  for (const name of names) {
1026
1130
  const error = get(errors, name);
1027
1131
  error
1028
- ? set(_formState.errors, name, error)
1132
+ ? _names.array.has(name) && isObject(error)
1133
+ ? updateFieldArrayRootError(_formState.errors, { [name]: error }, name)
1134
+ : set(_formState.errors, name, error)
1029
1135
  : unset(_formState.errors, name);
1030
1136
  }
1031
1137
  }
@@ -1034,9 +1140,55 @@ function createFormControl(props = {}) {
1034
1140
  }
1035
1141
  return errors;
1036
1142
  };
1037
- const executeBuiltInValidation = async (fields, shouldOnlyCheckValid, context = {
1143
+ const validateForm = async ({ name, eventType, }) => {
1144
+ if (props.validate) {
1145
+ const result = await props.validate({
1146
+ formValues: _formValues,
1147
+ formState: _formState,
1148
+ name,
1149
+ eventType,
1150
+ });
1151
+ if (isObject(result)) {
1152
+ for (const key in result) {
1153
+ const error = result[key];
1154
+ if (error) {
1155
+ setError(`${FORM_ERROR_TYPE}.${key}`, {
1156
+ message: isString(error.message) ? error.message : '',
1157
+ type: error.type || INPUT_VALIDATION_RULES.validate,
1158
+ });
1159
+ }
1160
+ }
1161
+ }
1162
+ else if (isString(result) || !result) {
1163
+ setError(FORM_ERROR_TYPE, {
1164
+ message: result || '',
1165
+ type: INPUT_VALIDATION_RULES.validate,
1166
+ });
1167
+ }
1168
+ else {
1169
+ clearErrors(FORM_ERROR_TYPE);
1170
+ }
1171
+ return result;
1172
+ }
1173
+ return true;
1174
+ };
1175
+ const executeBuiltInValidation = async ({ fields, onlyCheckValid, name, eventType, context = {
1038
1176
  valid: true,
1039
- }) => {
1177
+ runRootValidation: false,
1178
+ }, }) => {
1179
+ if (props.validate) {
1180
+ context.runRootValidation = true;
1181
+ const result = await validateForm({
1182
+ name,
1183
+ eventType,
1184
+ });
1185
+ if (!result) {
1186
+ context.valid = false;
1187
+ if (onlyCheckValid) {
1188
+ return context.valid;
1189
+ }
1190
+ }
1191
+ }
1040
1192
  for (const name in fields) {
1041
1193
  const field = fields[name];
1042
1194
  if (field) {
@@ -1044,28 +1196,41 @@ function createFormControl(props = {}) {
1044
1196
  if (_f) {
1045
1197
  const isFieldArrayRoot = _names.array.has(_f.name);
1046
1198
  const isPromiseFunction = field._f && hasPromiseValidation(field._f);
1047
- if (isPromiseFunction && _proxyFormState.validatingFields) {
1199
+ const shouldTrackIsValidatingState = _proxyFormState.validatingFields ||
1200
+ _proxyFormState.isValidating ||
1201
+ _proxySubscribeFormState.validatingFields ||
1202
+ _proxySubscribeFormState.isValidating;
1203
+ if (isPromiseFunction && shouldTrackIsValidatingState) {
1048
1204
  _updateIsValidating([_f.name], true);
1049
1205
  }
1050
- const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
1051
- if (isPromiseFunction && _proxyFormState.validatingFields) {
1206
+ const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
1207
+ if (isPromiseFunction && shouldTrackIsValidatingState) {
1052
1208
  _updateIsValidating([_f.name]);
1053
1209
  }
1054
1210
  if (fieldError[_f.name]) {
1055
1211
  context.valid = false;
1056
- if (shouldOnlyCheckValid || props.shouldUseNativeValidation) {
1212
+ if (onlyCheckValid) {
1057
1213
  break;
1058
1214
  }
1059
1215
  }
1060
- !shouldOnlyCheckValid &&
1216
+ !onlyCheckValid &&
1061
1217
  (get(fieldError, _f.name)
1062
1218
  ? isFieldArrayRoot
1063
1219
  ? updateFieldArrayRootError(_formState.errors, fieldError, _f.name)
1064
1220
  : set(_formState.errors, _f.name, fieldError[_f.name])
1065
1221
  : unset(_formState.errors, _f.name));
1222
+ if (props.shouldUseNativeValidation && fieldError[_f.name]) {
1223
+ break;
1224
+ }
1066
1225
  }
1067
1226
  !isEmptyObject(fieldValue) &&
1068
- (await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context));
1227
+ (await executeBuiltInValidation({
1228
+ context,
1229
+ onlyCheckValid,
1230
+ fields: fieldValue,
1231
+ name: name,
1232
+ eventType,
1233
+ }));
1069
1234
  }
1070
1235
  }
1071
1236
  return context.valid;
@@ -1145,7 +1310,7 @@ function createFormControl(props = {}) {
1145
1310
  updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1146
1311
  options.shouldValidate && trigger(name);
1147
1312
  };
1148
- const setValues = (name, value, options) => {
1313
+ const setFieldValues = (name, value, options) => {
1149
1314
  for (const fieldKey in value) {
1150
1315
  if (!value.hasOwnProperty(fieldKey)) {
1151
1316
  return;
@@ -1157,7 +1322,7 @@ function createFormControl(props = {}) {
1157
1322
  isObject(fieldValue) ||
1158
1323
  (field && !field._f)) &&
1159
1324
  !isDateObject(fieldValue)
1160
- ? setValues(fieldName, fieldValue, options)
1325
+ ? setFieldValues(fieldName, fieldValue, options)
1161
1326
  : setFieldValue(fieldName, fieldValue, options);
1162
1327
  }
1163
1328
  };
@@ -1165,7 +1330,11 @@ function createFormControl(props = {}) {
1165
1330
  const field = get(_fields, name);
1166
1331
  const isFieldArray = _names.array.has(name);
1167
1332
  const cloneValue = cloneObject(value);
1168
- set(_formValues, name, cloneValue);
1333
+ const previousValue = get(_formValues, name);
1334
+ const isValueUnchanged = deepEqual(previousValue, cloneValue);
1335
+ if (!isValueUnchanged) {
1336
+ set(_formValues, name, cloneValue);
1337
+ }
1169
1338
  if (isFieldArray) {
1170
1339
  _subjects.array.next({
1171
1340
  name,
@@ -1176,30 +1345,52 @@ function createFormControl(props = {}) {
1176
1345
  _proxySubscribeFormState.isDirty ||
1177
1346
  _proxySubscribeFormState.dirtyFields) &&
1178
1347
  options.shouldDirty) {
1348
+ _updateDirtyFields();
1179
1349
  _subjects.state.next({
1180
1350
  name,
1181
- dirtyFields: getDirtyFields(_defaultValues, _formValues),
1351
+ dirtyFields: _formState.dirtyFields,
1182
1352
  isDirty: _getDirty(name, cloneValue),
1183
1353
  });
1184
1354
  }
1185
1355
  }
1186
1356
  else {
1187
- field && !field._f && !isNullOrUndefined(cloneValue)
1188
- ? setValues(name, cloneValue, options)
1189
- : setFieldValue(name, cloneValue, options);
1357
+ const isEmpty = (Array.isArray(cloneValue) && !cloneValue.length) ||
1358
+ isEmptyObject(cloneValue);
1359
+ if (!field || field._f || isNullOrUndefined(cloneValue) || isEmpty) {
1360
+ setFieldValue(name, cloneValue, options);
1361
+ }
1362
+ else {
1363
+ setFieldValues(name, cloneValue, options);
1364
+ }
1190
1365
  }
1191
- if (isWatched(name, _names)) {
1366
+ if (!isValueUnchanged) {
1367
+ const watched = isWatched(name, _names);
1368
+ const values = cloneObject(_formValues);
1369
+ if (!isFieldArray) {
1370
+ for (const arrayName of getFieldArrayParentNames(_names.array, name)) {
1371
+ _subjects.array.next({ name: arrayName, values });
1372
+ }
1373
+ }
1192
1374
  _subjects.state.next({
1193
- ..._formState,
1194
- name,
1195
- values: cloneObject(_formValues),
1375
+ ...(watched && _formState),
1376
+ name: _state.mount || watched ? name : undefined,
1377
+ values,
1196
1378
  });
1197
1379
  }
1198
- else {
1199
- _subjects.state.next({
1200
- name: _state.mount ? name : undefined,
1201
- values: cloneObject(_formValues),
1202
- });
1380
+ };
1381
+ const setValues = (formValues) => {
1382
+ const updatedFormValues = isFunction(formValues)
1383
+ ? formValues(_formValues)
1384
+ : formValues;
1385
+ if (!deepEqual(_formValues, updatedFormValues)) {
1386
+ _formValues = {
1387
+ ..._formValues,
1388
+ ...updatedFormValues,
1389
+ };
1390
+ for (const fieldName of _names.mount) {
1391
+ setValue(fieldName, get(updatedFormValues, fieldName));
1392
+ }
1393
+ _subjects.state.next({ ..._formState, values: _formValues });
1203
1394
  }
1204
1395
  };
1205
1396
  const onChange = async (event) => {
@@ -1224,6 +1415,7 @@ function createFormControl(props = {}) {
1224
1415
  : getEventValue(event);
1225
1416
  const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
1226
1417
  const shouldSkipValidation = (!hasValidation(field._f) &&
1418
+ !props.validate &&
1227
1419
  !_options.resolver &&
1228
1420
  !get(_formState.errors, name) &&
1229
1421
  !field._f.deps) ||
@@ -1261,6 +1453,12 @@ function createFormControl(props = {}) {
1261
1453
  return (shouldRender &&
1262
1454
  _subjects.state.next({ name, ...(watched ? {} : fieldState) }));
1263
1455
  }
1456
+ if (!_options.resolver && props.validate) {
1457
+ await validateForm({
1458
+ name: name,
1459
+ eventType: event.type,
1460
+ });
1461
+ }
1264
1462
  !isBlurEvent && watched && _subjects.state.next({ ..._formState });
1265
1463
  if (_options.resolver) {
1266
1464
  const { errors } = await _runSchema([name]);
@@ -1285,7 +1483,12 @@ function createFormControl(props = {}) {
1285
1483
  }
1286
1484
  else if (_proxyFormState.isValid ||
1287
1485
  _proxySubscribeFormState.isValid) {
1288
- isValid = await executeBuiltInValidation(_fields, true);
1486
+ isValid = await executeBuiltInValidation({
1487
+ fields: _fields,
1488
+ onlyCheckValid: true,
1489
+ name: name,
1490
+ eventType: event.type,
1491
+ });
1289
1492
  }
1290
1493
  }
1291
1494
  }
@@ -1318,12 +1521,19 @@ function createFormControl(props = {}) {
1318
1521
  else if (name) {
1319
1522
  validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
1320
1523
  const field = get(_fields, fieldName);
1321
- return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
1524
+ return await executeBuiltInValidation({
1525
+ fields: field && field._f ? { [fieldName]: field } : field,
1526
+ eventType: EVENTS.TRIGGER,
1527
+ });
1322
1528
  }))).every(Boolean);
1323
1529
  !(!validationResult && !_formState.isValid) && _setValid();
1324
1530
  }
1325
1531
  else {
1326
- validationResult = isValid = await executeBuiltInValidation(_fields);
1532
+ validationResult = isValid = await executeBuiltInValidation({
1533
+ fields: _fields,
1534
+ name,
1535
+ eventType: EVENTS.TRIGGER,
1536
+ });
1327
1537
  }
1328
1538
  _subjects.state.next({
1329
1539
  ...(!isString(name) ||
@@ -1360,11 +1570,24 @@ function createFormControl(props = {}) {
1360
1570
  isTouched: !!get((formState || _formState).touchedFields, name),
1361
1571
  });
1362
1572
  const clearErrors = (name) => {
1363
- name &&
1364
- convertToArrayPayload(name).forEach((inputName) => unset(_formState.errors, inputName));
1365
- _subjects.state.next({
1366
- errors: name ? _formState.errors : {},
1367
- });
1573
+ const names = name ? convertToArrayPayload(name) : undefined;
1574
+ names?.forEach((inputName) => unset(_formState.errors, inputName));
1575
+ if (names) {
1576
+ // Emit for each cleared field with the field name so that
1577
+ // shouldSubscribeByName can filter and avoid broad re-renders
1578
+ names.forEach((inputName) => {
1579
+ _subjects.state.next({
1580
+ name: inputName,
1581
+ errors: _formState.errors,
1582
+ });
1583
+ });
1584
+ }
1585
+ else {
1586
+ // Clear all errors - emit without name to notify all subscribers
1587
+ _subjects.state.next({
1588
+ errors: {},
1589
+ });
1590
+ }
1368
1591
  };
1369
1592
  const setError = (name, error, options) => {
1370
1593
  const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
@@ -1388,8 +1611,9 @@ function createFormControl(props = {}) {
1388
1611
  next: (formState) => {
1389
1612
  if (shouldSubscribeByName(props.name, formState.name, props.exact) &&
1390
1613
  shouldRenderFormState(formState, props.formState || _proxyFormState, _setFormState, props.reRenderRoot)) {
1614
+ const snapshot = { ..._formValues };
1391
1615
  props.callback({
1392
- values: { ..._formValues },
1616
+ values: snapshot,
1393
1617
  ..._formState,
1394
1618
  ...formState,
1395
1619
  defaultValues: _defaultValues,
@@ -1451,6 +1675,7 @@ function createFormControl(props = {}) {
1451
1675
  const register = (name, options = {}) => {
1452
1676
  let field = get(_fields, name);
1453
1677
  const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
1678
+ const shouldRevalidateRemount = !_names.registerName.has(name) && field && field._f && !field._f.mount;
1454
1679
  set(_fields, name, {
1455
1680
  ...(field || {}),
1456
1681
  _f: {
@@ -1461,7 +1686,7 @@ function createFormControl(props = {}) {
1461
1686
  },
1462
1687
  });
1463
1688
  _names.mount.add(name);
1464
- if (field) {
1689
+ if (field && !shouldRevalidateRemount) {
1465
1690
  _setDisabledField({
1466
1691
  disabled: isBoolean(options.disabled)
1467
1692
  ? options.disabled
@@ -1491,7 +1716,9 @@ function createFormControl(props = {}) {
1491
1716
  onBlur: onChange,
1492
1717
  ref: (ref) => {
1493
1718
  if (ref) {
1719
+ _names.registerName.add(name);
1494
1720
  register(name, options);
1721
+ _names.registerName.delete(name);
1495
1722
  field = get(_fields, name);
1496
1723
  const fieldRef = isUndefined(ref.value)
1497
1724
  ? ref.querySelectorAll
@@ -1528,13 +1755,15 @@ function createFormControl(props = {}) {
1528
1755
  field._f.mount = false;
1529
1756
  }
1530
1757
  (_options.shouldUnregister || options.shouldUnregister) &&
1531
- !(isNameInFieldArray(_names.array, name) && _state.action) &&
1758
+ !(getFieldArrayParentNames(_names.array, name).length &&
1759
+ _state.action) &&
1532
1760
  _names.unMount.add(name);
1533
1761
  }
1534
1762
  },
1535
1763
  };
1536
1764
  };
1537
1765
  const _focusError = () => _options.shouldFocusError &&
1766
+ !_options.shouldUseNativeValidation &&
1538
1767
  iterateFieldsByAction(_fields, _focusInput, _names.mount);
1539
1768
  const _disableForm = (disabled) => {
1540
1769
  if (isBoolean(disabled)) {
@@ -1570,14 +1799,17 @@ function createFormControl(props = {}) {
1570
1799
  fieldValues = cloneObject(values);
1571
1800
  }
1572
1801
  else {
1573
- await executeBuiltInValidation(_fields);
1802
+ await executeBuiltInValidation({
1803
+ fields: _fields,
1804
+ eventType: EVENTS.SUBMIT,
1805
+ });
1574
1806
  }
1575
1807
  if (_names.disabled.size) {
1576
1808
  for (const name of _names.disabled) {
1577
1809
  unset(fieldValues, name);
1578
1810
  }
1579
1811
  }
1580
- unset(_formState.errors, 'root');
1812
+ unset(_formState.errors, ROOT_ERROR_TYPE);
1581
1813
  if (isEmptyObject(_formState.errors)) {
1582
1814
  _subjects.state.next({
1583
1815
  errors: {},
@@ -1701,6 +1933,7 @@ function createFormControl(props = {}) {
1701
1933
  mount: keepStateOptions.keepDirtyValues ? _names.mount : new Set(),
1702
1934
  unMount: new Set(),
1703
1935
  array: new Set(),
1936
+ registerName: new Set(),
1704
1937
  disabled: new Set(),
1705
1938
  watch: new Set(),
1706
1939
  watchAll: false,
@@ -1854,6 +2087,7 @@ function createFormControl(props = {}) {
1854
2087
  handleSubmit,
1855
2088
  watch,
1856
2089
  setValue,
2090
+ setValues,
1857
2091
  getValues,
1858
2092
  reset,
1859
2093
  resetField,