react-hook-form 6.9.2 → 6.9.5
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 +60 -42
- package/dist/index.cjs.development.js +171 -144
- package/dist/index.cjs.development.js.map +1 -1
- package/dist/index.cjs.production.min.js +1 -1
- package/dist/index.cjs.production.min.js.map +1 -1
- package/dist/index.esm.js +172 -146
- package/dist/index.esm.js.map +1 -1
- package/dist/index.ie11.development.js +199 -170
- package/dist/index.ie11.development.js.map +1 -1
- package/dist/index.ie11.production.min.js +1 -1
- package/dist/index.ie11.production.min.js.map +1 -1
- package/dist/index.umd.development.js +171 -144
- package/dist/index.umd.development.js.map +1 -1
- package/dist/index.umd.production.min.js +1 -1
- package/dist/index.umd.production.min.js.map +1 -1
- package/dist/logic/transformToNestObject.d.ts +1 -1
- package/dist/types/fieldArray.d.ts +9 -0
- package/dist/types/form.d.ts +3 -5
- package/dist/types/utils.d.ts +4 -4
- package/dist/useFieldArray.d.ts +2 -10
- package/dist/utils/cloneObject.d.ts +1 -0
- package/dist/utils/{filterBooleanArray.test.d.ts → cloneObject.test.d.ts} +0 -0
- package/dist/utils/{filterOutFalsy.d.ts → compact.d.ts} +0 -0
- package/dist/utils/{filterOutFalsy.test.d.ts → compact.test.d.ts} +0 -0
- package/dist/utils/{filterBooleanArray.d.ts → fillBooleanArray.d.ts} +0 -0
- package/dist/utils/{isArray.test.d.ts → fillBooleanArray.test.d.ts} +0 -0
- package/package.json +1 -1
- package/dist/utils/isArray.d.ts +0 -2
package/dist/index.esm.js
CHANGED
@@ -36,27 +36,23 @@ function attachEventListeners({ ref }, shouldAttachChangeEvent, handleChange) {
|
|
36
36
|
|
37
37
|
var isNullOrUndefined = (value) => value == null;
|
38
38
|
|
39
|
-
var isArray = (value) => Array.isArray(value);
|
40
|
-
|
41
39
|
const isObjectType = (value) => typeof value === 'object';
|
42
40
|
var isObject = (value) => !isNullOrUndefined(value) &&
|
43
|
-
!isArray(value) &&
|
41
|
+
!Array.isArray(value) &&
|
44
42
|
isObjectType(value) &&
|
45
43
|
!(value instanceof Date);
|
46
44
|
|
47
|
-
var isKey = (value) => !isArray(value) &&
|
45
|
+
var isKey = (value) => !Array.isArray(value) &&
|
48
46
|
(/^\w*$/.test(value) ||
|
49
47
|
!/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/.test(value));
|
50
48
|
|
51
|
-
var
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
return result;
|
59
|
-
};
|
49
|
+
var compact = (value) => value.filter(Boolean);
|
50
|
+
|
51
|
+
var stringToPath = (input) => compact(input
|
52
|
+
.replace(/["|']/g, '')
|
53
|
+
.replace(/\[/g, '.')
|
54
|
+
.replace(/\]/g, '')
|
55
|
+
.split('.'));
|
60
56
|
|
61
57
|
function set(object, path, value) {
|
62
58
|
let index = -1;
|
@@ -69,7 +65,7 @@ function set(object, path, value) {
|
|
69
65
|
if (index !== lastIndex) {
|
70
66
|
const objValue = object[key];
|
71
67
|
newValue =
|
72
|
-
isObject(objValue) || isArray(objValue)
|
68
|
+
isObject(objValue) || Array.isArray(objValue)
|
73
69
|
? objValue
|
74
70
|
: !isNaN(+tempPath[index + 1])
|
75
71
|
? []
|
@@ -81,20 +77,17 @@ function set(object, path, value) {
|
|
81
77
|
return object;
|
82
78
|
}
|
83
79
|
|
84
|
-
var transformToNestObject = (data
|
85
|
-
|
86
|
-
set(
|
87
|
-
return previous;
|
80
|
+
var transformToNestObject = (data, value = {}) => {
|
81
|
+
for (const key in data) {
|
82
|
+
!isKey(key) ? set(value, key, data[key]) : (value[key] = data[key]);
|
88
83
|
}
|
89
|
-
return
|
90
|
-
}
|
84
|
+
return value;
|
85
|
+
};
|
91
86
|
|
92
87
|
var isUndefined = (val) => val === undefined;
|
93
88
|
|
94
|
-
var filterOutFalsy = (value) => value.filter(Boolean);
|
95
|
-
|
96
89
|
var get = (obj, path, defaultValue) => {
|
97
|
-
const result =
|
90
|
+
const result = compact(path.split(/[,[\].]+?/)).reduce((result, key) => (isNullOrUndefined(result) ? result : result[key]), obj);
|
98
91
|
return isUndefined(result) || result === obj
|
99
92
|
? isUndefined(obj[path])
|
100
93
|
? defaultValue
|
@@ -132,7 +125,7 @@ const defaultReturn = {
|
|
132
125
|
isValid: false,
|
133
126
|
value: '',
|
134
127
|
};
|
135
|
-
var getRadioValue = (options) => isArray(options)
|
128
|
+
var getRadioValue = (options) => Array.isArray(options)
|
136
129
|
? options.reduce((previous, option) => option && option.ref.checked
|
137
130
|
? {
|
138
131
|
isValid: true,
|
@@ -159,7 +152,7 @@ const defaultResult = {
|
|
159
152
|
};
|
160
153
|
const validResult = { value: true, isValid: true };
|
161
154
|
var getCheckboxValue = (options) => {
|
162
|
-
if (isArray(options)) {
|
155
|
+
if (Array.isArray(options)) {
|
163
156
|
if (options.length > 1) {
|
164
157
|
const values = options
|
165
158
|
.filter((option) => option && option.ref.checked)
|
@@ -249,7 +242,7 @@ function unset(object, path) {
|
|
249
242
|
objectRef = objectRef ? objectRef[item] : object[item];
|
250
243
|
if (currentPathsLength === index &&
|
251
244
|
((isObject(objectRef) && isEmptyObject(objectRef)) ||
|
252
|
-
(isArray(objectRef) &&
|
245
|
+
(Array.isArray(objectRef) &&
|
253
246
|
!objectRef.filter((data) => (isObject(data) && !isEmptyObject(data)) || isBoolean(data)).length))) {
|
254
247
|
previousObjRef ? delete previousObjRef[item] : delete object[item];
|
255
248
|
}
|
@@ -275,15 +268,15 @@ function findRemovedFieldAndRemoveListener(fieldsRef, handleChange, field, shall
|
|
275
268
|
}
|
276
269
|
if ((isRadioInput(ref) || isCheckBoxInput(ref)) && fieldRef) {
|
277
270
|
const { options } = fieldRef;
|
278
|
-
if (isArray(options) && options.length) {
|
279
|
-
|
271
|
+
if (Array.isArray(options) && options.length) {
|
272
|
+
compact(options).forEach((option, index) => {
|
280
273
|
const { ref } = option;
|
281
274
|
if ((ref && isDetached(ref) && isSameRef(option, ref)) || forceDelete) {
|
282
275
|
removeAllEventListeners(ref, handleChange);
|
283
276
|
unset(options, `[${index}]`);
|
284
277
|
}
|
285
278
|
});
|
286
|
-
if (options && !
|
279
|
+
if (options && !compact(options).length) {
|
287
280
|
delete fieldsRef.current[name];
|
288
281
|
}
|
289
282
|
}
|
@@ -301,7 +294,7 @@ function setFieldArrayDirtyFields(values, defaultValues, dirtyFields, parentNode
|
|
301
294
|
let index = -1;
|
302
295
|
while (++index < values.length) {
|
303
296
|
for (const key in values[index]) {
|
304
|
-
if (isArray(values[index][key])) {
|
297
|
+
if (Array.isArray(values[index][key])) {
|
305
298
|
!dirtyFields[index] && (dirtyFields[index] = {});
|
306
299
|
dirtyFields[index][key] = [];
|
307
300
|
setFieldArrayDirtyFields(values[index][key], get(defaultValues[index] || {}, key, []), dirtyFields[index][key], dirtyFields[index], key);
|
@@ -331,13 +324,11 @@ function deepMerge(target, source) {
|
|
331
324
|
const targetValue = target[key];
|
332
325
|
const sourceValue = source[key];
|
333
326
|
try {
|
334
|
-
|
335
|
-
(
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
target[key] = sourceValue;
|
340
|
-
}
|
327
|
+
target[key] =
|
328
|
+
(isObject(targetValue) && isObject(sourceValue)) ||
|
329
|
+
(Array.isArray(targetValue) && Array.isArray(sourceValue))
|
330
|
+
? deepMerge(targetValue, sourceValue)
|
331
|
+
: sourceValue;
|
341
332
|
}
|
342
333
|
catch (_a) { }
|
343
334
|
}
|
@@ -350,7 +341,7 @@ var getFieldsValues = (fieldsRef, shallowFieldsStateRef, excludeDisabled, search
|
|
350
341
|
if (isUndefined(search) ||
|
351
342
|
(isString(search)
|
352
343
|
? name.startsWith(search)
|
353
|
-
: isArray(search) && search.find((data) => name.startsWith(data)))) {
|
344
|
+
: Array.isArray(search) && search.find((data) => name.startsWith(data)))) {
|
354
345
|
output[name] = getFieldValue(fieldsRef, name, undefined, excludeDisabled);
|
355
346
|
}
|
356
347
|
}
|
@@ -367,7 +358,8 @@ function deepEqual(object1 = [], object2 = [], isErrorObject) {
|
|
367
358
|
if (!(isErrorObject && ['ref', 'context'].includes(key))) {
|
368
359
|
const val1 = object1[key];
|
369
360
|
const val2 = object2[key];
|
370
|
-
if ((isObject(val1) || isArray(val1)) &&
|
361
|
+
if ((isObject(val1) || Array.isArray(val1)) &&
|
362
|
+
(isObject(val2) || Array.isArray(val2))
|
371
363
|
? !deepEqual(val1, val2, isErrorObject)
|
372
364
|
: val1 !== val2) {
|
373
365
|
return false;
|
@@ -559,7 +551,7 @@ var assignWatchFields = (fieldValues, fieldName, watchFields, inputValue, isSing
|
|
559
551
|
}
|
560
552
|
else {
|
561
553
|
value = get(fieldValues, fieldName);
|
562
|
-
if (isObject(value) || isArray(value)) {
|
554
|
+
if (isObject(value) || Array.isArray(value)) {
|
563
555
|
getPath(fieldName, value).forEach((name) => watchFields.add(name));
|
564
556
|
}
|
565
557
|
}
|
@@ -615,6 +607,22 @@ function onDomRemove(fieldsRef, removeFieldEventListenerAndRef) {
|
|
615
607
|
return observer;
|
616
608
|
}
|
617
609
|
|
610
|
+
function cloneObject(object) {
|
611
|
+
let copy;
|
612
|
+
if (isPrimitive(object)) {
|
613
|
+
return object;
|
614
|
+
}
|
615
|
+
if (object instanceof Date) {
|
616
|
+
copy = new Date(object.getTime());
|
617
|
+
return copy;
|
618
|
+
}
|
619
|
+
copy = Array.isArray(object) ? [] : {};
|
620
|
+
for (const key in object) {
|
621
|
+
copy[key] = cloneObject(object[key]);
|
622
|
+
}
|
623
|
+
return copy;
|
624
|
+
}
|
625
|
+
|
618
626
|
var modeChecker = (mode) => ({
|
619
627
|
isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
|
620
628
|
isOnBlur: mode === VALIDATION_MODE.onBlur,
|
@@ -643,7 +651,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
643
651
|
const isUnMount = useRef(false);
|
644
652
|
const isWatchAllRef = useRef(false);
|
645
653
|
const handleChangeRef = useRef();
|
646
|
-
const shallowFieldsStateRef = useRef(shouldUnregister ? {} :
|
654
|
+
const shallowFieldsStateRef = useRef(shouldUnregister ? {} : cloneObject(defaultValues));
|
647
655
|
const resetFieldArrayFunctionRef = useRef({});
|
648
656
|
const contextRef = useRef(context);
|
649
657
|
const resolverRef = useRef(resolver);
|
@@ -723,7 +731,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
723
731
|
}
|
724
732
|
else if (isCheckBoxInput(ref) && options) {
|
725
733
|
options.length > 1
|
726
|
-
? options.forEach(({ ref: checkboxRef }) => (checkboxRef.checked = isArray(value)
|
734
|
+
? options.forEach(({ ref: checkboxRef }) => (checkboxRef.checked = Array.isArray(value)
|
727
735
|
? !!value.find((data) => data === checkboxRef.value)
|
728
736
|
: value === checkboxRef.value))
|
729
737
|
: (options[0].ref.checked = !!value);
|
@@ -734,7 +742,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
734
742
|
}, []);
|
735
743
|
const isFormDirty = () => !deepEqual(getValues(), isEmptyObject(defaultValuesRef.current)
|
736
744
|
? defaultValuesAtRenderRef.current
|
737
|
-
: defaultValuesRef.current)
|
745
|
+
: defaultValuesRef.current);
|
738
746
|
const updateAndGetDirtyState = useCallback((name, shouldRender = true) => {
|
739
747
|
if (readFormStateRef.current.isDirty ||
|
740
748
|
readFormStateRef.current.dirtyFields) {
|
@@ -772,7 +780,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
772
780
|
const executeSchemaOrResolverValidation = useCallback(async (names) => {
|
773
781
|
const { errors } = await resolverRef.current(getValues(), contextRef.current, isValidateAllFieldCriteria);
|
774
782
|
const previousFormIsValid = formStateRef.current.isValid;
|
775
|
-
if (isArray(names)) {
|
783
|
+
if (Array.isArray(names)) {
|
776
784
|
const isInputsValid = names
|
777
785
|
.map((name) => {
|
778
786
|
const error = get(errors, name);
|
@@ -799,7 +807,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
799
807
|
if (resolverRef.current) {
|
800
808
|
return executeSchemaOrResolverValidation(fields);
|
801
809
|
}
|
802
|
-
if (isArray(fields)) {
|
810
|
+
if (Array.isArray(fields)) {
|
803
811
|
const result = await Promise.all(fields.map(async (data) => await executeValidation(data, null)));
|
804
812
|
updateFormState();
|
805
813
|
return result.every(Boolean);
|
@@ -829,8 +837,9 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
829
837
|
resetFieldArrayFunctionRef.current[name]({
|
830
838
|
[name]: value,
|
831
839
|
});
|
832
|
-
if (readFormStateRef.current.isDirty ||
|
833
|
-
readFormStateRef.current.dirtyFields)
|
840
|
+
if ((readFormStateRef.current.isDirty ||
|
841
|
+
readFormStateRef.current.dirtyFields) &&
|
842
|
+
config.shouldDirty) {
|
834
843
|
set(formStateRef.current.dirtyFields, name, setFieldArrayDirtyFields(value, get(defaultValuesRef.current, name, []), get(formStateRef.current.dirtyFields, name, [])));
|
835
844
|
updateFormState({
|
836
845
|
isDirty: !deepEqual(Object.assign(Object.assign({}, getValues()), { [name]: value }), defaultValuesRef.current),
|
@@ -908,11 +917,13 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
908
917
|
};
|
909
918
|
function setFieldArrayDefaultValues(data) {
|
910
919
|
if (!shouldUnregister) {
|
920
|
+
let copy = cloneObject(data);
|
911
921
|
for (const value of fieldArrayNamesRef.current) {
|
912
|
-
if (isKey(value) && !
|
913
|
-
|
922
|
+
if (isKey(value) && !copy[value]) {
|
923
|
+
copy = Object.assign(Object.assign({}, copy), { [value]: [] });
|
914
924
|
}
|
915
925
|
}
|
926
|
+
return copy;
|
916
927
|
}
|
917
928
|
return data;
|
918
929
|
}
|
@@ -920,7 +931,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
920
931
|
if (isString(payload)) {
|
921
932
|
return getFieldValue(fieldsRef, payload, shallowFieldsStateRef);
|
922
933
|
}
|
923
|
-
if (isArray(payload)) {
|
934
|
+
if (Array.isArray(payload)) {
|
924
935
|
const data = {};
|
925
936
|
for (const name of payload) {
|
926
937
|
set(data, name, getFieldValue(fieldsRef, name, shallowFieldsStateRef));
|
@@ -938,10 +949,26 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
938
949
|
});
|
939
950
|
}, [isValidateAllFieldCriteria]);
|
940
951
|
const removeFieldEventListener = useCallback((field, forceDelete) => findRemovedFieldAndRemoveListener(fieldsRef, handleChangeRef.current, field, shallowFieldsStateRef, shouldUnregister, forceDelete), [shouldUnregister]);
|
952
|
+
const updateWatchedValue = (name) => {
|
953
|
+
if (isWatchAllRef.current) {
|
954
|
+
updateFormState();
|
955
|
+
}
|
956
|
+
else if (watchFieldsRef) {
|
957
|
+
let shouldRenderUseWatch = true;
|
958
|
+
for (const watchField of watchFieldsRef.current) {
|
959
|
+
if (watchField.startsWith(name)) {
|
960
|
+
updateFormState();
|
961
|
+
shouldRenderUseWatch = false;
|
962
|
+
break;
|
963
|
+
}
|
964
|
+
}
|
965
|
+
shouldRenderUseWatch && renderWatchedInputs(name);
|
966
|
+
}
|
967
|
+
};
|
941
968
|
const removeFieldEventListenerAndRef = useCallback((field, forceDelete) => {
|
942
969
|
if (field) {
|
943
970
|
removeFieldEventListener(field, forceDelete);
|
944
|
-
if (shouldUnregister && !
|
971
|
+
if (shouldUnregister && !compact(field.options || []).length) {
|
945
972
|
unset(defaultValuesAtRenderRef.current, field.ref.name);
|
946
973
|
unset(validFieldsRef.current, field.ref.name);
|
947
974
|
unset(fieldsWithValidationRef.current, field.ref.name);
|
@@ -953,12 +980,13 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
953
980
|
dirtyFields: formStateRef.current.dirtyFields,
|
954
981
|
});
|
955
982
|
resolverRef.current && validateResolver();
|
983
|
+
updateWatchedValue(field.ref.name);
|
956
984
|
}
|
957
985
|
}
|
958
986
|
}, [validateResolver, removeFieldEventListener]);
|
959
987
|
function clearErrors(name) {
|
960
988
|
name &&
|
961
|
-
(isArray(name) ? name : [name]).forEach((inputName) => fieldsRef.current[inputName]
|
989
|
+
(Array.isArray(name) ? name : [name]).forEach((inputName) => fieldsRef.current[inputName]
|
962
990
|
? isKey(inputName)
|
963
991
|
? delete formStateRef.current.errors[inputName]
|
964
992
|
: set(formStateRef.current.errors, inputName, undefined)
|
@@ -989,7 +1017,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
989
1017
|
? get(combinedDefaultValues, fieldNames)
|
990
1018
|
: defaultValue, true);
|
991
1019
|
}
|
992
|
-
if (isArray(fieldNames)) {
|
1020
|
+
if (Array.isArray(fieldNames)) {
|
993
1021
|
return fieldNames.reduce((previous, name) => (Object.assign(Object.assign({}, previous), { [name]: assignWatchFields(fieldValues, name, watchFields, combinedDefaultValues) })), {});
|
994
1022
|
}
|
995
1023
|
isWatchAllRef.current = isUndefined(watchId);
|
@@ -1000,7 +1028,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1000
1028
|
return watchInternal(fieldNames, defaultValue);
|
1001
1029
|
}
|
1002
1030
|
function unregister(name) {
|
1003
|
-
for (const fieldName of isArray(name) ? name : [name]) {
|
1031
|
+
for (const fieldName of Array.isArray(name) ? name : [name]) {
|
1004
1032
|
removeFieldEventListenerAndRef(fieldsRef.current[fieldName], true);
|
1005
1033
|
}
|
1006
1034
|
}
|
@@ -1027,8 +1055,8 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1027
1055
|
let defaultValue;
|
1028
1056
|
if (field &&
|
1029
1057
|
(isRadioOrCheckbox
|
1030
|
-
? isArray(field.options) &&
|
1031
|
-
|
1058
|
+
? Array.isArray(field.options) &&
|
1059
|
+
compact(field.options).find((option) => {
|
1032
1060
|
return value === option.ref.value && compareRef(option.ref);
|
1033
1061
|
})
|
1034
1062
|
: compareRef(field.ref))) {
|
@@ -1038,7 +1066,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1038
1066
|
if (type) {
|
1039
1067
|
field = isRadioOrCheckbox
|
1040
1068
|
? Object.assign({ options: [
|
1041
|
-
...
|
1069
|
+
...compact((field && field.options) || []),
|
1042
1070
|
{
|
1043
1071
|
ref,
|
1044
1072
|
},
|
@@ -1108,16 +1136,14 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1108
1136
|
}
|
1109
1137
|
let fieldErrors = {};
|
1110
1138
|
let fieldValues = setFieldArrayDefaultValues(getFieldsValues(fieldsRef, shallowFieldsStateRef, true));
|
1111
|
-
|
1139
|
+
readFormStateRef.current.isSubmitting &&
|
1112
1140
|
updateFormState({
|
1113
1141
|
isSubmitting: true,
|
1114
1142
|
});
|
1115
|
-
}
|
1116
1143
|
try {
|
1117
1144
|
if (resolverRef.current) {
|
1118
1145
|
const { errors, values } = await resolverRef.current(fieldValues, contextRef.current, isValidateAllFieldCriteria);
|
1119
|
-
formStateRef.current.errors = errors;
|
1120
|
-
fieldErrors = errors;
|
1146
|
+
formStateRef.current.errors = fieldErrors = errors;
|
1121
1147
|
fieldValues = values;
|
1122
1148
|
}
|
1123
1149
|
else {
|
@@ -1186,7 +1212,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1186
1212
|
for (const field of Object.values(fieldsRef.current)) {
|
1187
1213
|
if (field) {
|
1188
1214
|
const { ref, options } = field;
|
1189
|
-
const inputRef = isRadioOrCheckboxFunction(ref) && isArray(options)
|
1215
|
+
const inputRef = isRadioOrCheckboxFunction(ref) && Array.isArray(options)
|
1190
1216
|
? options[0].ref
|
1191
1217
|
: ref;
|
1192
1218
|
if (isHTMLElement(inputRef)) {
|
@@ -1200,21 +1226,21 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1200
1226
|
}
|
1201
1227
|
}
|
1202
1228
|
fieldsRef.current = {};
|
1203
|
-
defaultValuesRef.current =
|
1204
|
-
|
1205
|
-
renderWatchedInputs('');
|
1206
|
-
}
|
1207
|
-
shallowFieldsStateRef.current = shouldUnregister ? {} : Object.assign({}, values) || {};
|
1229
|
+
defaultValuesRef.current = cloneObject(values || defaultValuesRef.current);
|
1230
|
+
values && renderWatchedInputs('');
|
1208
1231
|
Object.values(resetFieldArrayFunctionRef.current).forEach((resetFieldArray) => isFunction(resetFieldArray) && resetFieldArray());
|
1232
|
+
shallowFieldsStateRef.current = shouldUnregister
|
1233
|
+
? {}
|
1234
|
+
: cloneObject(values) || {};
|
1209
1235
|
resetRefs(omitResetState);
|
1210
1236
|
};
|
1211
|
-
observerRef.current =
|
1212
|
-
observerRef.current || !isWeb
|
1213
|
-
? observerRef.current
|
1214
|
-
: onDomRemove(fieldsRef, removeFieldEventListenerAndRef);
|
1215
1237
|
useEffect(() => {
|
1216
1238
|
isUnMount.current = false;
|
1217
1239
|
resolver && readFormStateRef.current.isValid && validateResolver();
|
1240
|
+
observerRef.current =
|
1241
|
+
observerRef.current || !isWeb
|
1242
|
+
? observerRef.current
|
1243
|
+
: onDomRemove(fieldsRef, removeFieldEventListenerAndRef);
|
1218
1244
|
return () => {
|
1219
1245
|
isUnMount.current = true;
|
1220
1246
|
observerRef.current && observerRef.current.disconnect();
|
@@ -1222,8 +1248,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1222
1248
|
if (process.env.NODE_ENV !== 'production') {
|
1223
1249
|
return;
|
1224
1250
|
}
|
1225
|
-
fieldsRef.current
|
1226
|
-
Object.values(fieldsRef.current).forEach((field) => removeFieldEventListenerAndRef(field, true));
|
1251
|
+
Object.values(fieldsRef.current).forEach((field) => removeFieldEventListenerAndRef(field, true));
|
1227
1252
|
};
|
1228
1253
|
}, [removeFieldEventListenerAndRef]);
|
1229
1254
|
if (!resolver && readFormStateRef.current.isValid) {
|
@@ -1238,15 +1263,13 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1238
1263
|
register: useCallback(register, [defaultValuesRef.current]),
|
1239
1264
|
unregister: useCallback(unregister, []),
|
1240
1265
|
};
|
1241
|
-
const control = Object.assign({
|
1266
|
+
const control = Object.assign({ updateWatchedValue,
|
1242
1267
|
shouldUnregister,
|
1243
1268
|
removeFieldEventListener,
|
1244
1269
|
watchInternal, mode: modeRef.current, reValidateMode: {
|
1245
1270
|
isReValidateOnBlur,
|
1246
1271
|
isReValidateOnChange,
|
1247
1272
|
}, fieldsRef,
|
1248
|
-
isWatchAllRef,
|
1249
|
-
watchFieldsRef,
|
1250
1273
|
resetFieldArrayFunctionRef,
|
1251
1274
|
useWatchFieldsRef,
|
1252
1275
|
useWatchRenderFunctionsRef,
|
@@ -1332,16 +1355,16 @@ function removeAtIndexes(data, index) {
|
|
1332
1355
|
delete data[k];
|
1333
1356
|
}
|
1334
1357
|
}
|
1335
|
-
return
|
1358
|
+
return compact(data);
|
1336
1359
|
}
|
1337
1360
|
var removeArrayAt = (data, index) => isUndefined(index)
|
1338
1361
|
? []
|
1339
|
-
: isArray(index)
|
1362
|
+
: Array.isArray(index)
|
1340
1363
|
? removeAtIndexes(data, index)
|
1341
1364
|
: removeAt(data, index);
|
1342
1365
|
|
1343
1366
|
var moveArrayAt = (data, from, to) => {
|
1344
|
-
if (isArray(data)) {
|
1367
|
+
if (Array.isArray(data)) {
|
1345
1368
|
if (isUndefined(data[to])) {
|
1346
1369
|
data[to] = undefined;
|
1347
1370
|
}
|
@@ -1358,18 +1381,18 @@ var swapArrayAt = (data, indexA, indexB) => {
|
|
1358
1381
|
};
|
1359
1382
|
|
1360
1383
|
function prepend(data, value) {
|
1361
|
-
return [...(isArray(value) ? value : [value || undefined]), ...data];
|
1384
|
+
return [...(Array.isArray(value) ? value : [value || undefined]), ...data];
|
1362
1385
|
}
|
1363
1386
|
|
1364
1387
|
function insert(data, index, value) {
|
1365
1388
|
return [
|
1366
1389
|
...data.slice(0, index),
|
1367
|
-
...(isArray(value) ? value : [value || undefined]),
|
1390
|
+
...(Array.isArray(value) ? value : [value || undefined]),
|
1368
1391
|
...data.slice(index),
|
1369
1392
|
];
|
1370
1393
|
}
|
1371
1394
|
|
1372
|
-
var fillEmptyArray = (value) => isArray(value) ? Array(value.length).fill(undefined) : undefined;
|
1395
|
+
var fillEmptyArray = (value) => Array.isArray(value) ? Array(value.length).fill(undefined) : undefined;
|
1373
1396
|
|
1374
1397
|
function mapValueToBoolean(value) {
|
1375
1398
|
if (isObject(value)) {
|
@@ -1381,10 +1404,11 @@ function mapValueToBoolean(value) {
|
|
1381
1404
|
}
|
1382
1405
|
return [true];
|
1383
1406
|
}
|
1384
|
-
var
|
1407
|
+
var fillBooleanArray = (value) => (Array.isArray(value) ? value : [value])
|
1408
|
+
.map(mapValueToBoolean)
|
1409
|
+
.flat();
|
1385
1410
|
|
1386
|
-
const
|
1387
|
-
const mapIds = (data, keyName) => (isArray(data) ? data : []).map((value) => appendId(value, keyName));
|
1411
|
+
const mapIds = (values, keyName) => values.map((value) => (Object.assign({ [keyName]: generateId() }, value)));
|
1388
1412
|
const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
1389
1413
|
const methods = useFormContext();
|
1390
1414
|
if (process.env.NODE_ENV !== 'production') {
|
@@ -1393,25 +1417,23 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1393
1417
|
}
|
1394
1418
|
}
|
1395
1419
|
const focusIndexRef = useRef(-1);
|
1396
|
-
const {
|
1420
|
+
const { updateWatchedValue, resetFieldArrayFunctionRef, fieldArrayNamesRef, fieldsRef, defaultValuesRef, removeFieldEventListener, formStateRef, shallowFieldsStateRef, updateFormState, readFormStateRef, validFieldsRef, fieldsWithValidationRef, fieldArrayDefaultValuesRef, validateResolver, getValues, shouldUnregister, } = control || methods.control;
|
1397
1421
|
const fieldArrayParentName = getFieldArrayParentName(name);
|
1398
|
-
const
|
1422
|
+
const memoizedDefaultValues = useRef([
|
1399
1423
|
...(get(fieldArrayDefaultValuesRef.current, fieldArrayParentName)
|
1400
1424
|
? get(fieldArrayDefaultValuesRef.current, name, [])
|
1401
1425
|
: get(shouldUnregister
|
1402
1426
|
? defaultValuesRef.current
|
1403
1427
|
: shallowFieldsStateRef.current, name, [])),
|
1404
|
-
];
|
1405
|
-
const memoizedDefaultValues = useRef(getDefaultValues());
|
1428
|
+
]);
|
1406
1429
|
const [fields, setFields] = useState(mapIds(memoizedDefaultValues.current, keyName));
|
1407
1430
|
const allFields = useRef(fields);
|
1408
|
-
const getCurrentFieldsValues = () => get(getValues()
|
1431
|
+
const getCurrentFieldsValues = () => get(getValues(), name, allFields.current).map((item, index) => (Object.assign(Object.assign({}, allFields.current[index]), item)));
|
1409
1432
|
allFields.current = fields;
|
1410
1433
|
fieldArrayNamesRef.current.add(name);
|
1411
1434
|
if (!get(fieldArrayDefaultValuesRef.current, fieldArrayParentName)) {
|
1412
1435
|
set(fieldArrayDefaultValuesRef.current, fieldArrayParentName, get(defaultValuesRef.current, fieldArrayParentName));
|
1413
1436
|
}
|
1414
|
-
const appendValueWithKey = (values) => values.map((value) => appendId(value, keyName));
|
1415
1437
|
const setFieldAndValidState = (fieldsValues) => {
|
1416
1438
|
setFields(fieldsValues);
|
1417
1439
|
if (readFormStateRef.current.isValid && validateResolver) {
|
@@ -1429,13 +1451,31 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1429
1451
|
}), get(defaultValuesRef.current, name)));
|
1430
1452
|
const resetFields = () => {
|
1431
1453
|
for (const key in fieldsRef.current) {
|
1432
|
-
|
1454
|
+
isMatchFieldArrayName(key, name) &&
|
1433
1455
|
removeFieldEventListener(fieldsRef.current[key], true);
|
1456
|
+
}
|
1457
|
+
};
|
1458
|
+
const cleanup = (ref) => !compact(get(ref, name, [])).length && unset(ref, name);
|
1459
|
+
const updateDirtyFieldsWithDefaultValues = (updatedFieldArrayValues) => {
|
1460
|
+
const defaultFieldArrayValues = get(defaultValuesRef.current, name, []);
|
1461
|
+
const updateDirtyFieldsBaseOnDefaultValues = (base, target) => {
|
1462
|
+
for (const key in base) {
|
1463
|
+
for (const innerKey in base[key]) {
|
1464
|
+
if (innerKey !== keyName &&
|
1465
|
+
(!target[key] ||
|
1466
|
+
!base[key] ||
|
1467
|
+
base[key][innerKey] !== target[key][innerKey])) {
|
1468
|
+
set(formStateRef.current.dirtyFields, `${name}[${key}]`, Object.assign(Object.assign({}, get(formStateRef.current.dirtyFields, `${name}[${key}]`, {})), { [innerKey]: true }));
|
1469
|
+
}
|
1470
|
+
}
|
1434
1471
|
}
|
1472
|
+
};
|
1473
|
+
if (updatedFieldArrayValues) {
|
1474
|
+
updateDirtyFieldsBaseOnDefaultValues(defaultFieldArrayValues, updatedFieldArrayValues);
|
1475
|
+
updateDirtyFieldsBaseOnDefaultValues(updatedFieldArrayValues, defaultFieldArrayValues);
|
1435
1476
|
}
|
1436
1477
|
};
|
1437
|
-
const
|
1438
|
-
const batchStateUpdate = (method, args, isDirty = true, shouldSet = true, shouldUpdateValid = false) => {
|
1478
|
+
const batchStateUpdate = (method, args, updatedFieldValues, isDirty = true, shouldSet = true, shouldUpdateValid = false) => {
|
1439
1479
|
if (get(shallowFieldsStateRef.current, name)) {
|
1440
1480
|
const output = method(get(shallowFieldsStateRef.current, name), args.argA, args.argB);
|
1441
1481
|
shouldSet && set(shallowFieldsStateRef.current, name, output);
|
@@ -1445,21 +1485,23 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1445
1485
|
shouldSet && set(fieldArrayDefaultValuesRef.current, name, output);
|
1446
1486
|
cleanup(fieldArrayDefaultValuesRef.current);
|
1447
1487
|
}
|
1448
|
-
if (isArray(get(formStateRef.current.errors, name))) {
|
1488
|
+
if (Array.isArray(get(formStateRef.current.errors, name))) {
|
1449
1489
|
const output = method(get(formStateRef.current.errors, name), args.argA, args.argB);
|
1450
1490
|
shouldSet && set(formStateRef.current.errors, name, output);
|
1451
1491
|
cleanup(formStateRef.current.errors);
|
1452
1492
|
}
|
1453
|
-
if (readFormStateRef.current.touched &&
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1493
|
+
if (readFormStateRef.current.touched &&
|
1494
|
+
get(formStateRef.current.touched, name)) {
|
1495
|
+
const output = method(get(formStateRef.current.touched, name), args.argA, args.argB);
|
1496
|
+
shouldSet && set(formStateRef.current.touched, name, output);
|
1497
|
+
cleanup(formStateRef.current.touched);
|
1457
1498
|
}
|
1458
1499
|
if (readFormStateRef.current.dirtyFields ||
|
1459
1500
|
readFormStateRef.current.isDirty) {
|
1460
|
-
const output = method(get(dirtyFields, name, []), args.argC, args.argD);
|
1461
|
-
shouldSet && set(dirtyFields, name, output);
|
1462
|
-
|
1501
|
+
const output = method(get(formStateRef.current.dirtyFields, name, []), args.argC, args.argD);
|
1502
|
+
shouldSet && set(formStateRef.current.dirtyFields, name, output);
|
1503
|
+
updateDirtyFieldsWithDefaultValues(updatedFieldValues);
|
1504
|
+
cleanup(formStateRef.current.dirtyFields);
|
1463
1505
|
}
|
1464
1506
|
if (shouldUpdateValid &&
|
1465
1507
|
readFormStateRef.current.isValid &&
|
@@ -1471,30 +1513,23 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1471
1513
|
}
|
1472
1514
|
updateFormState({
|
1473
1515
|
errors: formStateRef.current.errors,
|
1474
|
-
dirtyFields,
|
1516
|
+
dirtyFields: formStateRef.current.dirtyFields,
|
1475
1517
|
isDirty,
|
1476
|
-
touched,
|
1518
|
+
touched: formStateRef.current.touched,
|
1477
1519
|
});
|
1478
1520
|
};
|
1479
1521
|
const append = (value, shouldFocus = true) => {
|
1480
|
-
|
1522
|
+
const updateFormValues = [
|
1481
1523
|
...allFields.current,
|
1482
|
-
...(isArray(value)
|
1483
|
-
|
1484
|
-
|
1485
|
-
]);
|
1524
|
+
...mapIds(Array.isArray(value) ? value : [value], keyName),
|
1525
|
+
];
|
1526
|
+
setFieldAndValidState(updateFormValues);
|
1486
1527
|
if (readFormStateRef.current.dirtyFields ||
|
1487
1528
|
readFormStateRef.current.isDirty) {
|
1488
|
-
|
1489
|
-
set(dirtyFields, name, [
|
1490
|
-
...(allFields.current.length > dirtyInputs.length
|
1491
|
-
? (fillEmptyArray(allFields.current) || []).map((_, index) => dirtyInputs[index])
|
1492
|
-
: dirtyInputs),
|
1493
|
-
...filterBooleanArray(value),
|
1494
|
-
]);
|
1529
|
+
updateDirtyFieldsWithDefaultValues(updateFormValues);
|
1495
1530
|
updateFormState({
|
1496
1531
|
isDirty: true,
|
1497
|
-
dirtyFields,
|
1532
|
+
dirtyFields: formStateRef.current.dirtyFields,
|
1498
1533
|
});
|
1499
1534
|
}
|
1500
1535
|
if (!shouldUnregister) {
|
@@ -1507,34 +1542,37 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1507
1542
|
};
|
1508
1543
|
const prepend$1 = (value, shouldFocus = true) => {
|
1509
1544
|
const emptyArray = fillEmptyArray(value);
|
1510
|
-
|
1545
|
+
const updatedFieldArrayValues = prepend(getCurrentFieldsValues(), mapIds(Array.isArray(value) ? value : [value], keyName));
|
1546
|
+
setFieldAndValidState(updatedFieldArrayValues);
|
1511
1547
|
resetFields();
|
1512
1548
|
batchStateUpdate(prepend, {
|
1513
1549
|
argA: emptyArray,
|
1514
|
-
argC:
|
1515
|
-
});
|
1550
|
+
argC: fillBooleanArray(value),
|
1551
|
+
}, updatedFieldArrayValues);
|
1516
1552
|
focusIndexRef.current = shouldFocus ? 0 : -1;
|
1517
1553
|
};
|
1518
1554
|
const remove = (index) => {
|
1519
1555
|
const fieldValues = getCurrentFieldsValues();
|
1520
|
-
|
1556
|
+
const updatedFieldValues = removeArrayAt(fieldValues, index);
|
1557
|
+
setFieldAndValidState(updatedFieldValues);
|
1521
1558
|
resetFields();
|
1522
1559
|
batchStateUpdate(removeArrayAt, {
|
1523
1560
|
argA: index,
|
1524
1561
|
argC: index,
|
1525
|
-
}, getIsDirtyState(removeArrayAt(fieldValues, index)), true, true);
|
1562
|
+
}, updatedFieldValues, getIsDirtyState(removeArrayAt(fieldValues, index)), true, true);
|
1526
1563
|
};
|
1527
1564
|
const insert$1 = (index, value, shouldFocus = true) => {
|
1528
1565
|
const emptyArray = fillEmptyArray(value);
|
1529
1566
|
const fieldValues = getCurrentFieldsValues();
|
1530
|
-
|
1567
|
+
const updatedFieldArrayValues = insert(fieldValues, index, mapIds(Array.isArray(value) ? value : [value], keyName));
|
1568
|
+
setFieldAndValidState(updatedFieldArrayValues);
|
1531
1569
|
resetFields();
|
1532
1570
|
batchStateUpdate(insert, {
|
1533
1571
|
argA: index,
|
1534
1572
|
argB: emptyArray,
|
1535
1573
|
argC: index,
|
1536
|
-
argD:
|
1537
|
-
}, getIsDirtyState(insert(fieldValues, index)));
|
1574
|
+
argD: fillBooleanArray(value),
|
1575
|
+
}, updatedFieldArrayValues, getIsDirtyState(insert(fieldValues, index)));
|
1538
1576
|
focusIndexRef.current = shouldFocus ? index : -1;
|
1539
1577
|
};
|
1540
1578
|
const swap = (indexA, indexB) => {
|
@@ -1547,7 +1585,7 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1547
1585
|
argB: indexB,
|
1548
1586
|
argC: indexA,
|
1549
1587
|
argD: indexB,
|
1550
|
-
}, getIsDirtyState(fieldValues), false);
|
1588
|
+
}, undefined, getIsDirtyState(fieldValues), false);
|
1551
1589
|
};
|
1552
1590
|
const move = (from, to) => {
|
1553
1591
|
const fieldValues = getCurrentFieldsValues();
|
@@ -1559,7 +1597,7 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1559
1597
|
argB: to,
|
1560
1598
|
argC: from,
|
1561
1599
|
argD: to,
|
1562
|
-
}, getIsDirtyState(fieldValues), false);
|
1600
|
+
}, undefined, getIsDirtyState(fieldValues), false);
|
1563
1601
|
};
|
1564
1602
|
const reset = (data) => {
|
1565
1603
|
resetFields();
|
@@ -1579,20 +1617,7 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1579
1617
|
defaultValues.pop();
|
1580
1618
|
set(fieldArrayDefaultValuesRef.current, name, defaultValues);
|
1581
1619
|
}
|
1582
|
-
|
1583
|
-
updateFormState();
|
1584
|
-
}
|
1585
|
-
else if (watchFieldsRef) {
|
1586
|
-
let shouldRenderUseWatch = true;
|
1587
|
-
for (const watchField of watchFieldsRef.current) {
|
1588
|
-
if (watchField.startsWith(name)) {
|
1589
|
-
updateFormState();
|
1590
|
-
shouldRenderUseWatch = false;
|
1591
|
-
break;
|
1592
|
-
}
|
1593
|
-
}
|
1594
|
-
shouldRenderUseWatch && renderWatchedInputs(name);
|
1595
|
-
}
|
1620
|
+
updateWatchedValue(name);
|
1596
1621
|
if (focusIndexRef.current > -1) {
|
1597
1622
|
for (const key in fieldsRef.current) {
|
1598
1623
|
const field = fieldsRef.current[key];
|
@@ -1639,7 +1664,7 @@ function useWatch({ control, name, defaultValue, }) {
|
|
1639
1664
|
const [value, setValue] = useState(isUndefined(defaultValue)
|
1640
1665
|
? isString(name)
|
1641
1666
|
? get(defaultValuesRef.current, name)
|
1642
|
-
: isArray(name)
|
1667
|
+
: Array.isArray(name)
|
1643
1668
|
? name.reduce((previous, inputName) => (Object.assign(Object.assign({}, previous), { [inputName]: get(defaultValuesRef.current, inputName) })), {})
|
1644
1669
|
: defaultValuesRef.current
|
1645
1670
|
: defaultValue);
|
@@ -1647,7 +1672,10 @@ function useWatch({ control, name, defaultValue, }) {
|
|
1647
1672
|
const defaultValueRef = useRef(defaultValue);
|
1648
1673
|
const updateWatchValue = useCallback(() => {
|
1649
1674
|
const value = watchInternal(name, defaultValueRef.current, idRef.current);
|
1650
|
-
setValue(isObject(value)
|
1675
|
+
setValue(isObject(value)
|
1676
|
+
? Object.assign({}, value) : Array.isArray(value)
|
1677
|
+
? [...value]
|
1678
|
+
: value);
|
1651
1679
|
}, [setValue, watchInternal, defaultValueRef, name, idRef]);
|
1652
1680
|
useEffect(() => {
|
1653
1681
|
if (process.env.NODE_ENV !== 'production') {
|
@@ -1734,9 +1762,7 @@ const Controller = (_a) => {
|
|
1734
1762
|
}
|
1735
1763
|
}
|
1736
1764
|
}, [rules, name, register]);
|
1737
|
-
useEffect(() => () =>
|
1738
|
-
!isNameInFieldArray(fieldArrayNamesRef.current, name) && unregister(name);
|
1739
|
-
}, [unregister, name, fieldArrayNamesRef]);
|
1765
|
+
useEffect(() => () => unregister(name), [unregister, name]);
|
1740
1766
|
useEffect(() => {
|
1741
1767
|
if (process.env.NODE_ENV !== 'production') {
|
1742
1768
|
if (isUndefined(value)) {
|