react-hook-form 7.20.0 → 7.20.4
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/CHANGELOG.md +25 -2
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +80 -79
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/logic/generateWatchOutput.d.ts +2 -1
- package/dist/logic/getDirtyFields.d.ts +2 -0
- package/dist/logic/{getControllerValue.d.ts → getEventValue.d.ts} +0 -0
- package/dist/useWatch.d.ts +1 -1
- package/dist/utils/objectHasFunction.d.ts +2 -0
- package/package.json +3 -4
- package/dist/logic/setFieldArrayDirtyFields.d.ts +0 -2
- package/dist/logic/unsetEmptyArray.d.ts +0 -2
package/dist/index.esm.js
CHANGED
@@ -12,7 +12,7 @@ var isObject = (value) => !isNullOrUndefined(value) &&
|
|
12
12
|
isObjectType(value) &&
|
13
13
|
!isDateObject(value);
|
14
14
|
|
15
|
-
var
|
15
|
+
var getEventValue = (event) => isObject(event) && event.target
|
16
16
|
? isCheckBoxInput(event.target)
|
17
17
|
? event.target.checked
|
18
18
|
: event.target.value
|
@@ -155,7 +155,7 @@ function useFormState(props) {
|
|
155
155
|
|
156
156
|
var isString = (value) => typeof value === 'string';
|
157
157
|
|
158
|
-
|
158
|
+
var generateWatchOutput = (names, _names, formValues, isGlobal) => {
|
159
159
|
const isArray = Array.isArray(names);
|
160
160
|
if (isString(names)) {
|
161
161
|
isGlobal && _names.watch.add(names);
|
@@ -167,7 +167,18 @@ function generateWatchOutput(names, _names, formValues, isGlobal) {
|
|
167
167
|
}
|
168
168
|
isGlobal && (_names.watchAll = true);
|
169
169
|
return formValues;
|
170
|
-
}
|
170
|
+
};
|
171
|
+
|
172
|
+
var isFunction = (value) => typeof value === 'function';
|
173
|
+
|
174
|
+
var objectHasFunction = (data) => {
|
175
|
+
for (const key in data) {
|
176
|
+
if (isFunction(data[key])) {
|
177
|
+
return true;
|
178
|
+
}
|
179
|
+
}
|
180
|
+
return false;
|
181
|
+
};
|
171
182
|
|
172
183
|
function useWatch(props) {
|
173
184
|
const methods = useFormContext();
|
@@ -180,7 +191,8 @@ function useWatch(props) {
|
|
180
191
|
callback: (formState) => {
|
181
192
|
if (shouldSubscribeByName(_name.current, formState.name, exact)) {
|
182
193
|
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
183
|
-
updateValue(isUndefined(_name.current)
|
194
|
+
updateValue(isUndefined(_name.current) ||
|
195
|
+
(isObject(fieldValues) && !objectHasFunction(fieldValues))
|
184
196
|
? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
|
185
197
|
? [...fieldValues]
|
186
198
|
: fieldValues);
|
@@ -238,7 +250,7 @@ function useController(props) {
|
|
238
250
|
onChange: (event) => {
|
239
251
|
registerProps.onChange({
|
240
252
|
target: {
|
241
|
-
value:
|
253
|
+
value: getEventValue(event),
|
242
254
|
name: name,
|
243
255
|
},
|
244
256
|
type: EVENTS.CHANGE,
|
@@ -436,44 +448,44 @@ const useFieldArray = (props) => {
|
|
436
448
|
const append$1 = (value, options) => {
|
437
449
|
const appendValue = convertToArrayPayload(value);
|
438
450
|
const updatedFieldArrayValuesWithKey = append(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), mapIds(appendValue, keyName));
|
451
|
+
setFields(updatedFieldArrayValuesWithKey);
|
439
452
|
control._updateFieldArray(name, append, {
|
440
453
|
argA: fillEmptyArray(value),
|
441
454
|
}, updateValues(updatedFieldArrayValuesWithKey));
|
442
|
-
setFields(updatedFieldArrayValuesWithKey);
|
443
455
|
control._names.focus = getFocusFieldName(name, updatedFieldArrayValuesWithKey.length - appendValue.length, options);
|
444
456
|
};
|
445
457
|
const prepend$1 = (value, options) => {
|
446
458
|
const updatedFieldArrayValuesWithKey = prepend(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), mapIds(convertToArrayPayload(value), keyName));
|
459
|
+
setFields(updatedFieldArrayValuesWithKey);
|
447
460
|
control._updateFieldArray(name, prepend, {
|
448
461
|
argA: fillEmptyArray(value),
|
449
462
|
}, updateValues(updatedFieldArrayValuesWithKey));
|
450
|
-
setFields(updatedFieldArrayValuesWithKey);
|
451
463
|
control._names.focus = getFocusFieldName(name, 0, options);
|
452
464
|
};
|
453
465
|
const remove = (index) => {
|
454
466
|
const updatedFieldArrayValuesWithKey = removeArrayAt(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), index);
|
467
|
+
setFields(updatedFieldArrayValuesWithKey);
|
455
468
|
control._updateFieldArray(name, removeArrayAt, {
|
456
469
|
argA: index,
|
457
470
|
}, updateValues(updatedFieldArrayValuesWithKey));
|
458
|
-
setFields(updatedFieldArrayValuesWithKey);
|
459
471
|
};
|
460
472
|
const insert$1 = (index, value, options) => {
|
461
473
|
const updatedFieldArrayValuesWithKey = insert(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), index, mapIds(convertToArrayPayload(value), keyName));
|
474
|
+
setFields(updatedFieldArrayValuesWithKey);
|
462
475
|
control._updateFieldArray(name, insert, {
|
463
476
|
argA: index,
|
464
477
|
argB: fillEmptyArray(value),
|
465
478
|
}, updateValues(updatedFieldArrayValuesWithKey));
|
466
|
-
setFields(updatedFieldArrayValuesWithKey);
|
467
479
|
control._names.focus = getFocusFieldName(name, index, options);
|
468
480
|
};
|
469
481
|
const swap = (indexA, indexB) => {
|
470
482
|
const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
|
471
483
|
swapArrayAt(updatedFieldArrayValuesWithKey, indexA, indexB);
|
484
|
+
setFields(updatedFieldArrayValuesWithKey);
|
472
485
|
control._updateFieldArray(name, swapArrayAt, {
|
473
486
|
argA: indexA,
|
474
487
|
argB: indexB,
|
475
488
|
}, updateValues(updatedFieldArrayValuesWithKey), false);
|
476
|
-
setFields(updatedFieldArrayValuesWithKey);
|
477
489
|
};
|
478
490
|
const move = (from, to) => {
|
479
491
|
const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
|
@@ -488,16 +500,16 @@ const useFieldArray = (props) => {
|
|
488
500
|
const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
|
489
501
|
const updatedFieldArrayValues = updateAt(updatedFieldArrayValuesWithKey, index, value);
|
490
502
|
_fieldIds.current = mapIds(updatedFieldArrayValues, keyName);
|
503
|
+
setFields(_fieldIds.current);
|
491
504
|
control._updateFieldArray(name, updateAt, {
|
492
505
|
argA: index,
|
493
506
|
argB: value,
|
494
507
|
}, updateValues(_fieldIds.current), true, false);
|
495
|
-
setFields(_fieldIds.current);
|
496
508
|
};
|
497
509
|
const replace = (value) => {
|
498
510
|
const updatedFieldArrayValuesWithKey = mapIds(convertToArrayPayload(value), keyName);
|
499
|
-
control._updateFieldArray(name, () => updatedFieldArrayValuesWithKey, {}, updateValues(updatedFieldArrayValuesWithKey), true, false);
|
500
511
|
setFields(updatedFieldArrayValuesWithKey);
|
512
|
+
control._updateFieldArray(name, () => updatedFieldArrayValuesWithKey, {}, updateValues(updatedFieldArrayValuesWithKey), true, false);
|
501
513
|
};
|
502
514
|
React.useEffect(() => {
|
503
515
|
control._stateFlags.action = false;
|
@@ -543,8 +555,6 @@ const useFieldArray = (props) => {
|
|
543
555
|
};
|
544
556
|
};
|
545
557
|
|
546
|
-
var isFunction = (value) => typeof value === 'function';
|
547
|
-
|
548
558
|
function cloneObject(data) {
|
549
559
|
let copy;
|
550
560
|
const isArray = Array.isArray(data);
|
@@ -696,6 +706,47 @@ function unset(object, path) {
|
|
696
706
|
return object;
|
697
707
|
}
|
698
708
|
|
709
|
+
function markFieldsDirty(data, fields = {}) {
|
710
|
+
const isParentNodeArray = Array.isArray(data);
|
711
|
+
if (isObject(data) || isParentNodeArray) {
|
712
|
+
for (const key in data) {
|
713
|
+
if (Array.isArray(data[key]) ||
|
714
|
+
(isObject(data[key]) && !objectHasFunction(data[key]))) {
|
715
|
+
fields[key] = Array.isArray(data[key]) ? [] : {};
|
716
|
+
markFieldsDirty(data[key], fields[key]);
|
717
|
+
}
|
718
|
+
else if (!isNullOrUndefined(data[key])) {
|
719
|
+
fields[key] = true;
|
720
|
+
}
|
721
|
+
}
|
722
|
+
}
|
723
|
+
return fields;
|
724
|
+
}
|
725
|
+
function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues) {
|
726
|
+
const isParentNodeArray = Array.isArray(data);
|
727
|
+
if (isObject(data) || isParentNodeArray) {
|
728
|
+
for (const key in data) {
|
729
|
+
if (Array.isArray(data[key]) ||
|
730
|
+
(isObject(data[key]) && !objectHasFunction(data[key]))) {
|
731
|
+
if (isUndefined(formValues) ||
|
732
|
+
isPrimitive(dirtyFieldsFromValues[key])) {
|
733
|
+
dirtyFieldsFromValues[key] = Array.isArray(data[key])
|
734
|
+
? markFieldsDirty(data[key], [])
|
735
|
+
: Object.assign({}, markFieldsDirty(data[key]));
|
736
|
+
}
|
737
|
+
else {
|
738
|
+
getDirtyFieldsFromDefaultValues(data[key], isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
|
739
|
+
}
|
740
|
+
}
|
741
|
+
else {
|
742
|
+
dirtyFieldsFromValues[key] = !deepEqual(data[key], formValues[key]);
|
743
|
+
}
|
744
|
+
}
|
745
|
+
}
|
746
|
+
return dirtyFieldsFromValues;
|
747
|
+
}
|
748
|
+
var getDirtyFields = (defaultValues, formValues) => getDirtyFieldsFromDefaultValues(defaultValues, formValues, markFieldsDirty(formValues));
|
749
|
+
|
699
750
|
const defaultResult = {
|
700
751
|
value: false,
|
701
752
|
isValid: false,
|
@@ -818,49 +869,6 @@ function schemaErrorLookup(errors, _fields, name) {
|
|
818
869
|
};
|
819
870
|
}
|
820
871
|
|
821
|
-
function deepMerge(target, source) {
|
822
|
-
if (isPrimitive(target) || isPrimitive(source)) {
|
823
|
-
return source;
|
824
|
-
}
|
825
|
-
for (const key in source) {
|
826
|
-
const targetValue = target[key];
|
827
|
-
const sourceValue = source[key];
|
828
|
-
try {
|
829
|
-
target[key] =
|
830
|
-
(isObject(targetValue) && isObject(sourceValue)) ||
|
831
|
-
(Array.isArray(targetValue) && Array.isArray(sourceValue))
|
832
|
-
? deepMerge(targetValue, sourceValue)
|
833
|
-
: sourceValue;
|
834
|
-
}
|
835
|
-
catch (_a) { }
|
836
|
-
}
|
837
|
-
return target;
|
838
|
-
}
|
839
|
-
|
840
|
-
function setDirtyFields(values, defaultValues, dirtyFields, parentNode, parentName) {
|
841
|
-
let index = -1;
|
842
|
-
while (++index < values.length) {
|
843
|
-
for (const key in values[index]) {
|
844
|
-
if (Array.isArray(values[index][key])) {
|
845
|
-
!dirtyFields[index] && (dirtyFields[index] = {});
|
846
|
-
dirtyFields[index][key] = [];
|
847
|
-
setDirtyFields(values[index][key], get(defaultValues[index] || {}, key, []), dirtyFields[index][key], dirtyFields[index], key);
|
848
|
-
}
|
849
|
-
else {
|
850
|
-
!isNullOrUndefined(defaultValues) &&
|
851
|
-
deepEqual(get(defaultValues[index] || {}, key), values[index][key])
|
852
|
-
? set(dirtyFields[index] || {}, key)
|
853
|
-
: (dirtyFields[index] = Object.assign(Object.assign({}, dirtyFields[index]), { [key]: true }));
|
854
|
-
}
|
855
|
-
}
|
856
|
-
parentNode &&
|
857
|
-
!dirtyFields.length &&
|
858
|
-
delete parentNode[parentName];
|
859
|
-
}
|
860
|
-
return dirtyFields;
|
861
|
-
}
|
862
|
-
var setFieldArrayDirtyFields = (values, defaultValues, dirtyFields) => deepMerge(setDirtyFields(values, defaultValues, dirtyFields.slice(0, values.length)), setDirtyFields(defaultValues, values, dirtyFields.slice(0, values.length)));
|
863
|
-
|
864
872
|
var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode) => {
|
865
873
|
if (mode.isOnAll) {
|
866
874
|
return false;
|
@@ -877,8 +885,6 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
|
|
877
885
|
return true;
|
878
886
|
};
|
879
887
|
|
880
|
-
var unsetEmptyArray = (ref, name) => !compact(get(ref, name, [])).length && unset(ref, name);
|
881
|
-
|
882
888
|
var isMessage = (value) => isString(value) || React.isValidElement(value);
|
883
889
|
|
884
890
|
var isRegex = (value) => value instanceof RegExp;
|
@@ -908,7 +914,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
908
914
|
return {};
|
909
915
|
}
|
910
916
|
const inputRef = refs ? refs[0] : ref;
|
911
|
-
const
|
917
|
+
const setCustomValidity = (message) => {
|
912
918
|
if (shouldUseNativeValidation && inputRef.reportValidity) {
|
913
919
|
inputRef.setCustomValidity(isBoolean(message) ? '' : message || ' ');
|
914
920
|
inputRef.reportValidity();
|
@@ -938,7 +944,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
938
944
|
if (value) {
|
939
945
|
error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.required, message, ref: inputRef }, appendErrorsCurry(INPUT_VALIDATION_RULES.required, message));
|
940
946
|
if (!validateAllFieldCriteria) {
|
941
|
-
|
947
|
+
setCustomValidity(message);
|
942
948
|
return error;
|
943
949
|
}
|
944
950
|
}
|
@@ -969,7 +975,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
969
975
|
if (exceedMax || exceedMin) {
|
970
976
|
getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
|
971
977
|
if (!validateAllFieldCriteria) {
|
972
|
-
|
978
|
+
setCustomValidity(error[name].message);
|
973
979
|
return error;
|
974
980
|
}
|
975
981
|
}
|
@@ -984,7 +990,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
984
990
|
if (exceedMax || exceedMin) {
|
985
991
|
getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
|
986
992
|
if (!validateAllFieldCriteria) {
|
987
|
-
|
993
|
+
setCustomValidity(error[name].message);
|
988
994
|
return error;
|
989
995
|
}
|
990
996
|
}
|
@@ -995,7 +1001,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
995
1001
|
error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.pattern, message,
|
996
1002
|
ref }, appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message));
|
997
1003
|
if (!validateAllFieldCriteria) {
|
998
|
-
|
1004
|
+
setCustomValidity(message);
|
999
1005
|
return error;
|
1000
1006
|
}
|
1001
1007
|
}
|
@@ -1007,7 +1013,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1007
1013
|
if (validateError) {
|
1008
1014
|
error[name] = Object.assign(Object.assign({}, validateError), appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message));
|
1009
1015
|
if (!validateAllFieldCriteria) {
|
1010
|
-
|
1016
|
+
setCustomValidity(validateError.message);
|
1011
1017
|
return error;
|
1012
1018
|
}
|
1013
1019
|
}
|
@@ -1021,7 +1027,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1021
1027
|
const validateError = getValidateError(await validate[key](inputValue), inputRef, key);
|
1022
1028
|
if (validateError) {
|
1023
1029
|
validationResult = Object.assign(Object.assign({}, validateError), appendErrorsCurry(key, validateError.message));
|
1024
|
-
|
1030
|
+
setCustomValidity(validateError.message);
|
1025
1031
|
if (validateAllFieldCriteria) {
|
1026
1032
|
error[name] = validationResult;
|
1027
1033
|
}
|
@@ -1035,7 +1041,7 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1035
1041
|
}
|
1036
1042
|
}
|
1037
1043
|
}
|
1038
|
-
|
1044
|
+
setCustomValidity(true);
|
1039
1045
|
return error;
|
1040
1046
|
};
|
1041
1047
|
|
@@ -1122,16 +1128,14 @@ function createFormControl(props = {}) {
|
|
1122
1128
|
if (Array.isArray(get(_formState.errors, name))) {
|
1123
1129
|
const errors = method(get(_formState.errors, name), args.argA, args.argB);
|
1124
1130
|
shouldSetValues && set(_formState.errors, name, errors);
|
1125
|
-
unsetEmptyArray(_formState.errors, name);
|
1126
1131
|
}
|
1127
1132
|
if (_proxyFormState.touchedFields && get(_formState.touchedFields, name)) {
|
1128
1133
|
const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
|
1129
1134
|
shouldSetValues &&
|
1130
1135
|
set(_formState.touchedFields, name, touchedFields);
|
1131
|
-
unsetEmptyArray(_formState.touchedFields, name);
|
1132
1136
|
}
|
1133
1137
|
if (_proxyFormState.dirtyFields || _proxyFormState.isDirty) {
|
1134
|
-
|
1138
|
+
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
1135
1139
|
}
|
1136
1140
|
_subjects.state.next({
|
1137
1141
|
isDirty: _getDirty(name, values),
|
@@ -1189,8 +1193,6 @@ function createFormControl(props = {}) {
|
|
1189
1193
|
isFieldDirty && shouldRender && _subjects.state.next(output);
|
1190
1194
|
return isFieldDirty ? output : {};
|
1191
1195
|
};
|
1192
|
-
const updateFieldArrayDirty = (name, value) => (set(_formState.dirtyFields, name, setFieldArrayDirtyFields(value, get(_defaultValues, name, []), get(_formState.dirtyFields, name, []))),
|
1193
|
-
unsetEmptyArray(_formState.dirtyFields, name));
|
1194
1196
|
const shouldRenderByError = async (shouldSkipRender, name, isValid, error, fieldState) => {
|
1195
1197
|
const previousFieldError = get(_formState.errors, name);
|
1196
1198
|
const shouldUpdateValid = _proxyFormState.isValid && _formState.isValid !== isValid;
|
@@ -1302,10 +1304,7 @@ function createFormControl(props = {}) {
|
|
1302
1304
|
isWeb && isHTMLElement(fieldReference.ref) && isNullOrUndefined(value)
|
1303
1305
|
? ''
|
1304
1306
|
: value;
|
1305
|
-
if (
|
1306
|
-
fieldReference.ref.files = fieldValue;
|
1307
|
-
}
|
1308
|
-
else if (isMultipleSelect(fieldReference.ref)) {
|
1307
|
+
if (isMultipleSelect(fieldReference.ref)) {
|
1309
1308
|
[...fieldReference.ref.options].forEach((selectRef) => (selectRef.selected = fieldValue.includes(selectRef.value)));
|
1310
1309
|
}
|
1311
1310
|
else if (fieldReference.refs) {
|
@@ -1320,7 +1319,7 @@ function createFormControl(props = {}) {
|
|
1320
1319
|
fieldReference.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
|
1321
1320
|
}
|
1322
1321
|
}
|
1323
|
-
else {
|
1322
|
+
else if (!isFileInput(fieldReference.ref)) {
|
1324
1323
|
fieldReference.ref.value = fieldValue;
|
1325
1324
|
}
|
1326
1325
|
}
|
@@ -1353,7 +1352,7 @@ function createFormControl(props = {}) {
|
|
1353
1352
|
});
|
1354
1353
|
if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields) &&
|
1355
1354
|
options.shouldDirty) {
|
1356
|
-
|
1355
|
+
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
1357
1356
|
_subjects.state.next({
|
1358
1357
|
name,
|
1359
1358
|
dirtyFields: _formState.dirtyFields,
|
@@ -1378,7 +1377,9 @@ function createFormControl(props = {}) {
|
|
1378
1377
|
if (field) {
|
1379
1378
|
let error;
|
1380
1379
|
let isValid;
|
1381
|
-
const fieldValue = target.type
|
1380
|
+
const fieldValue = target.type
|
1381
|
+
? getFieldValue(field._f)
|
1382
|
+
: getEventValue(event);
|
1382
1383
|
const isBlurEvent = event.type === EVENTS.BLUR;
|
1383
1384
|
const shouldSkipValidation = (!hasValidation(field._f) &&
|
1384
1385
|
!_options.resolver &&
|