@depup/react-hook-form 7.72.0-depup.0 → 7.83.0-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +2455 -2019
- 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/isNameInFieldArray.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 +491 -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 +81 -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 +34 -31
- 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,22 +124,36 @@ function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
|
|
|
120
124
|
if (keys1.length !== keys2.length) {
|
|
121
125
|
return false;
|
|
122
126
|
}
|
|
123
|
-
if (
|
|
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') {
|
|
134
152
|
const val2 = object2[key];
|
|
135
153
|
if ((isDateObject(val1) && isDateObject(val2)) ||
|
|
136
|
-
(isObject(val1)
|
|
137
|
-
|
|
138
|
-
? !deepEqual(val1, val2,
|
|
154
|
+
((isObject(val1) || Array.isArray(val1)) &&
|
|
155
|
+
(isObject(val2) || Array.isArray(val2)))
|
|
156
|
+
? !deepEqual(val1, val2, visited)
|
|
139
157
|
: !Object.is(val1, val2)) {
|
|
140
158
|
return false;
|
|
141
159
|
}
|
|
@@ -164,17 +182,43 @@ function extractFormValues(fieldsState, formValues) {
|
|
|
164
182
|
return values;
|
|
165
183
|
}
|
|
166
184
|
|
|
167
|
-
|
|
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 ||
|
|
@@ -460,13 +554,21 @@ var hasValidation = (options) => options.mount &&
|
|
|
460
554
|
options.pattern ||
|
|
461
555
|
options.validate);
|
|
462
556
|
|
|
463
|
-
var isNameInFieldArray = (names, name) =>
|
|
557
|
+
var isNameInFieldArray = (names, name) => name
|
|
558
|
+
.split('.')
|
|
559
|
+
.some((part, index, arr) => !isNaN(Number(part)) && names.has(arr.slice(0, index).join('.')));
|
|
464
560
|
|
|
465
|
-
var isWatched = (name, _names, isBlurEvent) =>
|
|
466
|
-
(
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
561
|
+
var isWatched = (name, _names, isBlurEvent) => {
|
|
562
|
+
if (isBlurEvent)
|
|
563
|
+
return false;
|
|
564
|
+
if (_names.watchAll || _names.watch.has(name))
|
|
565
|
+
return true;
|
|
566
|
+
for (const watchName of _names.watch) {
|
|
567
|
+
if (name.startsWith(watchName) && name.charAt(watchName.length) === '.')
|
|
568
|
+
return true;
|
|
569
|
+
}
|
|
570
|
+
return false;
|
|
571
|
+
};
|
|
470
572
|
|
|
471
573
|
const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
|
|
472
574
|
for (const key of fieldsNames || Object.keys(fields)) {
|
|
@@ -534,9 +636,10 @@ function schemaErrorLookup(errors, _fields, name) {
|
|
|
534
636
|
var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
|
|
535
637
|
updateFormState(formStateData);
|
|
536
638
|
const { name, ...formState } = formStateData;
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
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] ===
|
|
540
643
|
(!isRoot || VALIDATION_MODE.all)));
|
|
541
644
|
};
|
|
542
645
|
|
|
@@ -545,7 +648,7 @@ var shouldSubscribeByName = (name, signalName, exact) => !name ||
|
|
|
545
648
|
name === signalName ||
|
|
546
649
|
convertToArrayPayload(name).some((currentName) => currentName &&
|
|
547
650
|
(exact
|
|
548
|
-
? currentName === signalName
|
|
651
|
+
? currentName === signalName || currentName.startsWith(signalName + '.')
|
|
549
652
|
: currentName.startsWith(signalName) ||
|
|
550
653
|
signalName.startsWith(currentName)));
|
|
551
654
|
|
|
@@ -568,7 +671,8 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
|
|
|
568
671
|
var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
|
|
569
672
|
|
|
570
673
|
var updateFieldArrayRootError = (errors, error, name) => {
|
|
571
|
-
const
|
|
674
|
+
const existingErrors = get(errors, name);
|
|
675
|
+
const fieldArrayErrors = Array.isArray(existingErrors) ? existingErrors : [];
|
|
572
676
|
set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
|
|
573
677
|
set(errors, name, fieldArrayErrors);
|
|
574
678
|
return errors;
|
|
@@ -602,7 +706,13 @@ var validateField = async (field, disabledFieldNames, formValues, validateAllFie
|
|
|
602
706
|
const inputRef = refs ? refs[0] : ref;
|
|
603
707
|
const setCustomValidity = (message) => {
|
|
604
708
|
if (shouldUseNativeValidation && inputRef.reportValidity) {
|
|
605
|
-
|
|
709
|
+
const validityMessage = isBoolean(message) ? '' : message || '';
|
|
710
|
+
if (refs) {
|
|
711
|
+
refs.forEach((ref) => ref.setCustomValidity(validityMessage));
|
|
712
|
+
}
|
|
713
|
+
else {
|
|
714
|
+
inputRef.setCustomValidity(validityMessage);
|
|
715
|
+
}
|
|
606
716
|
inputRef.reportValidity();
|
|
607
717
|
}
|
|
608
718
|
};
|
|
@@ -777,24 +887,36 @@ const defaultOptions = {
|
|
|
777
887
|
reValidateMode: VALIDATION_MODE.onChange,
|
|
778
888
|
shouldFocusError: true,
|
|
779
889
|
};
|
|
890
|
+
const FORM_ERROR_TYPE = 'form';
|
|
891
|
+
const updateDirtyFields = (dirtyFields, nextDirtyFields) => {
|
|
892
|
+
for (const key in dirtyFields) {
|
|
893
|
+
if (!(key in nextDirtyFields)) {
|
|
894
|
+
delete dirtyFields[key];
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
Object.assign(dirtyFields, nextDirtyFields);
|
|
898
|
+
};
|
|
899
|
+
const DEFAULT_FORM_STATE = {
|
|
900
|
+
submitCount: 0,
|
|
901
|
+
isDirty: false,
|
|
902
|
+
isReady: false,
|
|
903
|
+
isValidating: false,
|
|
904
|
+
isSubmitted: false,
|
|
905
|
+
isSubmitting: false,
|
|
906
|
+
isSubmitSuccessful: false,
|
|
907
|
+
isValid: false,
|
|
908
|
+
touchedFields: {},
|
|
909
|
+
dirtyFields: {},
|
|
910
|
+
validatingFields: {},
|
|
911
|
+
};
|
|
780
912
|
function createFormControl(props = {}) {
|
|
781
913
|
let _options = {
|
|
782
914
|
...defaultOptions,
|
|
783
915
|
...props,
|
|
784
916
|
};
|
|
785
917
|
let _formState = {
|
|
786
|
-
|
|
787
|
-
isDirty: false,
|
|
788
|
-
isReady: false,
|
|
918
|
+
...cloneObject(DEFAULT_FORM_STATE),
|
|
789
919
|
isLoading: isFunction(_options.defaultValues),
|
|
790
|
-
isValidating: false,
|
|
791
|
-
isSubmitted: false,
|
|
792
|
-
isSubmitting: false,
|
|
793
|
-
isSubmitSuccessful: false,
|
|
794
|
-
isValid: false,
|
|
795
|
-
touchedFields: {},
|
|
796
|
-
dirtyFields: {},
|
|
797
|
-
validatingFields: {},
|
|
798
920
|
errors: _options.errors || {},
|
|
799
921
|
disabled: _options.disabled || false,
|
|
800
922
|
};
|
|
@@ -817,9 +939,13 @@ function createFormControl(props = {}) {
|
|
|
817
939
|
unMount: new Set(),
|
|
818
940
|
array: new Set(),
|
|
819
941
|
watch: new Set(),
|
|
942
|
+
registerName: new Set(),
|
|
820
943
|
};
|
|
821
|
-
|
|
822
|
-
|
|
944
|
+
const delayErrorCallbacks = {};
|
|
945
|
+
const timers = {};
|
|
946
|
+
let _valuesSubscriberCount = 0;
|
|
947
|
+
let _validationModeBeforeSubmit = getValidationModes(_options.mode);
|
|
948
|
+
let _validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
|
823
949
|
const defaultProxyFormState = {
|
|
824
950
|
isDirty: false,
|
|
825
951
|
dirtyFields: false,
|
|
@@ -839,10 +965,11 @@ function createFormControl(props = {}) {
|
|
|
839
965
|
array: createSubject(),
|
|
840
966
|
state: createSubject(),
|
|
841
967
|
};
|
|
968
|
+
let _setValidCallId = 0;
|
|
842
969
|
const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
|
|
843
|
-
const debounce = (callback) => (wait) => {
|
|
844
|
-
clearTimeout(
|
|
845
|
-
|
|
970
|
+
const debounce = (name, callback) => (wait) => {
|
|
971
|
+
clearTimeout(timers[name]);
|
|
972
|
+
timers[name] = setTimeout(callback, wait);
|
|
846
973
|
};
|
|
847
974
|
const _setValid = async (shouldUpdateValid) => {
|
|
848
975
|
if (_state.keepIsValid) {
|
|
@@ -852,10 +979,11 @@ function createFormControl(props = {}) {
|
|
|
852
979
|
(_proxyFormState.isValid ||
|
|
853
980
|
_proxySubscribeFormState.isValid ||
|
|
854
981
|
shouldUpdateValid)) {
|
|
982
|
+
const callId = ++_setValidCallId;
|
|
855
983
|
let isValid;
|
|
856
984
|
if (_options.resolver) {
|
|
857
985
|
isValid = isEmptyObject((await _runSchema()).errors);
|
|
858
|
-
_updateIsValidating();
|
|
986
|
+
callId === _setValidCallId && _updateIsValidating();
|
|
859
987
|
}
|
|
860
988
|
else {
|
|
861
989
|
isValid = await executeBuiltInValidation({
|
|
@@ -864,7 +992,7 @@ function createFormControl(props = {}) {
|
|
|
864
992
|
eventType: EVENTS.VALID,
|
|
865
993
|
});
|
|
866
994
|
}
|
|
867
|
-
if (isValid !== _formState.isValid) {
|
|
995
|
+
if (callId === _setValidCallId && isValid !== _formState.isValid) {
|
|
868
996
|
_subjects.state.next({
|
|
869
997
|
isValid,
|
|
870
998
|
});
|
|
@@ -890,6 +1018,9 @@ function createFormControl(props = {}) {
|
|
|
890
1018
|
});
|
|
891
1019
|
}
|
|
892
1020
|
};
|
|
1021
|
+
const _updateDirtyFields = () => {
|
|
1022
|
+
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
|
|
1023
|
+
};
|
|
893
1024
|
const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
|
894
1025
|
if (args && method && !_options.disabled) {
|
|
895
1026
|
_state.action = true;
|
|
@@ -911,9 +1042,7 @@ function createFormControl(props = {}) {
|
|
|
911
1042
|
shouldSetValues && set(_formState.touchedFields, name, touchedFields);
|
|
912
1043
|
}
|
|
913
1044
|
if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
|
|
914
|
-
|
|
915
|
-
const rootName = getNodeParentName(name);
|
|
916
|
-
set(_formState.dirtyFields, rootName, get(fullDirtyFields, rootName));
|
|
1045
|
+
_updateDirtyFields();
|
|
917
1046
|
}
|
|
918
1047
|
_subjects.state.next({
|
|
919
1048
|
name,
|
|
@@ -929,6 +1058,7 @@ function createFormControl(props = {}) {
|
|
|
929
1058
|
};
|
|
930
1059
|
const updateErrors = (name, error) => {
|
|
931
1060
|
set(_formState.errors, name, error);
|
|
1061
|
+
_formState.errors = { ..._formState.errors };
|
|
932
1062
|
_subjects.state.next({
|
|
933
1063
|
errors: _formState.errors,
|
|
934
1064
|
});
|
|
@@ -940,16 +1070,53 @@ function createFormControl(props = {}) {
|
|
|
940
1070
|
isValid: false,
|
|
941
1071
|
});
|
|
942
1072
|
};
|
|
1073
|
+
const hasExplicitNullIntermediate = (name) => {
|
|
1074
|
+
const segments = isKey(name) ? [name] : stringToPath(name);
|
|
1075
|
+
let formValues = _formValues;
|
|
1076
|
+
let defaultValues = _defaultValues;
|
|
1077
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
1078
|
+
const key = segments[i];
|
|
1079
|
+
formValues = isNullOrUndefined(formValues) ? formValues : formValues[key];
|
|
1080
|
+
defaultValues = isNullOrUndefined(defaultValues)
|
|
1081
|
+
? defaultValues
|
|
1082
|
+
: defaultValues[key];
|
|
1083
|
+
if (formValues === null && defaultValues !== null) {
|
|
1084
|
+
return true;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
return false;
|
|
1088
|
+
};
|
|
943
1089
|
const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
|
|
944
1090
|
const field = get(_fields, name);
|
|
945
1091
|
if (field) {
|
|
1092
|
+
if (hasExplicitNullIntermediate(name)) {
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
const wasUnsetInFormValues = isUndefined(get(_formValues, name));
|
|
946
1096
|
const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
|
|
947
1097
|
isUndefined(defaultValue) ||
|
|
948
1098
|
(ref && ref.defaultChecked) ||
|
|
949
1099
|
shouldSkipSetValueAs
|
|
950
1100
|
? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
|
|
951
1101
|
: setFieldValue(name, defaultValue);
|
|
952
|
-
_state.mount && !_state.action
|
|
1102
|
+
if (_state.mount && !_state.action) {
|
|
1103
|
+
_setValid();
|
|
1104
|
+
if (wasUnsetInFormValues &&
|
|
1105
|
+
_formState.isDirty &&
|
|
1106
|
+
(_proxyFormState.isDirty || _proxySubscribeFormState.isDirty)) {
|
|
1107
|
+
const isDirty = _getDirty();
|
|
1108
|
+
if (!isDirty) {
|
|
1109
|
+
_formState.isDirty = false;
|
|
1110
|
+
_subjects.state.next({ ..._formState });
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
if (props.shouldUnregister &&
|
|
1114
|
+
wasUnsetInFormValues &&
|
|
1115
|
+
!isUndefined(get(_formValues, name)) &&
|
|
1116
|
+
isWatched(name, _names)) {
|
|
1117
|
+
_state.watch = true;
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
953
1120
|
}
|
|
954
1121
|
};
|
|
955
1122
|
const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
|
|
@@ -958,18 +1125,26 @@ function createFormControl(props = {}) {
|
|
|
958
1125
|
const output = {
|
|
959
1126
|
name,
|
|
960
1127
|
};
|
|
961
|
-
|
|
1128
|
+
// an explicit programmatic update (e.g. setValue with shouldDirty: true)
|
|
1129
|
+
// opts into dirty tracking even when the form is disabled
|
|
1130
|
+
if (!_options.disabled || shouldDirty === true) {
|
|
962
1131
|
if (!isBlurEvent || shouldDirty) {
|
|
1132
|
+
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
|
963
1133
|
if (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty) {
|
|
964
1134
|
isPreviousDirty = _formState.isDirty;
|
|
965
|
-
_formState.isDirty = output.isDirty =
|
|
1135
|
+
_formState.isDirty = output.isDirty =
|
|
1136
|
+
!isCurrentFieldPristine || _getDirty();
|
|
966
1137
|
shouldUpdateField = isPreviousDirty !== output.isDirty;
|
|
967
1138
|
}
|
|
968
|
-
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
|
969
1139
|
isPreviousDirty = !!get(_formState.dirtyFields, name);
|
|
970
|
-
isCurrentFieldPristine
|
|
971
|
-
|
|
972
|
-
|
|
1140
|
+
if (isCurrentFieldPristine !== _formState.isDirty) {
|
|
1141
|
+
updateDirtyFields(_formState.dirtyFields, getDirtyFields(_defaultValues, _formValues, undefined, _fields));
|
|
1142
|
+
}
|
|
1143
|
+
else {
|
|
1144
|
+
isCurrentFieldPristine
|
|
1145
|
+
? unset(_formState.dirtyFields, name)
|
|
1146
|
+
: set(_formState.dirtyFields, name, true);
|
|
1147
|
+
}
|
|
973
1148
|
output.dirtyFields = _formState.dirtyFields;
|
|
974
1149
|
shouldUpdateField =
|
|
975
1150
|
shouldUpdateField ||
|
|
@@ -999,15 +1174,16 @@ function createFormControl(props = {}) {
|
|
|
999
1174
|
isBoolean(isValid) &&
|
|
1000
1175
|
_formState.isValid !== isValid;
|
|
1001
1176
|
if (_options.delayError && error) {
|
|
1002
|
-
|
|
1003
|
-
|
|
1177
|
+
delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
|
|
1178
|
+
delayErrorCallbacks[name](_options.delayError);
|
|
1004
1179
|
}
|
|
1005
1180
|
else {
|
|
1006
|
-
clearTimeout(
|
|
1007
|
-
|
|
1181
|
+
clearTimeout(timers[name]);
|
|
1182
|
+
delete delayErrorCallbacks[name];
|
|
1008
1183
|
error
|
|
1009
1184
|
? set(_formState.errors, name, error)
|
|
1010
1185
|
: unset(_formState.errors, name);
|
|
1186
|
+
_formState.errors = { ..._formState.errors };
|
|
1011
1187
|
}
|
|
1012
1188
|
if ((error ? !deepEqual(previousFieldError, error) : previousFieldError) ||
|
|
1013
1189
|
!isEmptyObject(fieldState) ||
|
|
@@ -1036,9 +1212,14 @@ function createFormControl(props = {}) {
|
|
|
1036
1212
|
for (const name of names) {
|
|
1037
1213
|
const error = get(errors, name);
|
|
1038
1214
|
error
|
|
1039
|
-
?
|
|
1215
|
+
? _names.array.has(name) &&
|
|
1216
|
+
isObject(error) &&
|
|
1217
|
+
!Object.keys(error).some((key) => !Number.isNaN(Number(key)))
|
|
1218
|
+
? updateFieldArrayRootError(_formState.errors, { [name]: error }, name)
|
|
1219
|
+
: set(_formState.errors, name, error)
|
|
1040
1220
|
: unset(_formState.errors, name);
|
|
1041
1221
|
}
|
|
1222
|
+
_formState.errors = { ..._formState.errors };
|
|
1042
1223
|
}
|
|
1043
1224
|
else {
|
|
1044
1225
|
_formState.errors = errors;
|
|
@@ -1058,8 +1239,8 @@ function createFormControl(props = {}) {
|
|
|
1058
1239
|
const error = result[key];
|
|
1059
1240
|
if (error) {
|
|
1060
1241
|
setError(`${FORM_ERROR_TYPE}.${key}`, {
|
|
1061
|
-
message: isString(
|
|
1062
|
-
type: INPUT_VALIDATION_RULES.validate,
|
|
1242
|
+
message: isString(error.message) ? error.message : '',
|
|
1243
|
+
type: error.type || INPUT_VALIDATION_RULES.validate,
|
|
1063
1244
|
});
|
|
1064
1245
|
}
|
|
1065
1246
|
}
|
|
@@ -1101,11 +1282,15 @@ function createFormControl(props = {}) {
|
|
|
1101
1282
|
if (_f) {
|
|
1102
1283
|
const isFieldArrayRoot = _names.array.has(_f.name);
|
|
1103
1284
|
const isPromiseFunction = field._f && hasPromiseValidation(field._f);
|
|
1104
|
-
|
|
1285
|
+
const shouldTrackIsValidatingState = _proxyFormState.validatingFields ||
|
|
1286
|
+
_proxyFormState.isValidating ||
|
|
1287
|
+
_proxySubscribeFormState.validatingFields ||
|
|
1288
|
+
_proxySubscribeFormState.isValidating;
|
|
1289
|
+
if (isPromiseFunction && shouldTrackIsValidatingState) {
|
|
1105
1290
|
_updateIsValidating([_f.name], true);
|
|
1106
1291
|
}
|
|
1107
1292
|
const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
|
|
1108
|
-
if (isPromiseFunction &&
|
|
1293
|
+
if (isPromiseFunction && shouldTrackIsValidatingState) {
|
|
1109
1294
|
_updateIsValidating([_f.name]);
|
|
1110
1295
|
}
|
|
1111
1296
|
if (fieldError[_f.name]) {
|
|
@@ -1147,9 +1332,8 @@ function createFormControl(props = {}) {
|
|
|
1147
1332
|
}
|
|
1148
1333
|
_names.unMount = new Set();
|
|
1149
1334
|
};
|
|
1150
|
-
const _getDirty = (name, data) =>
|
|
1151
|
-
(
|
|
1152
|
-
!deepEqual(getValues(), _defaultValues));
|
|
1335
|
+
const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
|
|
1336
|
+
!deepEqual(_state.mount ? _formValues : _defaultValues, _defaultValues));
|
|
1153
1337
|
const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
|
|
1154
1338
|
...(_state.mount
|
|
1155
1339
|
? _formValues
|
|
@@ -1160,7 +1344,7 @@ function createFormControl(props = {}) {
|
|
|
1160
1344
|
: defaultValue),
|
|
1161
1345
|
}, isGlobal, defaultValue);
|
|
1162
1346
|
const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
|
|
1163
|
-
const setFieldValue = (name, value, options = {}) => {
|
|
1347
|
+
const setFieldValue = (name, value, options = {}, skipClone = false, skipRender = false) => {
|
|
1164
1348
|
const field = get(_fields, name);
|
|
1165
1349
|
let fieldValue = value;
|
|
1166
1350
|
if (field) {
|
|
@@ -1198,20 +1382,23 @@ function createFormControl(props = {}) {
|
|
|
1198
1382
|
}
|
|
1199
1383
|
else {
|
|
1200
1384
|
fieldReference.ref.value = fieldValue;
|
|
1201
|
-
if (!fieldReference.ref.type) {
|
|
1385
|
+
if (!fieldReference.ref.type && !skipRender) {
|
|
1202
1386
|
_subjects.state.next({
|
|
1203
1387
|
name,
|
|
1204
|
-
values: cloneObject(_formValues),
|
|
1388
|
+
values: skipClone ? _formValues : cloneObject(_formValues),
|
|
1205
1389
|
});
|
|
1206
1390
|
}
|
|
1207
1391
|
}
|
|
1208
1392
|
}
|
|
1209
1393
|
}
|
|
1210
1394
|
(options.shouldDirty || options.shouldTouch) &&
|
|
1211
|
-
updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty,
|
|
1212
|
-
options.shouldValidate &&
|
|
1395
|
+
updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, !skipRender);
|
|
1396
|
+
options.shouldValidate &&
|
|
1397
|
+
trigger(name, {
|
|
1398
|
+
delayError: options.delayError,
|
|
1399
|
+
});
|
|
1213
1400
|
};
|
|
1214
|
-
const
|
|
1401
|
+
const setFieldValues = (name, value, options, skipClone = false, skipRender = false) => {
|
|
1215
1402
|
for (const fieldKey in value) {
|
|
1216
1403
|
if (!value.hasOwnProperty(fieldKey)) {
|
|
1217
1404
|
return;
|
|
@@ -1223,49 +1410,84 @@ function createFormControl(props = {}) {
|
|
|
1223
1410
|
isObject(fieldValue) ||
|
|
1224
1411
|
(field && !field._f)) &&
|
|
1225
1412
|
!isDateObject(fieldValue)
|
|
1226
|
-
?
|
|
1227
|
-
: setFieldValue(fieldName, fieldValue, options);
|
|
1413
|
+
? setFieldValues(fieldName, fieldValue, options, skipClone, skipRender)
|
|
1414
|
+
: setFieldValue(fieldName, fieldValue, options, skipClone, skipRender);
|
|
1228
1415
|
}
|
|
1229
1416
|
};
|
|
1230
|
-
const
|
|
1417
|
+
const _setValue = (name, value, options, skipClone, skipStateEmit = false) => {
|
|
1231
1418
|
const field = get(_fields, name);
|
|
1232
1419
|
const isFieldArray = _names.array.has(name);
|
|
1233
|
-
const cloneValue = cloneObject(value);
|
|
1234
|
-
|
|
1420
|
+
const cloneValue = skipClone ? value : cloneObject(value);
|
|
1421
|
+
const previousValue = get(_formValues, name);
|
|
1422
|
+
const isValueUnchanged = deepEqual(previousValue, cloneValue);
|
|
1423
|
+
if (!isValueUnchanged) {
|
|
1424
|
+
set(_formValues, name, cloneValue);
|
|
1425
|
+
}
|
|
1235
1426
|
if (isFieldArray) {
|
|
1236
1427
|
_subjects.array.next({
|
|
1237
1428
|
name,
|
|
1238
|
-
values: cloneObject(_formValues),
|
|
1429
|
+
values: skipClone ? _formValues : cloneObject(_formValues),
|
|
1239
1430
|
});
|
|
1240
1431
|
if ((_proxyFormState.isDirty ||
|
|
1241
1432
|
_proxyFormState.dirtyFields ||
|
|
1242
1433
|
_proxySubscribeFormState.isDirty ||
|
|
1243
1434
|
_proxySubscribeFormState.dirtyFields) &&
|
|
1244
1435
|
options.shouldDirty) {
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1436
|
+
_updateDirtyFields();
|
|
1437
|
+
if (!skipStateEmit) {
|
|
1438
|
+
_subjects.state.next({
|
|
1439
|
+
name,
|
|
1440
|
+
dirtyFields: _formState.dirtyFields,
|
|
1441
|
+
isDirty: _getDirty(name, cloneValue),
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1250
1444
|
}
|
|
1251
1445
|
}
|
|
1252
1446
|
else {
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1447
|
+
const isEmpty = (Array.isArray(cloneValue) && !cloneValue.length) ||
|
|
1448
|
+
isEmptyObject(cloneValue);
|
|
1449
|
+
if (!field || field._f || isNullOrUndefined(cloneValue) || isEmpty) {
|
|
1450
|
+
setFieldValue(name, cloneValue, options, skipClone, skipStateEmit);
|
|
1451
|
+
}
|
|
1452
|
+
else {
|
|
1453
|
+
setFieldValues(name, cloneValue, options, skipClone, skipStateEmit);
|
|
1454
|
+
}
|
|
1256
1455
|
}
|
|
1257
|
-
if (
|
|
1456
|
+
if (!isValueUnchanged && !skipStateEmit) {
|
|
1457
|
+
const watched = isWatched(name, _names);
|
|
1458
|
+
const values = skipClone ? _formValues : cloneObject(_formValues);
|
|
1258
1459
|
_subjects.state.next({
|
|
1259
|
-
..._formState,
|
|
1260
|
-
name,
|
|
1261
|
-
values
|
|
1460
|
+
...(watched && _formState),
|
|
1461
|
+
name: _state.mount || watched ? name : undefined,
|
|
1462
|
+
values,
|
|
1262
1463
|
});
|
|
1263
1464
|
}
|
|
1264
|
-
|
|
1465
|
+
};
|
|
1466
|
+
const setValue = (name, value, options = {}) => _setValue(name, value, options, false);
|
|
1467
|
+
const setValues = (formValues, options = {}) => {
|
|
1468
|
+
const updatedFormValues = isFunction(formValues)
|
|
1469
|
+
? formValues(_formValues)
|
|
1470
|
+
: formValues;
|
|
1471
|
+
if (!deepEqual(_formValues, updatedFormValues)) {
|
|
1472
|
+
_formValues = {
|
|
1473
|
+
..._formValues,
|
|
1474
|
+
...updatedFormValues,
|
|
1475
|
+
};
|
|
1476
|
+
const flattenedUpdates = flatten(updatedFormValues);
|
|
1477
|
+
for (const fieldName of _names.mount) {
|
|
1478
|
+
if (fieldName in flattenedUpdates) {
|
|
1479
|
+
_setValue(fieldName, flattenedUpdates[fieldName], options, true, true);
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1265
1482
|
_subjects.state.next({
|
|
1266
|
-
|
|
1267
|
-
|
|
1483
|
+
..._formState,
|
|
1484
|
+
name: undefined,
|
|
1485
|
+
type: undefined,
|
|
1486
|
+
...(_valuesSubscriberCount ? { values: _formValues } : {}),
|
|
1268
1487
|
});
|
|
1488
|
+
if (options.shouldValidate) {
|
|
1489
|
+
_setValid();
|
|
1490
|
+
}
|
|
1269
1491
|
}
|
|
1270
1492
|
};
|
|
1271
1493
|
const onChange = async (event) => {
|
|
@@ -1280,8 +1502,6 @@ function createFormControl(props = {}) {
|
|
|
1280
1502
|
(isDateObject(fieldValue) && isNaN(fieldValue.getTime())) ||
|
|
1281
1503
|
deepEqual(fieldValue, get(_formValues, name, fieldValue));
|
|
1282
1504
|
};
|
|
1283
|
-
const validationModeBeforeSubmit = getValidationModes(_options.mode);
|
|
1284
|
-
const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
|
1285
1505
|
if (field) {
|
|
1286
1506
|
let error;
|
|
1287
1507
|
let isValid;
|
|
@@ -1289,18 +1509,20 @@ function createFormControl(props = {}) {
|
|
|
1289
1509
|
? getFieldValue(field._f)
|
|
1290
1510
|
: getEventValue(event);
|
|
1291
1511
|
const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
|
|
1292
|
-
const
|
|
1512
|
+
const hasNoValidationEffect = !hasValidation(field._f) &&
|
|
1293
1513
|
!props.validate &&
|
|
1294
1514
|
!_options.resolver &&
|
|
1295
1515
|
!get(_formState.errors, name) &&
|
|
1296
|
-
!field._f.deps
|
|
1297
|
-
|
|
1516
|
+
!field._f.deps;
|
|
1517
|
+
const shouldSkipValidation = hasNoValidationEffect ||
|
|
1518
|
+
skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, _validationModeAfterSubmit, _validationModeBeforeSubmit);
|
|
1298
1519
|
const watched = isWatched(name, _names, isBlurEvent);
|
|
1299
1520
|
set(_formValues, name, fieldValue);
|
|
1300
1521
|
if (isBlurEvent) {
|
|
1301
1522
|
if (!target || !target.readOnly) {
|
|
1302
1523
|
field._f.onBlur && field._f.onBlur(event);
|
|
1303
|
-
|
|
1524
|
+
const pendingDelayError = delayErrorCallbacks[name];
|
|
1525
|
+
pendingDelayError && pendingDelayError(0);
|
|
1304
1526
|
}
|
|
1305
1527
|
}
|
|
1306
1528
|
else if (field._f.onChange) {
|
|
@@ -1312,10 +1534,13 @@ function createFormControl(props = {}) {
|
|
|
1312
1534
|
_subjects.state.next({
|
|
1313
1535
|
name,
|
|
1314
1536
|
type: event.type,
|
|
1315
|
-
|
|
1537
|
+
...(_valuesSubscriberCount
|
|
1538
|
+
? { values: cloneObject(_formValues) }
|
|
1539
|
+
: {}),
|
|
1316
1540
|
});
|
|
1317
1541
|
if (shouldSkipValidation) {
|
|
1318
|
-
if (
|
|
1542
|
+
if ((!hasNoValidationEffect || !_formState.isValid) &&
|
|
1543
|
+
(_proxyFormState.isValid || _proxySubscribeFormState.isValid)) {
|
|
1319
1544
|
if (_options.mode === 'onBlur') {
|
|
1320
1545
|
if (isBlurEvent) {
|
|
1321
1546
|
_setValid();
|
|
@@ -1339,13 +1564,15 @@ function createFormControl(props = {}) {
|
|
|
1339
1564
|
const { errors } = await _runSchema([name]);
|
|
1340
1565
|
_updateIsValidating([name]);
|
|
1341
1566
|
_updateIsFieldValueUpdated(fieldValue);
|
|
1342
|
-
if (isFieldValueUpdated) {
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
error = errorLookupResult.error;
|
|
1346
|
-
name = errorLookupResult.name;
|
|
1347
|
-
isValid = isEmptyObject(errors);
|
|
1567
|
+
if (!isFieldValueUpdated) {
|
|
1568
|
+
!isEmptyObject(fieldState) && _subjects.state.next(fieldState);
|
|
1569
|
+
return;
|
|
1348
1570
|
}
|
|
1571
|
+
const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
|
|
1572
|
+
const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
|
|
1573
|
+
error = errorLookupResult.error;
|
|
1574
|
+
name = errorLookupResult.name;
|
|
1575
|
+
isValid = isEmptyObject(errors);
|
|
1349
1576
|
}
|
|
1350
1577
|
else {
|
|
1351
1578
|
_updateIsValidating([name], true);
|
|
@@ -1410,6 +1637,18 @@ function createFormControl(props = {}) {
|
|
|
1410
1637
|
eventType: EVENTS.TRIGGER,
|
|
1411
1638
|
});
|
|
1412
1639
|
}
|
|
1640
|
+
if (options.delayError && _options.delayError && isString(name)) {
|
|
1641
|
+
const error = get(_formState.errors, name);
|
|
1642
|
+
if (error) {
|
|
1643
|
+
unset(_formState.errors, name);
|
|
1644
|
+
delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
|
|
1645
|
+
delayErrorCallbacks[name](_options.delayError);
|
|
1646
|
+
}
|
|
1647
|
+
else {
|
|
1648
|
+
clearTimeout(timers[name]);
|
|
1649
|
+
delete delayErrorCallbacks[name];
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1413
1652
|
_subjects.state.next({
|
|
1414
1653
|
...(!isString(name) ||
|
|
1415
1654
|
((_proxyFormState.isValid || _proxySubscribeFormState.isValid) &&
|
|
@@ -1448,8 +1687,6 @@ function createFormControl(props = {}) {
|
|
|
1448
1687
|
const names = name ? convertToArrayPayload(name) : undefined;
|
|
1449
1688
|
names === null || names === void 0 ? void 0 : names.forEach((inputName) => unset(_formState.errors, inputName));
|
|
1450
1689
|
if (names) {
|
|
1451
|
-
// Emit for each cleared field with the field name so that
|
|
1452
|
-
// shouldSubscribeByName can filter and avoid broad re-renders
|
|
1453
1690
|
names.forEach((inputName) => {
|
|
1454
1691
|
_subjects.state.next({
|
|
1455
1692
|
name: inputName,
|
|
@@ -1458,16 +1695,15 @@ function createFormControl(props = {}) {
|
|
|
1458
1695
|
});
|
|
1459
1696
|
}
|
|
1460
1697
|
else {
|
|
1461
|
-
|
|
1698
|
+
_formState.errors = {};
|
|
1462
1699
|
_subjects.state.next({
|
|
1463
|
-
errors:
|
|
1700
|
+
errors: _formState.errors,
|
|
1464
1701
|
});
|
|
1465
1702
|
}
|
|
1466
1703
|
};
|
|
1467
1704
|
const setError = (name, error, options) => {
|
|
1468
1705
|
const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
|
|
1469
1706
|
const currentError = get(_formState.errors, name) || {};
|
|
1470
|
-
// Don't override existing error messages elsewhere in the object tree.
|
|
1471
1707
|
const { ref: currentRef, message, type, ...restOfErrorTree } = currentError;
|
|
1472
1708
|
set(_formState.errors, name, {
|
|
1473
1709
|
...restOfErrorTree,
|
|
@@ -1481,25 +1717,60 @@ function createFormControl(props = {}) {
|
|
|
1481
1717
|
});
|
|
1482
1718
|
options && options.shouldFocus && ref && ref.focus && ref.focus();
|
|
1483
1719
|
};
|
|
1484
|
-
const watch = (name, defaultValue) =>
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1720
|
+
const watch = (name, defaultValue) => {
|
|
1721
|
+
if (isFunction(name)) {
|
|
1722
|
+
_valuesSubscriberCount++;
|
|
1723
|
+
const { unsubscribe } = _subjects.state.subscribe({
|
|
1724
|
+
next: (payload) => 'values' in payload &&
|
|
1725
|
+
name(payload.values || _getWatch(undefined, defaultValue), payload),
|
|
1726
|
+
});
|
|
1727
|
+
let called = false;
|
|
1728
|
+
return {
|
|
1729
|
+
unsubscribe: () => {
|
|
1730
|
+
if (called) {
|
|
1731
|
+
return;
|
|
1732
|
+
}
|
|
1733
|
+
called = true;
|
|
1734
|
+
_valuesSubscriberCount--;
|
|
1735
|
+
unsubscribe();
|
|
1736
|
+
},
|
|
1737
|
+
};
|
|
1738
|
+
}
|
|
1739
|
+
return _getWatch(name, defaultValue, true);
|
|
1740
|
+
};
|
|
1741
|
+
const _subscribe = (props) => {
|
|
1742
|
+
var _a;
|
|
1743
|
+
const needsValues = !!((_a = props.formState) === null || _a === void 0 ? void 0 : _a.values);
|
|
1744
|
+
if (needsValues) {
|
|
1745
|
+
_valuesSubscriberCount++;
|
|
1746
|
+
}
|
|
1747
|
+
const { unsubscribe } = _subjects.state.subscribe({
|
|
1748
|
+
next: (formState) => {
|
|
1749
|
+
if (shouldSubscribeByName(props.name, formState.name, props.exact) &&
|
|
1750
|
+
shouldRenderFormState(formState, props.formState || _proxyFormState, _setFormState, props.reRenderRoot)) {
|
|
1751
|
+
const snapshot = { ..._formValues };
|
|
1752
|
+
props.callback({
|
|
1753
|
+
values: snapshot,
|
|
1754
|
+
..._formState,
|
|
1755
|
+
...formState,
|
|
1756
|
+
defaultValues: _defaultValues,
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
},
|
|
1760
|
+
});
|
|
1761
|
+
if (!needsValues) {
|
|
1762
|
+
return unsubscribe;
|
|
1763
|
+
}
|
|
1764
|
+
let called = false;
|
|
1765
|
+
return () => {
|
|
1766
|
+
if (called) {
|
|
1767
|
+
return;
|
|
1500
1768
|
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1769
|
+
called = true;
|
|
1770
|
+
_valuesSubscriberCount--;
|
|
1771
|
+
unsubscribe();
|
|
1772
|
+
};
|
|
1773
|
+
};
|
|
1503
1774
|
const subscribe = (props) => {
|
|
1504
1775
|
_state.mount = true;
|
|
1505
1776
|
_proxySubscribeFormState = {
|
|
@@ -1554,6 +1825,7 @@ function createFormControl(props = {}) {
|
|
|
1554
1825
|
const register = (name, options = {}) => {
|
|
1555
1826
|
let field = get(_fields, name);
|
|
1556
1827
|
const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
|
|
1828
|
+
const shouldRevalidateRemount = !_names.registerName.has(name) && field && field._f && !field._f.mount;
|
|
1557
1829
|
set(_fields, name, {
|
|
1558
1830
|
...(field || {}),
|
|
1559
1831
|
_f: {
|
|
@@ -1564,7 +1836,7 @@ function createFormControl(props = {}) {
|
|
|
1564
1836
|
},
|
|
1565
1837
|
});
|
|
1566
1838
|
_names.mount.add(name);
|
|
1567
|
-
if (field) {
|
|
1839
|
+
if (field && !shouldRevalidateRemount) {
|
|
1568
1840
|
_setDisabledField({
|
|
1569
1841
|
disabled: isBoolean(options.disabled)
|
|
1570
1842
|
? options.disabled
|
|
@@ -1594,7 +1866,9 @@ function createFormControl(props = {}) {
|
|
|
1594
1866
|
onBlur: onChange,
|
|
1595
1867
|
ref: (ref) => {
|
|
1596
1868
|
if (ref) {
|
|
1869
|
+
_names.registerName.add(name);
|
|
1597
1870
|
register(name, options);
|
|
1871
|
+
_names.registerName.delete(name);
|
|
1598
1872
|
field = get(_fields, name);
|
|
1599
1873
|
const fieldRef = isUndefined(ref.value)
|
|
1600
1874
|
? ref.querySelectorAll
|
|
@@ -1608,20 +1882,23 @@ function createFormControl(props = {}) {
|
|
|
1608
1882
|
: fieldRef === field._f.ref) {
|
|
1609
1883
|
return;
|
|
1610
1884
|
}
|
|
1885
|
+
const newField = {
|
|
1886
|
+
...field._f,
|
|
1887
|
+
};
|
|
1888
|
+
if (radioOrCheckbox) {
|
|
1889
|
+
newField.refs = [
|
|
1890
|
+
...refs.filter(live),
|
|
1891
|
+
fieldRef,
|
|
1892
|
+
...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
|
|
1893
|
+
];
|
|
1894
|
+
newField.ref = { type: fieldRef.type, name };
|
|
1895
|
+
}
|
|
1896
|
+
else {
|
|
1897
|
+
newField.ref = fieldRef;
|
|
1898
|
+
delete newField.refs;
|
|
1899
|
+
}
|
|
1611
1900
|
set(_fields, name, {
|
|
1612
|
-
_f:
|
|
1613
|
-
...field._f,
|
|
1614
|
-
...(radioOrCheckbox
|
|
1615
|
-
? {
|
|
1616
|
-
refs: [
|
|
1617
|
-
...refs.filter(live),
|
|
1618
|
-
fieldRef,
|
|
1619
|
-
...(Array.isArray(get(_defaultValues, name)) ? [{}] : []),
|
|
1620
|
-
],
|
|
1621
|
-
ref: { type: fieldRef.type, name },
|
|
1622
|
-
}
|
|
1623
|
-
: { ref: fieldRef }),
|
|
1624
|
-
},
|
|
1901
|
+
_f: newField,
|
|
1625
1902
|
});
|
|
1626
1903
|
updateValidAndValue(name, false, undefined, fieldRef);
|
|
1627
1904
|
}
|
|
@@ -1638,6 +1915,7 @@ function createFormControl(props = {}) {
|
|
|
1638
1915
|
};
|
|
1639
1916
|
};
|
|
1640
1917
|
const _focusError = () => _options.shouldFocusError &&
|
|
1918
|
+
!_options.shouldUseNativeValidation &&
|
|
1641
1919
|
iterateFieldsByAction(_fields, _focusInput, _names.mount);
|
|
1642
1920
|
const _disableForm = (disabled) => {
|
|
1643
1921
|
if (isBoolean(disabled)) {
|
|
@@ -1742,7 +2020,8 @@ function createFormControl(props = {}) {
|
|
|
1742
2020
|
const updatedValues = formValues ? cloneObject(formValues) : _defaultValues;
|
|
1743
2021
|
const cloneUpdatedValues = cloneObject(updatedValues);
|
|
1744
2022
|
const isEmptyResetValues = isEmptyObject(formValues);
|
|
1745
|
-
const values =
|
|
2023
|
+
const values = cloneUpdatedValues;
|
|
2024
|
+
const fieldRefs = _fields;
|
|
1746
2025
|
if (!keepStateOptions.keepDefaultValues) {
|
|
1747
2026
|
_defaultValues = updatedValues;
|
|
1748
2027
|
}
|
|
@@ -1750,7 +2029,7 @@ function createFormControl(props = {}) {
|
|
|
1750
2029
|
if (keepStateOptions.keepDirtyValues) {
|
|
1751
2030
|
const fieldsToCheck = new Set([
|
|
1752
2031
|
..._names.mount,
|
|
1753
|
-
...Object.keys(getDirtyFields(_defaultValues, _formValues)),
|
|
2032
|
+
...Object.keys(getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs)),
|
|
1754
2033
|
]);
|
|
1755
2034
|
for (const fieldName of Array.from(fieldsToCheck)) {
|
|
1756
2035
|
const isDirty = get(_formState.dirtyFields, fieldName);
|
|
@@ -1791,15 +2070,25 @@ function createFormControl(props = {}) {
|
|
|
1791
2070
|
_fields = {};
|
|
1792
2071
|
}
|
|
1793
2072
|
}
|
|
1794
|
-
|
|
1795
|
-
|
|
2073
|
+
if (_options.shouldUnregister) {
|
|
2074
|
+
_formValues = keepStateOptions.keepDefaultValues
|
|
1796
2075
|
? cloneObject(_defaultValues)
|
|
1797
|
-
: {}
|
|
1798
|
-
|
|
2076
|
+
: {};
|
|
2077
|
+
if (keepStateOptions.keepFieldsRef) {
|
|
2078
|
+
for (const fieldName of _names.mount) {
|
|
2079
|
+
set(_formValues, fieldName, get(values, fieldName));
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
else {
|
|
2084
|
+
_formValues = cloneObject(values);
|
|
2085
|
+
}
|
|
1799
2086
|
_subjects.array.next({
|
|
1800
2087
|
values: { ...values },
|
|
1801
2088
|
});
|
|
1802
2089
|
_subjects.state.next({
|
|
2090
|
+
name: undefined,
|
|
2091
|
+
type: undefined,
|
|
1803
2092
|
values: { ...values },
|
|
1804
2093
|
});
|
|
1805
2094
|
}
|
|
@@ -1807,6 +2096,7 @@ function createFormControl(props = {}) {
|
|
|
1807
2096
|
mount: keepStateOptions.keepDirtyValues ? _names.mount : new Set(),
|
|
1808
2097
|
unMount: new Set(),
|
|
1809
2098
|
array: new Set(),
|
|
2099
|
+
registerName: new Set(),
|
|
1810
2100
|
disabled: new Set(),
|
|
1811
2101
|
watch: new Set(),
|
|
1812
2102
|
watchAll: false,
|
|
@@ -1820,9 +2110,6 @@ function createFormControl(props = {}) {
|
|
|
1820
2110
|
_state.watch = !!_options.shouldUnregister;
|
|
1821
2111
|
_state.keepIsValid = !!keepStateOptions.keepIsValid;
|
|
1822
2112
|
_state.action = false;
|
|
1823
|
-
// Clear errors synchronously to prevent validation errors on subsequent submissions
|
|
1824
|
-
// This fixes the issue where form.reset() causes validation errors on subsequent
|
|
1825
|
-
// submissions in Next.js 16 with Server Actions
|
|
1826
2113
|
if (!keepStateOptions.keepErrors) {
|
|
1827
2114
|
_formState.errors = {};
|
|
1828
2115
|
}
|
|
@@ -1834,8 +2121,10 @@ function createFormControl(props = {}) {
|
|
|
1834
2121
|
? false
|
|
1835
2122
|
: keepStateOptions.keepDirty
|
|
1836
2123
|
? _formState.isDirty
|
|
1837
|
-
:
|
|
1838
|
-
|
|
2124
|
+
: keepStateOptions.keepValues
|
|
2125
|
+
? _getDirty()
|
|
2126
|
+
: !!(keepStateOptions.keepDefaultValues &&
|
|
2127
|
+
!deepEqual(formValues, _defaultValues)),
|
|
1839
2128
|
isSubmitted: keepStateOptions.keepIsSubmitted
|
|
1840
2129
|
? _formState.isSubmitted
|
|
1841
2130
|
: false,
|
|
@@ -1843,10 +2132,10 @@ function createFormControl(props = {}) {
|
|
|
1843
2132
|
? {}
|
|
1844
2133
|
: keepStateOptions.keepDirtyValues
|
|
1845
2134
|
? keepStateOptions.keepDefaultValues && _formValues
|
|
1846
|
-
? getDirtyFields(_defaultValues, _formValues)
|
|
2135
|
+
? getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs)
|
|
1847
2136
|
: _formState.dirtyFields
|
|
1848
2137
|
: keepStateOptions.keepDefaultValues && formValues
|
|
1849
|
-
? getDirtyFields(_defaultValues, formValues)
|
|
2138
|
+
? getDirtyFields(_defaultValues, formValues, undefined, fieldRefs)
|
|
1850
2139
|
: keepStateOptions.keepDirty
|
|
1851
2140
|
? _formState.dirtyFields
|
|
1852
2141
|
: {},
|
|
@@ -1872,8 +2161,6 @@ function createFormControl(props = {}) {
|
|
|
1872
2161
|
? fieldReference.refs[0]
|
|
1873
2162
|
: fieldReference.ref;
|
|
1874
2163
|
if (fieldRef.focus) {
|
|
1875
|
-
// Use setTimeout to ensure focus happens after any pending state updates
|
|
1876
|
-
// This fixes the issue where setFocus doesn't work immediately after setError
|
|
1877
2164
|
setTimeout(() => {
|
|
1878
2165
|
fieldRef.focus();
|
|
1879
2166
|
options.shouldSelect &&
|
|
@@ -1884,9 +2171,15 @@ function createFormControl(props = {}) {
|
|
|
1884
2171
|
}
|
|
1885
2172
|
};
|
|
1886
2173
|
const _setFormState = (updatedFormState) => {
|
|
2174
|
+
// `name`, `type`, and `values` describe the event that produced this
|
|
2175
|
+
// update, not the form's persisted state (they aren't part of
|
|
2176
|
+
// `FormState`). Merging them in would leak a stale `name`/`type` from
|
|
2177
|
+
// one event into a later, unrelated notification that doesn't specify
|
|
2178
|
+
// its own.
|
|
2179
|
+
const { name, type, values, ...formState } = updatedFormState;
|
|
1887
2180
|
_formState = {
|
|
1888
2181
|
..._formState,
|
|
1889
|
-
...
|
|
2182
|
+
...formState,
|
|
1890
2183
|
};
|
|
1891
2184
|
};
|
|
1892
2185
|
const _resetDefaultValues = () => isFunction(_options.defaultValues) &&
|
|
@@ -1896,6 +2189,21 @@ function createFormControl(props = {}) {
|
|
|
1896
2189
|
isLoading: false,
|
|
1897
2190
|
});
|
|
1898
2191
|
});
|
|
2192
|
+
const resetDefaultValues = (values, options = {}) => {
|
|
2193
|
+
_defaultValues = cloneObject(values);
|
|
2194
|
+
if (!options.keepDirty) {
|
|
2195
|
+
const newDirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
|
|
2196
|
+
_formState.dirtyFields = newDirtyFields;
|
|
2197
|
+
_formState.isDirty = !isEmptyObject(newDirtyFields);
|
|
2198
|
+
}
|
|
2199
|
+
if (!options.keepIsValid) {
|
|
2200
|
+
_setValid();
|
|
2201
|
+
}
|
|
2202
|
+
_subjects.state.next({
|
|
2203
|
+
..._formState,
|
|
2204
|
+
defaultValues: _defaultValues,
|
|
2205
|
+
});
|
|
2206
|
+
};
|
|
1899
2207
|
const methods = {
|
|
1900
2208
|
control: {
|
|
1901
2209
|
register,
|
|
@@ -1952,6 +2260,8 @@ function createFormControl(props = {}) {
|
|
|
1952
2260
|
..._options,
|
|
1953
2261
|
...value,
|
|
1954
2262
|
};
|
|
2263
|
+
_validationModeBeforeSubmit = getValidationModes(_options.mode);
|
|
2264
|
+
_validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
|
1955
2265
|
},
|
|
1956
2266
|
},
|
|
1957
2267
|
subscribe,
|
|
@@ -1960,9 +2270,11 @@ function createFormControl(props = {}) {
|
|
|
1960
2270
|
handleSubmit,
|
|
1961
2271
|
watch,
|
|
1962
2272
|
setValue,
|
|
2273
|
+
setValues,
|
|
1963
2274
|
getValues,
|
|
1964
2275
|
reset,
|
|
1965
2276
|
resetField,
|
|
2277
|
+
resetDefaultValues,
|
|
1966
2278
|
clearErrors,
|
|
1967
2279
|
unregister,
|
|
1968
2280
|
setError,
|