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