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.
- package/README.md +16 -29
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +395 -153
- package/dist/index.esm.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/logic/createFormControl.d.ts +13 -0
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/logic/getDirtyFields.d.ts.map +1 -1
- package/dist/logic/{isNameInFieldArray.d.ts → getFieldArrayParentNames.d.ts} +2 -2
- package/dist/logic/getFieldArrayParentNames.d.ts.map +1 -0
- package/dist/logic/getProxyFormState.d.ts.map +1 -1
- package/dist/logic/getResolverOptions.d.ts +2 -2
- package/dist/logic/hasValidation.d.ts +1 -1
- package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
- package/dist/logic/updateFieldArrayRootError.d.ts.map +1 -1
- package/dist/logic/validateField.d.ts.map +1 -1
- package/dist/react-server.esm.mjs +310 -76
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/types/errors.d.ts +1 -0
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/form.d.ts +12 -5
- package/dist/types/form.d.ts.map +1 -1
- package/dist/types/path/eager.d.ts +1 -1
- package/dist/types/path/eager.d.ts.map +1 -1
- package/dist/types/utils.d.ts +2 -2
- package/dist/types/validator.d.ts +13 -1
- package/dist/types/validator.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useForm.d.ts.map +1 -1
- package/dist/useFormContext.d.ts.map +1 -1
- package/dist/useFormState.d.ts.map +1 -1
- package/dist/utils/deepEqual.d.ts +1 -1
- package/dist/utils/deepEqual.d.ts.map +1 -1
- package/dist/utils/unset.d.ts.map +1 -1
- package/dist/watch.d.ts +1 -1
- package/dist/watch.d.ts.map +1 -1
- package/package.json +25 -26
- package/dist/__tests__/controller.server.test.d.ts +0 -2
- package/dist/__tests__/controller.server.test.d.ts.map +0 -1
- package/dist/__tests__/controller.test.d.ts +0 -2
- package/dist/__tests__/controller.test.d.ts.map +0 -1
- package/dist/__tests__/form.test.d.ts +0 -2
- package/dist/__tests__/form.test.d.ts.map +0 -1
- package/dist/__tests__/formStateSubscribe.server.test.d.ts +0 -2
- package/dist/__tests__/formStateSubscribe.server.test.d.ts.map +0 -1
- package/dist/__tests__/formStateSubscribe.test.d.ts +0 -2
- package/dist/__tests__/formStateSubscribe.test.d.ts.map +0 -1
- package/dist/__tests__/isPlainObject.test.d.ts +0 -2
- package/dist/__tests__/isPlainObject.test.d.ts.map +0 -1
- package/dist/__tests__/logic/appendErrors.test.d.ts +0 -2
- package/dist/__tests__/logic/appendErrors.test.d.ts.map +0 -1
- package/dist/__tests__/logic/createFormControl.test.d.ts +0 -2
- package/dist/__tests__/logic/createFormControl.test.d.ts.map +0 -1
- package/dist/__tests__/logic/generateId.test.d.ts +0 -2
- package/dist/__tests__/logic/generateId.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getCheckboxValue.test.d.ts +0 -2
- package/dist/__tests__/logic/getCheckboxValue.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getDirtyFields.test.d.ts +0 -2
- package/dist/__tests__/logic/getDirtyFields.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getEventValue.test.d.ts +0 -2
- package/dist/__tests__/logic/getEventValue.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getFieldValue.test.d.ts +0 -2
- package/dist/__tests__/logic/getFieldValue.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getFieldValueAs.test.d.ts +0 -2
- package/dist/__tests__/logic/getFieldValueAs.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getFocusFieldName.test.d.ts +0 -2
- package/dist/__tests__/logic/getFocusFieldName.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getNodeParentName.test.d.ts +0 -2
- package/dist/__tests__/logic/getNodeParentName.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getRadioValue.test.d.ts +0 -2
- package/dist/__tests__/logic/getRadioValue.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getResolverOptions.test.d.ts +0 -2
- package/dist/__tests__/logic/getResolverOptions.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getRuleValue.test.d.ts +0 -2
- package/dist/__tests__/logic/getRuleValue.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getValidateError.test.d.ts +0 -2
- package/dist/__tests__/logic/getValidateError.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getValidationModes.test.d.ts +0 -2
- package/dist/__tests__/logic/getValidationModes.test.d.ts.map +0 -1
- package/dist/__tests__/logic/getValueAndMessage.test.d.ts +0 -2
- package/dist/__tests__/logic/getValueAndMessage.test.d.ts.map +0 -1
- package/dist/__tests__/logic/hasPromiseValidation.test.d.ts +0 -2
- package/dist/__tests__/logic/hasPromiseValidation.test.d.ts.map +0 -1
- package/dist/__tests__/logic/hasValidation.test.d.ts +0 -2
- package/dist/__tests__/logic/hasValidation.test.d.ts.map +0 -1
- package/dist/__tests__/logic/isNameInFieldArray.test.d.ts +0 -2
- package/dist/__tests__/logic/isNameInFieldArray.test.d.ts.map +0 -1
- package/dist/__tests__/logic/isWatched.test.d.ts +0 -2
- package/dist/__tests__/logic/isWatched.test.d.ts.map +0 -1
- package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts +0 -2
- package/dist/__tests__/logic/iterateFieldsByAction.test.d.ts.map +0 -1
- package/dist/__tests__/logic/schemaErrorLookup.test.d.ts +0 -2
- package/dist/__tests__/logic/schemaErrorLookup.test.d.ts.map +0 -1
- package/dist/__tests__/logic/shouldRenderFormState.test.d.ts +0 -2
- package/dist/__tests__/logic/shouldRenderFormState.test.d.ts.map +0 -1
- package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts +0 -2
- package/dist/__tests__/logic/shouldSubscribeByName.test.d.ts.map +0 -1
- package/dist/__tests__/logic/skipValidation.test.d.ts +0 -2
- package/dist/__tests__/logic/skipValidation.test.d.ts.map +0 -1
- package/dist/__tests__/logic/unsetEmptyArray.test.d.ts +0 -2
- package/dist/__tests__/logic/unsetEmptyArray.test.d.ts.map +0 -1
- package/dist/__tests__/logic/validateField.test.d.ts +0 -2
- package/dist/__tests__/logic/validateField.test.d.ts.map +0 -1
- package/dist/__tests__/type.test.d.ts +0 -2
- package/dist/__tests__/type.test.d.ts.map +0 -1
- package/dist/__tests__/useController.test.d.ts +0 -2
- package/dist/__tests__/useController.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/append.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/append.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/focus.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/focus.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/insert.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/insert.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/move.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/move.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/prepend.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/prepend.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/remove.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/remove.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/replace.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/replace.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/swap.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/swap.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray/update.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray/update.test.d.ts.map +0 -1
- package/dist/__tests__/useFieldArray.test.d.ts +0 -2
- package/dist/__tests__/useFieldArray.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/clearErrors.test.d.ts +0 -2
- package/dist/__tests__/useForm/clearErrors.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/formState.test.d.ts +0 -2
- package/dist/__tests__/useForm/formState.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/getFieldState.test.d.ts +0 -2
- package/dist/__tests__/useForm/getFieldState.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/getValues.test.d.ts +0 -2
- package/dist/__tests__/useForm/getValues.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/handleSubmit.test.d.ts +0 -2
- package/dist/__tests__/useForm/handleSubmit.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/register.test.d.ts +0 -2
- package/dist/__tests__/useForm/register.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/reset.test.d.ts +0 -2
- package/dist/__tests__/useForm/reset.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/resetField.test.d.ts +0 -2
- package/dist/__tests__/useForm/resetField.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/resolver.test.d.ts +0 -2
- package/dist/__tests__/useForm/resolver.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/setError.test.d.ts +0 -2
- package/dist/__tests__/useForm/setError.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/setFocus.test.d.ts +0 -2
- package/dist/__tests__/useForm/setFocus.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/setValue.test.d.ts +0 -2
- package/dist/__tests__/useForm/setValue.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/subscribe.test.d.ts +0 -2
- package/dist/__tests__/useForm/subscribe.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/trigger.test.d.ts +0 -2
- package/dist/__tests__/useForm/trigger.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/unregister.test.d.ts +0 -2
- package/dist/__tests__/useForm/unregister.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts +0 -2
- package/dist/__tests__/useForm/useFormWithNullValues.test.d.ts.map +0 -1
- package/dist/__tests__/useForm/watch.test.d.ts +0 -2
- package/dist/__tests__/useForm/watch.test.d.ts.map +0 -1
- package/dist/__tests__/useForm.server.test.d.ts +0 -2
- package/dist/__tests__/useForm.server.test.d.ts.map +0 -1
- package/dist/__tests__/useForm.test.d.ts +0 -2
- package/dist/__tests__/useForm.test.d.ts.map +0 -1
- package/dist/__tests__/useFormContext.server.test.d.ts +0 -2
- package/dist/__tests__/useFormContext.server.test.d.ts.map +0 -1
- package/dist/__tests__/useFormContext.test.d.ts +0 -2
- package/dist/__tests__/useFormContext.test.d.ts.map +0 -1
- package/dist/__tests__/useFormState.test.d.ts +0 -2
- package/dist/__tests__/useFormState.test.d.ts.map +0 -1
- package/dist/__tests__/useWatch.test.d.ts +0 -2
- package/dist/__tests__/useWatch.test.d.ts.map +0 -1
- package/dist/__tests__/utils/append.test.d.ts +0 -2
- package/dist/__tests__/utils/append.test.d.ts.map +0 -1
- package/dist/__tests__/utils/cloneObject.test.d.ts +0 -2
- package/dist/__tests__/utils/cloneObject.test.d.ts.map +0 -1
- package/dist/__tests__/utils/compact.test.d.ts +0 -2
- package/dist/__tests__/utils/compact.test.d.ts.map +0 -1
- package/dist/__tests__/utils/convertToArrayPayload.test.d.ts +0 -2
- package/dist/__tests__/utils/convertToArrayPayload.test.d.ts.map +0 -1
- package/dist/__tests__/utils/createSubject.test.d.ts +0 -2
- package/dist/__tests__/utils/createSubject.test.d.ts.map +0 -1
- package/dist/__tests__/utils/deepEqual.test.d.ts +0 -2
- package/dist/__tests__/utils/deepEqual.test.d.ts.map +0 -1
- package/dist/__tests__/utils/deepMerge.test.d.ts +0 -2
- package/dist/__tests__/utils/deepMerge.test.d.ts.map +0 -1
- package/dist/__tests__/utils/extractFormValues.test.d.ts +0 -2
- package/dist/__tests__/utils/extractFormValues.test.d.ts.map +0 -1
- package/dist/__tests__/utils/fillEmptyArray.test.d.ts +0 -2
- package/dist/__tests__/utils/fillEmptyArray.test.d.ts.map +0 -1
- package/dist/__tests__/utils/flatten.test.d.ts +0 -2
- package/dist/__tests__/utils/flatten.test.d.ts.map +0 -1
- package/dist/__tests__/utils/get.test.d.ts +0 -2
- package/dist/__tests__/utils/get.test.d.ts.map +0 -1
- package/dist/__tests__/utils/insert.test.d.ts +0 -2
- package/dist/__tests__/utils/insert.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isBoolean.test.d.ts +0 -2
- package/dist/__tests__/utils/isBoolean.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isCheckBoxInput.test.d.ts +0 -2
- package/dist/__tests__/utils/isCheckBoxInput.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isEmptyObject.test.d.ts +0 -2
- package/dist/__tests__/utils/isEmptyObject.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isFileInput.test.d.ts +0 -2
- package/dist/__tests__/utils/isFileInput.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isFunction.test.d.ts +0 -2
- package/dist/__tests__/utils/isFunction.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isHTMLElement.test.d.ts +0 -2
- package/dist/__tests__/utils/isHTMLElement.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isKey.test.d.ts +0 -2
- package/dist/__tests__/utils/isKey.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isMultipleSelect.test.d.ts +0 -2
- package/dist/__tests__/utils/isMultipleSelect.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isNullOrUndefined.test.d.ts +0 -2
- package/dist/__tests__/utils/isNullOrUndefined.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isObject.test.d.ts +0 -2
- package/dist/__tests__/utils/isObject.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isPrimitive.test.d.ts +0 -2
- package/dist/__tests__/utils/isPrimitive.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isRadioInput.test.d.ts +0 -2
- package/dist/__tests__/utils/isRadioInput.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts +0 -2
- package/dist/__tests__/utils/isRadioOrCheckbox.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isRegex.test.d.ts +0 -2
- package/dist/__tests__/utils/isRegex.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isString.test.d.ts +0 -2
- package/dist/__tests__/utils/isString.test.d.ts.map +0 -1
- package/dist/__tests__/utils/isUndefined.test.d.ts +0 -2
- package/dist/__tests__/utils/isUndefined.test.d.ts.map +0 -1
- package/dist/__tests__/utils/live.test.d.ts +0 -2
- package/dist/__tests__/utils/live.test.d.ts.map +0 -1
- package/dist/__tests__/utils/move.test.d.ts +0 -2
- package/dist/__tests__/utils/move.test.d.ts.map +0 -1
- package/dist/__tests__/utils/noop.test.d.ts +0 -2
- package/dist/__tests__/utils/noop.test.d.ts.map +0 -1
- package/dist/__tests__/utils/objectHasFunction.test.d.ts +0 -2
- package/dist/__tests__/utils/objectHasFunction.test.d.ts.map +0 -1
- package/dist/__tests__/utils/prepend.test.d.ts +0 -2
- package/dist/__tests__/utils/prepend.test.d.ts.map +0 -1
- package/dist/__tests__/utils/remove.test.d.ts +0 -2
- package/dist/__tests__/utils/remove.test.d.ts.map +0 -1
- package/dist/__tests__/utils/set.test.d.ts +0 -2
- package/dist/__tests__/utils/set.test.d.ts.map +0 -1
- package/dist/__tests__/utils/stringToPath.test.d.ts +0 -2
- package/dist/__tests__/utils/stringToPath.test.d.ts.map +0 -1
- package/dist/__tests__/utils/swap.test.d.ts +0 -2
- package/dist/__tests__/utils/swap.test.d.ts.map +0 -1
- package/dist/__tests__/utils/unset.test.d.ts +0 -2
- package/dist/__tests__/utils/unset.test.d.ts.map +0 -1
- package/dist/__tests__/utils/validationModeChecker.test.d.ts +0 -2
- package/dist/__tests__/utils/validationModeChecker.test.d.ts.map +0 -1
- package/dist/__tests__/watch.server.test.d.ts +0 -2
- package/dist/__tests__/watch.server.test.d.ts.map +0 -1
- package/dist/__tests__/watch.test.d.ts +0 -2
- package/dist/__tests__/watch.test.d.ts.map +0 -1
- 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,
|
|
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 (
|
|
126
|
+
if (visited.has(object1) || visited.has(object2)) {
|
|
118
127
|
return true;
|
|
119
128
|
}
|
|
120
|
-
|
|
121
|
-
|
|
129
|
+
visited.add(object1);
|
|
130
|
+
visited.add(object2);
|
|
122
131
|
for (const key of keys1) {
|
|
123
132
|
const val1 = object1[key];
|
|
124
|
-
if (!
|
|
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)
|
|
131
|
-
|
|
132
|
-
? !deepEqual(val1, val2,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
960
|
-
|
|
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
|
-
|
|
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
|
-
?
|
|
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
|
|
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
|
-
|
|
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 && !
|
|
1051
|
-
if (isPromiseFunction &&
|
|
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 (
|
|
1212
|
+
if (onlyCheckValid) {
|
|
1057
1213
|
break;
|
|
1058
1214
|
}
|
|
1059
1215
|
}
|
|
1060
|
-
!
|
|
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(
|
|
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
|
|
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
|
-
?
|
|
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
|
-
|
|
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:
|
|
1351
|
+
dirtyFields: _formState.dirtyFields,
|
|
1182
1352
|
isDirty: _getDirty(name, cloneValue),
|
|
1183
1353
|
});
|
|
1184
1354
|
}
|
|
1185
1355
|
}
|
|
1186
1356
|
else {
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
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 (
|
|
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
|
|
1375
|
+
...(watched && _formState),
|
|
1376
|
+
name: _state.mount || watched ? name : undefined,
|
|
1377
|
+
values,
|
|
1196
1378
|
});
|
|
1197
1379
|
}
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
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:
|
|
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
|
-
!(
|
|
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(
|
|
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,
|
|
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,
|