react-hook-form 7.81.0 → 7.82.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 +6 -7
- 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 +2277 -2216
- 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.map +1 -1
- package/dist/logic/getDirtyFields.d.ts +3 -2
- package/dist/logic/getDirtyFields.d.ts.map +1 -1
- package/dist/react-server.esm.mjs +82 -57
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/types/form.d.ts +1 -0
- package/dist/types/form.d.ts.map +1 -1
- package/dist/useFormContext.d.ts +1 -1
- package/dist/useFormContext.d.ts.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFormControl.d.ts","sourceRoot":"","sources":["../../src/logic/createFormControl.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAcV,WAAW,
|
|
1
|
+
{"version":3,"file":"createFormControl.d.ts","sourceRoot":"","sources":["../../src/logic/createFormControl.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAcV,WAAW,EAkBX,YAAY,EAKZ,aAAa,EAYd,MAAM,UAAU,CAAC;AA0DlB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;CAY9B,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,GAAG,EACd,kBAAkB,GAAG,YAAY,EAEjC,KAAK,GAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAM,GACnE,IAAI,CACL,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAC,EACzD,WAAW,CACZ,GAAG;IACF,WAAW,EAAE,IAAI,CACf,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAC,EACzD,WAAW,CACZ,CAAC;CACH,CA62DA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import type { FieldRefs } from '../types';
|
|
2
|
+
declare function markFieldsDirty<T>(data: T, fields?: Record<string, any>, fieldRefs?: Record<string, any>): Record<string, any>;
|
|
3
|
+
export default function getDirtyFields<T>(data: T, formValues: T, dirtyFieldsFromValues?: Record<Extract<keyof T, string>, ReturnType<typeof markFieldsDirty> | boolean>, fieldRefs?: FieldRefs): Record<Extract<keyof T, string>, boolean | Record<string, any>>;
|
|
3
4
|
export {};
|
|
4
5
|
//# sourceMappingURL=getDirtyFields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDirtyFields.d.ts","sourceRoot":"","sources":["../../src/logic/getDirtyFields.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getDirtyFields.d.ts","sourceRoot":"","sources":["../../src/logic/getDirtyFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AA8B1C,iBAAS,eAAe,CAAC,CAAC,EACxB,IAAI,EAAE,CAAC,EACP,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAChC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,uBAsBhC;AAED,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,CAAC,EACtC,IAAI,EAAE,CAAC,EACP,UAAU,EAAE,CAAC,EACb,qBAAqB,CAAC,EAAE,MAAM,CAC5B,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EACxB,UAAU,CAAC,OAAO,eAAe,CAAC,GAAG,OAAO,CAC7C,EACD,SAAS,CAAC,EAAE,SAAS,mEAwCtB"}
|
|
@@ -353,12 +353,33 @@ var objectHasFunction = (data) => {
|
|
|
353
353
|
function isTraversable(value) {
|
|
354
354
|
return Array.isArray(value) || (isObject(value) && !objectHasFunction(value));
|
|
355
355
|
}
|
|
356
|
-
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) {
|
|
357
373
|
for (const key in data) {
|
|
358
374
|
const value = data[key];
|
|
359
|
-
|
|
375
|
+
const fieldRef = fieldRefs && fieldRefs[key];
|
|
376
|
+
if (isTraversable(value) &&
|
|
377
|
+
(!Array.isArray(value) || !isRegisteredLeaf(fieldRef))) {
|
|
360
378
|
fields[key] = Array.isArray(value) ? [] : {};
|
|
361
|
-
markFieldsDirty(value, fields[key]);
|
|
379
|
+
markFieldsDirty(value, fields[key], fieldRef);
|
|
380
|
+
if (isEmptyDirtyContainer(fields[key])) {
|
|
381
|
+
clearDirtyField(fields, key);
|
|
382
|
+
}
|
|
362
383
|
}
|
|
363
384
|
else if (!isUndefined(value)) {
|
|
364
385
|
fields[key] = true;
|
|
@@ -366,49 +387,33 @@ function markFieldsDirty(data, fields = {}) {
|
|
|
366
387
|
}
|
|
367
388
|
return fields;
|
|
368
389
|
}
|
|
369
|
-
function
|
|
370
|
-
if (value === false) {
|
|
371
|
-
return undefined;
|
|
372
|
-
}
|
|
373
|
-
if (value === true) {
|
|
374
|
-
return true;
|
|
375
|
-
}
|
|
376
|
-
if (Array.isArray(value)) {
|
|
377
|
-
const result = value.map((value) => pruneDirtyFields(value));
|
|
378
|
-
return (result.some((value) => value !== undefined) ? result : undefined);
|
|
379
|
-
}
|
|
380
|
-
if (isObject(value)) {
|
|
381
|
-
const result = {};
|
|
382
|
-
for (const key in value) {
|
|
383
|
-
const pruned = pruneDirtyFields(value[key]);
|
|
384
|
-
if (!isUndefined(pruned)) {
|
|
385
|
-
result[key] = pruned;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
return (Object.keys(result).length ? result : undefined);
|
|
389
|
-
}
|
|
390
|
-
return undefined;
|
|
391
|
-
}
|
|
392
|
-
function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
|
|
390
|
+
function getDirtyFields(data, formValues, dirtyFieldsFromValues, fieldRefs) {
|
|
393
391
|
if (!dirtyFieldsFromValues) {
|
|
394
|
-
dirtyFieldsFromValues = markFieldsDirty(formValues);
|
|
392
|
+
dirtyFieldsFromValues = markFieldsDirty(formValues, {}, fieldRefs);
|
|
395
393
|
}
|
|
396
394
|
for (const key in data) {
|
|
397
395
|
const value = data[key];
|
|
398
|
-
|
|
396
|
+
const fieldRef = fieldRefs && fieldRefs[key];
|
|
397
|
+
if (isTraversable(value) &&
|
|
398
|
+
(!Array.isArray(value) || !isRegisteredLeaf(fieldRef))) {
|
|
399
399
|
if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) {
|
|
400
|
-
dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {});
|
|
400
|
+
dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {}, fieldRef);
|
|
401
401
|
}
|
|
402
402
|
else {
|
|
403
|
-
getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
|
|
403
|
+
getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key], fieldRef);
|
|
404
404
|
}
|
|
405
|
+
if (isEmptyDirtyContainer(dirtyFieldsFromValues[key])) {
|
|
406
|
+
clearDirtyField(dirtyFieldsFromValues, key);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
else if (deepEqual(value, formValues[key])) {
|
|
410
|
+
clearDirtyField(dirtyFieldsFromValues, key);
|
|
405
411
|
}
|
|
406
412
|
else {
|
|
407
|
-
|
|
408
|
-
dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
|
|
413
|
+
dirtyFieldsFromValues[key] = true;
|
|
409
414
|
}
|
|
410
415
|
}
|
|
411
|
-
return
|
|
416
|
+
return dirtyFieldsFromValues;
|
|
412
417
|
}
|
|
413
418
|
|
|
414
419
|
var getEventValue = (event) => isObject(event) && event.target
|
|
@@ -926,8 +931,8 @@ function createFormControl(props = {}) {
|
|
|
926
931
|
watch: new Set(),
|
|
927
932
|
registerName: new Set(),
|
|
928
933
|
};
|
|
929
|
-
|
|
930
|
-
|
|
934
|
+
const delayErrorCallbacks = {};
|
|
935
|
+
const timers = {};
|
|
931
936
|
let _valuesSubscriberCount = 0;
|
|
932
937
|
let _validationModeBeforeSubmit = getValidationModes(_options.mode);
|
|
933
938
|
let _validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
|
@@ -950,10 +955,11 @@ function createFormControl(props = {}) {
|
|
|
950
955
|
array: createSubject(),
|
|
951
956
|
state: createSubject(),
|
|
952
957
|
};
|
|
958
|
+
let _setValidCallId = 0;
|
|
953
959
|
const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
|
|
954
|
-
const debounce = (callback) => (wait) => {
|
|
955
|
-
clearTimeout(
|
|
956
|
-
|
|
960
|
+
const debounce = (name, callback) => (wait) => {
|
|
961
|
+
clearTimeout(timers[name]);
|
|
962
|
+
timers[name] = setTimeout(callback, wait);
|
|
957
963
|
};
|
|
958
964
|
const _setValid = async (shouldUpdateValid) => {
|
|
959
965
|
if (_state.keepIsValid) {
|
|
@@ -963,10 +969,11 @@ function createFormControl(props = {}) {
|
|
|
963
969
|
(_proxyFormState.isValid ||
|
|
964
970
|
_proxySubscribeFormState.isValid ||
|
|
965
971
|
shouldUpdateValid)) {
|
|
972
|
+
const callId = ++_setValidCallId;
|
|
966
973
|
let isValid;
|
|
967
974
|
if (_options.resolver) {
|
|
968
975
|
isValid = isEmptyObject((await _runSchema()).errors);
|
|
969
|
-
_updateIsValidating();
|
|
976
|
+
callId === _setValidCallId && _updateIsValidating();
|
|
970
977
|
}
|
|
971
978
|
else {
|
|
972
979
|
isValid = await executeBuiltInValidation({
|
|
@@ -975,7 +982,7 @@ function createFormControl(props = {}) {
|
|
|
975
982
|
eventType: EVENTS.VALID,
|
|
976
983
|
});
|
|
977
984
|
}
|
|
978
|
-
if (isValid !== _formState.isValid) {
|
|
985
|
+
if (callId === _setValidCallId && isValid !== _formState.isValid) {
|
|
979
986
|
_subjects.state.next({
|
|
980
987
|
isValid,
|
|
981
988
|
});
|
|
@@ -1002,7 +1009,7 @@ function createFormControl(props = {}) {
|
|
|
1002
1009
|
}
|
|
1003
1010
|
};
|
|
1004
1011
|
const _updateDirtyFields = () => {
|
|
1005
|
-
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
1012
|
+
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
|
|
1006
1013
|
};
|
|
1007
1014
|
const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
|
1008
1015
|
if (args && method && !_options.disabled) {
|
|
@@ -1108,7 +1115,9 @@ function createFormControl(props = {}) {
|
|
|
1108
1115
|
const output = {
|
|
1109
1116
|
name,
|
|
1110
1117
|
};
|
|
1111
|
-
|
|
1118
|
+
// an explicit programmatic update (e.g. setValue with shouldDirty: true)
|
|
1119
|
+
// opts into dirty tracking even when the form is disabled
|
|
1120
|
+
if (!_options.disabled || shouldDirty === true) {
|
|
1112
1121
|
if (!isBlurEvent || shouldDirty) {
|
|
1113
1122
|
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
|
1114
1123
|
if (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty) {
|
|
@@ -1119,7 +1128,7 @@ function createFormControl(props = {}) {
|
|
|
1119
1128
|
}
|
|
1120
1129
|
isPreviousDirty = !!get(_formState.dirtyFields, name);
|
|
1121
1130
|
if (isCurrentFieldPristine !== _formState.isDirty) {
|
|
1122
|
-
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
1131
|
+
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
|
|
1123
1132
|
}
|
|
1124
1133
|
else {
|
|
1125
1134
|
isCurrentFieldPristine
|
|
@@ -1155,12 +1164,12 @@ function createFormControl(props = {}) {
|
|
|
1155
1164
|
isBoolean(isValid) &&
|
|
1156
1165
|
_formState.isValid !== isValid;
|
|
1157
1166
|
if (_options.delayError && error) {
|
|
1158
|
-
|
|
1159
|
-
|
|
1167
|
+
delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
|
|
1168
|
+
delayErrorCallbacks[name](_options.delayError);
|
|
1160
1169
|
}
|
|
1161
1170
|
else {
|
|
1162
|
-
clearTimeout(
|
|
1163
|
-
|
|
1171
|
+
clearTimeout(timers[name]);
|
|
1172
|
+
delete delayErrorCallbacks[name];
|
|
1164
1173
|
error
|
|
1165
1174
|
? set(_formState.errors, name, error)
|
|
1166
1175
|
: unset(_formState.errors, name);
|
|
@@ -1313,9 +1322,8 @@ function createFormControl(props = {}) {
|
|
|
1313
1322
|
}
|
|
1314
1323
|
_names.unMount = new Set();
|
|
1315
1324
|
};
|
|
1316
|
-
const _getDirty = (name, data) =>
|
|
1317
|
-
(
|
|
1318
|
-
!deepEqual(_state.mount ? _formValues : _defaultValues, _defaultValues));
|
|
1325
|
+
const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
|
|
1326
|
+
!deepEqual(_state.mount ? _formValues : _defaultValues, _defaultValues));
|
|
1319
1327
|
const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
|
|
1320
1328
|
...(_state.mount
|
|
1321
1329
|
? _formValues
|
|
@@ -1375,7 +1383,10 @@ function createFormControl(props = {}) {
|
|
|
1375
1383
|
}
|
|
1376
1384
|
(options.shouldDirty || options.shouldTouch) &&
|
|
1377
1385
|
updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, !skipRender);
|
|
1378
|
-
options.shouldValidate &&
|
|
1386
|
+
options.shouldValidate &&
|
|
1387
|
+
trigger(name, {
|
|
1388
|
+
delayError: options.delayError,
|
|
1389
|
+
});
|
|
1379
1390
|
};
|
|
1380
1391
|
const setFieldValues = (name, value, options, skipClone = false, skipRender = false) => {
|
|
1381
1392
|
for (const fieldKey in value) {
|
|
@@ -1500,7 +1511,8 @@ function createFormControl(props = {}) {
|
|
|
1500
1511
|
if (isBlurEvent) {
|
|
1501
1512
|
if (!target || !target.readOnly) {
|
|
1502
1513
|
field._f.onBlur && field._f.onBlur(event);
|
|
1503
|
-
|
|
1514
|
+
const pendingDelayError = delayErrorCallbacks[name];
|
|
1515
|
+
pendingDelayError && pendingDelayError(0);
|
|
1504
1516
|
}
|
|
1505
1517
|
}
|
|
1506
1518
|
else if (field._f.onChange) {
|
|
@@ -1615,6 +1627,18 @@ function createFormControl(props = {}) {
|
|
|
1615
1627
|
eventType: EVENTS.TRIGGER,
|
|
1616
1628
|
});
|
|
1617
1629
|
}
|
|
1630
|
+
if (options.delayError && _options.delayError && isString(name)) {
|
|
1631
|
+
const error = get(_formState.errors, name);
|
|
1632
|
+
if (error) {
|
|
1633
|
+
unset(_formState.errors, name);
|
|
1634
|
+
delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
|
|
1635
|
+
delayErrorCallbacks[name](_options.delayError);
|
|
1636
|
+
}
|
|
1637
|
+
else {
|
|
1638
|
+
clearTimeout(timers[name]);
|
|
1639
|
+
delete delayErrorCallbacks[name];
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1618
1642
|
_subjects.state.next({
|
|
1619
1643
|
...(!isString(name) ||
|
|
1620
1644
|
((_proxyFormState.isValid || _proxySubscribeFormState.isValid) &&
|
|
@@ -1983,6 +2007,7 @@ function createFormControl(props = {}) {
|
|
|
1983
2007
|
const cloneUpdatedValues = cloneObject(updatedValues);
|
|
1984
2008
|
const isEmptyResetValues = isEmptyObject(formValues);
|
|
1985
2009
|
const values = cloneUpdatedValues;
|
|
2010
|
+
const fieldRefs = _fields;
|
|
1986
2011
|
if (!keepStateOptions.keepDefaultValues) {
|
|
1987
2012
|
_defaultValues = updatedValues;
|
|
1988
2013
|
}
|
|
@@ -1990,7 +2015,7 @@ function createFormControl(props = {}) {
|
|
|
1990
2015
|
if (keepStateOptions.keepDirtyValues) {
|
|
1991
2016
|
const fieldsToCheck = new Set([
|
|
1992
2017
|
..._names.mount,
|
|
1993
|
-
...Object.keys(getDirtyFields(_defaultValues, _formValues)),
|
|
2018
|
+
...Object.keys(getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs)),
|
|
1994
2019
|
]);
|
|
1995
2020
|
for (const fieldName of Array.from(fieldsToCheck)) {
|
|
1996
2021
|
const isDirty = get(_formState.dirtyFields, fieldName);
|
|
@@ -2093,10 +2118,10 @@ function createFormControl(props = {}) {
|
|
|
2093
2118
|
? {}
|
|
2094
2119
|
: keepStateOptions.keepDirtyValues
|
|
2095
2120
|
? keepStateOptions.keepDefaultValues && _formValues
|
|
2096
|
-
? getDirtyFields(_defaultValues, _formValues)
|
|
2121
|
+
? getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs)
|
|
2097
2122
|
: _formState.dirtyFields
|
|
2098
2123
|
: keepStateOptions.keepDefaultValues && formValues
|
|
2099
|
-
? getDirtyFields(_defaultValues, formValues)
|
|
2124
|
+
? getDirtyFields(_defaultValues, formValues, undefined, fieldRefs)
|
|
2100
2125
|
: keepStateOptions.keepDirty
|
|
2101
2126
|
? _formState.dirtyFields
|
|
2102
2127
|
: {},
|
|
@@ -2153,7 +2178,7 @@ function createFormControl(props = {}) {
|
|
|
2153
2178
|
const resetDefaultValues = (values, options = {}) => {
|
|
2154
2179
|
_defaultValues = cloneObject(values);
|
|
2155
2180
|
if (!options.keepDirty) {
|
|
2156
|
-
const newDirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
2181
|
+
const newDirtyFields = getDirtyFields(_defaultValues, _formValues, undefined, _fields);
|
|
2157
2182
|
_formState.dirtyFields = newDirtyFields;
|
|
2158
2183
|
_formState.isDirty = !isEmptyObject(newDirtyFields);
|
|
2159
2184
|
}
|