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
@@ -40,27 +40,23 @@ function attachEventListeners({ ref }, shouldAttachChangeEvent, handleChange) {
|
|
40
40
|
|
41
41
|
var isNullOrUndefined = (value) => value == null;
|
42
42
|
|
43
|
-
var isArray = (value) => Array.isArray(value);
|
44
|
-
|
45
43
|
const isObjectType = (value) => typeof value === 'object';
|
46
44
|
var isObject = (value) => !isNullOrUndefined(value) &&
|
47
|
-
!isArray(value) &&
|
45
|
+
!Array.isArray(value) &&
|
48
46
|
isObjectType(value) &&
|
49
47
|
!(value instanceof Date);
|
50
48
|
|
51
|
-
var isKey = (value) => !isArray(value) &&
|
49
|
+
var isKey = (value) => !Array.isArray(value) &&
|
52
50
|
(/^\w*$/.test(value) ||
|
53
51
|
!/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/.test(value));
|
54
52
|
|
55
|
-
var
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
return result;
|
63
|
-
};
|
53
|
+
var compact = (value) => value.filter(Boolean);
|
54
|
+
|
55
|
+
var stringToPath = (input) => compact(input
|
56
|
+
.replace(/["|']/g, '')
|
57
|
+
.replace(/\[/g, '.')
|
58
|
+
.replace(/\]/g, '')
|
59
|
+
.split('.'));
|
64
60
|
|
65
61
|
function set(object, path, value) {
|
66
62
|
let index = -1;
|
@@ -73,7 +69,7 @@ function set(object, path, value) {
|
|
73
69
|
if (index !== lastIndex) {
|
74
70
|
const objValue = object[key];
|
75
71
|
newValue =
|
76
|
-
isObject(objValue) || isArray(objValue)
|
72
|
+
isObject(objValue) || Array.isArray(objValue)
|
77
73
|
? objValue
|
78
74
|
: !isNaN(+tempPath[index + 1])
|
79
75
|
? []
|
@@ -85,20 +81,17 @@ function set(object, path, value) {
|
|
85
81
|
return object;
|
86
82
|
}
|
87
83
|
|
88
|
-
var transformToNestObject = (data
|
89
|
-
|
90
|
-
set(
|
91
|
-
return previous;
|
84
|
+
var transformToNestObject = (data, value = {}) => {
|
85
|
+
for (const key in data) {
|
86
|
+
!isKey(key) ? set(value, key, data[key]) : (value[key] = data[key]);
|
92
87
|
}
|
93
|
-
return
|
94
|
-
}
|
88
|
+
return value;
|
89
|
+
};
|
95
90
|
|
96
91
|
var isUndefined = (val) => val === undefined;
|
97
92
|
|
98
|
-
var filterOutFalsy = (value) => value.filter(Boolean);
|
99
|
-
|
100
93
|
var get = (obj, path, defaultValue) => {
|
101
|
-
const result =
|
94
|
+
const result = compact(path.split(/[,[\].]+?/)).reduce((result, key) => (isNullOrUndefined(result) ? result : result[key]), obj);
|
102
95
|
return isUndefined(result) || result === obj
|
103
96
|
? isUndefined(obj[path])
|
104
97
|
? defaultValue
|
@@ -136,7 +129,7 @@ const defaultReturn = {
|
|
136
129
|
isValid: false,
|
137
130
|
value: '',
|
138
131
|
};
|
139
|
-
var getRadioValue = (options) => isArray(options)
|
132
|
+
var getRadioValue = (options) => Array.isArray(options)
|
140
133
|
? options.reduce((previous, option) => option && option.ref.checked
|
141
134
|
? {
|
142
135
|
isValid: true,
|
@@ -163,7 +156,7 @@ const defaultResult = {
|
|
163
156
|
};
|
164
157
|
const validResult = { value: true, isValid: true };
|
165
158
|
var getCheckboxValue = (options) => {
|
166
|
-
if (isArray(options)) {
|
159
|
+
if (Array.isArray(options)) {
|
167
160
|
if (options.length > 1) {
|
168
161
|
const values = options
|
169
162
|
.filter((option) => option && option.ref.checked)
|
@@ -253,7 +246,7 @@ function unset(object, path) {
|
|
253
246
|
objectRef = objectRef ? objectRef[item] : object[item];
|
254
247
|
if (currentPathsLength === index &&
|
255
248
|
((isObject(objectRef) && isEmptyObject(objectRef)) ||
|
256
|
-
(isArray(objectRef) &&
|
249
|
+
(Array.isArray(objectRef) &&
|
257
250
|
!objectRef.filter((data) => (isObject(data) && !isEmptyObject(data)) || isBoolean(data)).length))) {
|
258
251
|
previousObjRef ? delete previousObjRef[item] : delete object[item];
|
259
252
|
}
|
@@ -279,15 +272,15 @@ function findRemovedFieldAndRemoveListener(fieldsRef, handleChange, field, shall
|
|
279
272
|
}
|
280
273
|
if ((isRadioInput(ref) || isCheckBoxInput(ref)) && fieldRef) {
|
281
274
|
const { options } = fieldRef;
|
282
|
-
if (isArray(options) && options.length) {
|
283
|
-
|
275
|
+
if (Array.isArray(options) && options.length) {
|
276
|
+
compact(options).forEach((option, index) => {
|
284
277
|
const { ref } = option;
|
285
278
|
if ((ref && isDetached(ref) && isSameRef(option, ref)) || forceDelete) {
|
286
279
|
removeAllEventListeners(ref, handleChange);
|
287
280
|
unset(options, `[${index}]`);
|
288
281
|
}
|
289
282
|
});
|
290
|
-
if (options && !
|
283
|
+
if (options && !compact(options).length) {
|
291
284
|
delete fieldsRef.current[name];
|
292
285
|
}
|
293
286
|
}
|
@@ -305,7 +298,7 @@ function setFieldArrayDirtyFields(values, defaultValues, dirtyFields, parentNode
|
|
305
298
|
let index = -1;
|
306
299
|
while (++index < values.length) {
|
307
300
|
for (const key in values[index]) {
|
308
|
-
if (isArray(values[index][key])) {
|
301
|
+
if (Array.isArray(values[index][key])) {
|
309
302
|
!dirtyFields[index] && (dirtyFields[index] = {});
|
310
303
|
dirtyFields[index][key] = [];
|
311
304
|
setFieldArrayDirtyFields(values[index][key], get(defaultValues[index] || {}, key, []), dirtyFields[index][key], dirtyFields[index], key);
|
@@ -335,13 +328,11 @@ function deepMerge(target, source) {
|
|
335
328
|
const targetValue = target[key];
|
336
329
|
const sourceValue = source[key];
|
337
330
|
try {
|
338
|
-
|
339
|
-
(
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
target[key] = sourceValue;
|
344
|
-
}
|
331
|
+
target[key] =
|
332
|
+
(isObject(targetValue) && isObject(sourceValue)) ||
|
333
|
+
(Array.isArray(targetValue) && Array.isArray(sourceValue))
|
334
|
+
? deepMerge(targetValue, sourceValue)
|
335
|
+
: sourceValue;
|
345
336
|
}
|
346
337
|
catch (_a) { }
|
347
338
|
}
|
@@ -354,7 +345,7 @@ var getFieldsValues = (fieldsRef, shallowFieldsStateRef, excludeDisabled, search
|
|
354
345
|
if (isUndefined(search) ||
|
355
346
|
(isString(search)
|
356
347
|
? name.startsWith(search)
|
357
|
-
: isArray(search) && search.find((data) => name.startsWith(data)))) {
|
348
|
+
: Array.isArray(search) && search.find((data) => name.startsWith(data)))) {
|
358
349
|
output[name] = getFieldValue(fieldsRef, name, undefined, excludeDisabled);
|
359
350
|
}
|
360
351
|
}
|
@@ -371,7 +362,8 @@ function deepEqual(object1 = [], object2 = [], isErrorObject) {
|
|
371
362
|
if (!(isErrorObject && ['ref', 'context'].includes(key))) {
|
372
363
|
const val1 = object1[key];
|
373
364
|
const val2 = object2[key];
|
374
|
-
if ((isObject(val1) || isArray(val1)) &&
|
365
|
+
if ((isObject(val1) || Array.isArray(val1)) &&
|
366
|
+
(isObject(val2) || Array.isArray(val2))
|
375
367
|
? !deepEqual(val1, val2, isErrorObject)
|
376
368
|
: val1 !== val2) {
|
377
369
|
return false;
|
@@ -563,7 +555,7 @@ var assignWatchFields = (fieldValues, fieldName, watchFields, inputValue, isSing
|
|
563
555
|
}
|
564
556
|
else {
|
565
557
|
value = get(fieldValues, fieldName);
|
566
|
-
if (isObject(value) || isArray(value)) {
|
558
|
+
if (isObject(value) || Array.isArray(value)) {
|
567
559
|
getPath(fieldName, value).forEach((name) => watchFields.add(name));
|
568
560
|
}
|
569
561
|
}
|
@@ -619,6 +611,22 @@ function onDomRemove(fieldsRef, removeFieldEventListenerAndRef) {
|
|
619
611
|
return observer;
|
620
612
|
}
|
621
613
|
|
614
|
+
function cloneObject(object) {
|
615
|
+
let copy;
|
616
|
+
if (isPrimitive(object)) {
|
617
|
+
return object;
|
618
|
+
}
|
619
|
+
if (object instanceof Date) {
|
620
|
+
copy = new Date(object.getTime());
|
621
|
+
return copy;
|
622
|
+
}
|
623
|
+
copy = Array.isArray(object) ? [] : {};
|
624
|
+
for (const key in object) {
|
625
|
+
copy[key] = cloneObject(object[key]);
|
626
|
+
}
|
627
|
+
return copy;
|
628
|
+
}
|
629
|
+
|
622
630
|
var modeChecker = (mode) => ({
|
623
631
|
isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
|
624
632
|
isOnBlur: mode === VALIDATION_MODE.onBlur,
|
@@ -647,7 +655,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
647
655
|
const isUnMount = React.useRef(false);
|
648
656
|
const isWatchAllRef = React.useRef(false);
|
649
657
|
const handleChangeRef = React.useRef();
|
650
|
-
const shallowFieldsStateRef = React.useRef(shouldUnregister ? {} :
|
658
|
+
const shallowFieldsStateRef = React.useRef(shouldUnregister ? {} : cloneObject(defaultValues));
|
651
659
|
const resetFieldArrayFunctionRef = React.useRef({});
|
652
660
|
const contextRef = React.useRef(context);
|
653
661
|
const resolverRef = React.useRef(resolver);
|
@@ -727,7 +735,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
727
735
|
}
|
728
736
|
else if (isCheckBoxInput(ref) && options) {
|
729
737
|
options.length > 1
|
730
|
-
? options.forEach(({ ref: checkboxRef }) => (checkboxRef.checked = isArray(value)
|
738
|
+
? options.forEach(({ ref: checkboxRef }) => (checkboxRef.checked = Array.isArray(value)
|
731
739
|
? !!value.find((data) => data === checkboxRef.value)
|
732
740
|
: value === checkboxRef.value))
|
733
741
|
: (options[0].ref.checked = !!value);
|
@@ -738,7 +746,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
738
746
|
}, []);
|
739
747
|
const isFormDirty = () => !deepEqual(getValues(), isEmptyObject(defaultValuesRef.current)
|
740
748
|
? defaultValuesAtRenderRef.current
|
741
|
-
: defaultValuesRef.current)
|
749
|
+
: defaultValuesRef.current);
|
742
750
|
const updateAndGetDirtyState = React.useCallback((name, shouldRender = true) => {
|
743
751
|
if (readFormStateRef.current.isDirty ||
|
744
752
|
readFormStateRef.current.dirtyFields) {
|
@@ -776,7 +784,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
776
784
|
const executeSchemaOrResolverValidation = React.useCallback(async (names) => {
|
777
785
|
const { errors } = await resolverRef.current(getValues(), contextRef.current, isValidateAllFieldCriteria);
|
778
786
|
const previousFormIsValid = formStateRef.current.isValid;
|
779
|
-
if (isArray(names)) {
|
787
|
+
if (Array.isArray(names)) {
|
780
788
|
const isInputsValid = names
|
781
789
|
.map((name) => {
|
782
790
|
const error = get(errors, name);
|
@@ -803,7 +811,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
803
811
|
if (resolverRef.current) {
|
804
812
|
return executeSchemaOrResolverValidation(fields);
|
805
813
|
}
|
806
|
-
if (isArray(fields)) {
|
814
|
+
if (Array.isArray(fields)) {
|
807
815
|
const result = await Promise.all(fields.map(async (data) => await executeValidation(data, null)));
|
808
816
|
updateFormState();
|
809
817
|
return result.every(Boolean);
|
@@ -833,8 +841,9 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
833
841
|
resetFieldArrayFunctionRef.current[name]({
|
834
842
|
[name]: value,
|
835
843
|
});
|
836
|
-
if (readFormStateRef.current.isDirty ||
|
837
|
-
readFormStateRef.current.dirtyFields)
|
844
|
+
if ((readFormStateRef.current.isDirty ||
|
845
|
+
readFormStateRef.current.dirtyFields) &&
|
846
|
+
config.shouldDirty) {
|
838
847
|
set(formStateRef.current.dirtyFields, name, setFieldArrayDirtyFields(value, get(defaultValuesRef.current, name, []), get(formStateRef.current.dirtyFields, name, [])));
|
839
848
|
updateFormState({
|
840
849
|
isDirty: !deepEqual(Object.assign(Object.assign({}, getValues()), { [name]: value }), defaultValuesRef.current),
|
@@ -912,11 +921,13 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
912
921
|
};
|
913
922
|
function setFieldArrayDefaultValues(data) {
|
914
923
|
if (!shouldUnregister) {
|
924
|
+
let copy = cloneObject(data);
|
915
925
|
for (const value of fieldArrayNamesRef.current) {
|
916
|
-
if (isKey(value) && !
|
917
|
-
|
926
|
+
if (isKey(value) && !copy[value]) {
|
927
|
+
copy = Object.assign(Object.assign({}, copy), { [value]: [] });
|
918
928
|
}
|
919
929
|
}
|
930
|
+
return copy;
|
920
931
|
}
|
921
932
|
return data;
|
922
933
|
}
|
@@ -924,7 +935,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
924
935
|
if (isString(payload)) {
|
925
936
|
return getFieldValue(fieldsRef, payload, shallowFieldsStateRef);
|
926
937
|
}
|
927
|
-
if (isArray(payload)) {
|
938
|
+
if (Array.isArray(payload)) {
|
928
939
|
const data = {};
|
929
940
|
for (const name of payload) {
|
930
941
|
set(data, name, getFieldValue(fieldsRef, name, shallowFieldsStateRef));
|
@@ -942,10 +953,26 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
942
953
|
});
|
943
954
|
}, [isValidateAllFieldCriteria]);
|
944
955
|
const removeFieldEventListener = React.useCallback((field, forceDelete) => findRemovedFieldAndRemoveListener(fieldsRef, handleChangeRef.current, field, shallowFieldsStateRef, shouldUnregister, forceDelete), [shouldUnregister]);
|
956
|
+
const updateWatchedValue = (name) => {
|
957
|
+
if (isWatchAllRef.current) {
|
958
|
+
updateFormState();
|
959
|
+
}
|
960
|
+
else if (watchFieldsRef) {
|
961
|
+
let shouldRenderUseWatch = true;
|
962
|
+
for (const watchField of watchFieldsRef.current) {
|
963
|
+
if (watchField.startsWith(name)) {
|
964
|
+
updateFormState();
|
965
|
+
shouldRenderUseWatch = false;
|
966
|
+
break;
|
967
|
+
}
|
968
|
+
}
|
969
|
+
shouldRenderUseWatch && renderWatchedInputs(name);
|
970
|
+
}
|
971
|
+
};
|
945
972
|
const removeFieldEventListenerAndRef = React.useCallback((field, forceDelete) => {
|
946
973
|
if (field) {
|
947
974
|
removeFieldEventListener(field, forceDelete);
|
948
|
-
if (shouldUnregister && !
|
975
|
+
if (shouldUnregister && !compact(field.options || []).length) {
|
949
976
|
unset(defaultValuesAtRenderRef.current, field.ref.name);
|
950
977
|
unset(validFieldsRef.current, field.ref.name);
|
951
978
|
unset(fieldsWithValidationRef.current, field.ref.name);
|
@@ -957,12 +984,13 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
957
984
|
dirtyFields: formStateRef.current.dirtyFields,
|
958
985
|
});
|
959
986
|
resolverRef.current && validateResolver();
|
987
|
+
updateWatchedValue(field.ref.name);
|
960
988
|
}
|
961
989
|
}
|
962
990
|
}, [validateResolver, removeFieldEventListener]);
|
963
991
|
function clearErrors(name) {
|
964
992
|
name &&
|
965
|
-
(isArray(name) ? name : [name]).forEach((inputName) => fieldsRef.current[inputName]
|
993
|
+
(Array.isArray(name) ? name : [name]).forEach((inputName) => fieldsRef.current[inputName]
|
966
994
|
? isKey(inputName)
|
967
995
|
? delete formStateRef.current.errors[inputName]
|
968
996
|
: set(formStateRef.current.errors, inputName, undefined)
|
@@ -993,7 +1021,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
993
1021
|
? get(combinedDefaultValues, fieldNames)
|
994
1022
|
: defaultValue, true);
|
995
1023
|
}
|
996
|
-
if (isArray(fieldNames)) {
|
1024
|
+
if (Array.isArray(fieldNames)) {
|
997
1025
|
return fieldNames.reduce((previous, name) => (Object.assign(Object.assign({}, previous), { [name]: assignWatchFields(fieldValues, name, watchFields, combinedDefaultValues) })), {});
|
998
1026
|
}
|
999
1027
|
isWatchAllRef.current = isUndefined(watchId);
|
@@ -1004,7 +1032,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1004
1032
|
return watchInternal(fieldNames, defaultValue);
|
1005
1033
|
}
|
1006
1034
|
function unregister(name) {
|
1007
|
-
for (const fieldName of isArray(name) ? name : [name]) {
|
1035
|
+
for (const fieldName of Array.isArray(name) ? name : [name]) {
|
1008
1036
|
removeFieldEventListenerAndRef(fieldsRef.current[fieldName], true);
|
1009
1037
|
}
|
1010
1038
|
}
|
@@ -1031,8 +1059,8 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1031
1059
|
let defaultValue;
|
1032
1060
|
if (field &&
|
1033
1061
|
(isRadioOrCheckbox
|
1034
|
-
? isArray(field.options) &&
|
1035
|
-
|
1062
|
+
? Array.isArray(field.options) &&
|
1063
|
+
compact(field.options).find((option) => {
|
1036
1064
|
return value === option.ref.value && compareRef(option.ref);
|
1037
1065
|
})
|
1038
1066
|
: compareRef(field.ref))) {
|
@@ -1042,7 +1070,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1042
1070
|
if (type) {
|
1043
1071
|
field = isRadioOrCheckbox
|
1044
1072
|
? Object.assign({ options: [
|
1045
|
-
...
|
1073
|
+
...compact((field && field.options) || []),
|
1046
1074
|
{
|
1047
1075
|
ref,
|
1048
1076
|
},
|
@@ -1112,16 +1140,14 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1112
1140
|
}
|
1113
1141
|
let fieldErrors = {};
|
1114
1142
|
let fieldValues = setFieldArrayDefaultValues(getFieldsValues(fieldsRef, shallowFieldsStateRef, true));
|
1115
|
-
|
1143
|
+
readFormStateRef.current.isSubmitting &&
|
1116
1144
|
updateFormState({
|
1117
1145
|
isSubmitting: true,
|
1118
1146
|
});
|
1119
|
-
}
|
1120
1147
|
try {
|
1121
1148
|
if (resolverRef.current) {
|
1122
1149
|
const { errors, values } = await resolverRef.current(fieldValues, contextRef.current, isValidateAllFieldCriteria);
|
1123
|
-
formStateRef.current.errors = errors;
|
1124
|
-
fieldErrors = errors;
|
1150
|
+
formStateRef.current.errors = fieldErrors = errors;
|
1125
1151
|
fieldValues = values;
|
1126
1152
|
}
|
1127
1153
|
else {
|
@@ -1190,7 +1216,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1190
1216
|
for (const field of Object.values(fieldsRef.current)) {
|
1191
1217
|
if (field) {
|
1192
1218
|
const { ref, options } = field;
|
1193
|
-
const inputRef = isRadioOrCheckboxFunction(ref) && isArray(options)
|
1219
|
+
const inputRef = isRadioOrCheckboxFunction(ref) && Array.isArray(options)
|
1194
1220
|
? options[0].ref
|
1195
1221
|
: ref;
|
1196
1222
|
if (isHTMLElement(inputRef)) {
|
@@ -1204,21 +1230,21 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1204
1230
|
}
|
1205
1231
|
}
|
1206
1232
|
fieldsRef.current = {};
|
1207
|
-
defaultValuesRef.current =
|
1208
|
-
|
1209
|
-
renderWatchedInputs('');
|
1210
|
-
}
|
1211
|
-
shallowFieldsStateRef.current = shouldUnregister ? {} : Object.assign({}, values) || {};
|
1233
|
+
defaultValuesRef.current = cloneObject(values || defaultValuesRef.current);
|
1234
|
+
values && renderWatchedInputs('');
|
1212
1235
|
Object.values(resetFieldArrayFunctionRef.current).forEach((resetFieldArray) => isFunction(resetFieldArray) && resetFieldArray());
|
1236
|
+
shallowFieldsStateRef.current = shouldUnregister
|
1237
|
+
? {}
|
1238
|
+
: cloneObject(values) || {};
|
1213
1239
|
resetRefs(omitResetState);
|
1214
1240
|
};
|
1215
|
-
observerRef.current =
|
1216
|
-
observerRef.current || !isWeb
|
1217
|
-
? observerRef.current
|
1218
|
-
: onDomRemove(fieldsRef, removeFieldEventListenerAndRef);
|
1219
1241
|
React.useEffect(() => {
|
1220
1242
|
isUnMount.current = false;
|
1221
1243
|
resolver && readFormStateRef.current.isValid && validateResolver();
|
1244
|
+
observerRef.current =
|
1245
|
+
observerRef.current || !isWeb
|
1246
|
+
? observerRef.current
|
1247
|
+
: onDomRemove(fieldsRef, removeFieldEventListenerAndRef);
|
1222
1248
|
return () => {
|
1223
1249
|
isUnMount.current = true;
|
1224
1250
|
observerRef.current && observerRef.current.disconnect();
|
@@ -1240,15 +1266,13 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
|
|
1240
1266
|
register: React.useCallback(register, [defaultValuesRef.current]),
|
1241
1267
|
unregister: React.useCallback(unregister, []),
|
1242
1268
|
};
|
1243
|
-
const control = Object.assign({
|
1269
|
+
const control = Object.assign({ updateWatchedValue,
|
1244
1270
|
shouldUnregister,
|
1245
1271
|
removeFieldEventListener,
|
1246
1272
|
watchInternal, mode: modeRef.current, reValidateMode: {
|
1247
1273
|
isReValidateOnBlur,
|
1248
1274
|
isReValidateOnChange,
|
1249
1275
|
}, fieldsRef,
|
1250
|
-
isWatchAllRef,
|
1251
|
-
watchFieldsRef,
|
1252
1276
|
resetFieldArrayFunctionRef,
|
1253
1277
|
useWatchFieldsRef,
|
1254
1278
|
useWatchRenderFunctionsRef,
|
@@ -1334,16 +1358,16 @@ function removeAtIndexes(data, index) {
|
|
1334
1358
|
delete data[k];
|
1335
1359
|
}
|
1336
1360
|
}
|
1337
|
-
return
|
1361
|
+
return compact(data);
|
1338
1362
|
}
|
1339
1363
|
var removeArrayAt = (data, index) => isUndefined(index)
|
1340
1364
|
? []
|
1341
|
-
: isArray(index)
|
1365
|
+
: Array.isArray(index)
|
1342
1366
|
? removeAtIndexes(data, index)
|
1343
1367
|
: removeAt(data, index);
|
1344
1368
|
|
1345
1369
|
var moveArrayAt = (data, from, to) => {
|
1346
|
-
if (isArray(data)) {
|
1370
|
+
if (Array.isArray(data)) {
|
1347
1371
|
if (isUndefined(data[to])) {
|
1348
1372
|
data[to] = undefined;
|
1349
1373
|
}
|
@@ -1360,18 +1384,18 @@ var swapArrayAt = (data, indexA, indexB) => {
|
|
1360
1384
|
};
|
1361
1385
|
|
1362
1386
|
function prepend(data, value) {
|
1363
|
-
return [...(isArray(value) ? value : [value || undefined]), ...data];
|
1387
|
+
return [...(Array.isArray(value) ? value : [value || undefined]), ...data];
|
1364
1388
|
}
|
1365
1389
|
|
1366
1390
|
function insert(data, index, value) {
|
1367
1391
|
return [
|
1368
1392
|
...data.slice(0, index),
|
1369
|
-
...(isArray(value) ? value : [value || undefined]),
|
1393
|
+
...(Array.isArray(value) ? value : [value || undefined]),
|
1370
1394
|
...data.slice(index),
|
1371
1395
|
];
|
1372
1396
|
}
|
1373
1397
|
|
1374
|
-
var fillEmptyArray = (value) => isArray(value) ? Array(value.length).fill(undefined) : undefined;
|
1398
|
+
var fillEmptyArray = (value) => Array.isArray(value) ? Array(value.length).fill(undefined) : undefined;
|
1375
1399
|
|
1376
1400
|
function mapValueToBoolean(value) {
|
1377
1401
|
if (isObject(value)) {
|
@@ -1383,10 +1407,11 @@ function mapValueToBoolean(value) {
|
|
1383
1407
|
}
|
1384
1408
|
return [true];
|
1385
1409
|
}
|
1386
|
-
var
|
1410
|
+
var fillBooleanArray = (value) => (Array.isArray(value) ? value : [value])
|
1411
|
+
.map(mapValueToBoolean)
|
1412
|
+
.flat();
|
1387
1413
|
|
1388
|
-
const
|
1389
|
-
const mapIds = (data, keyName) => (isArray(data) ? data : []).map((value) => appendId(value, keyName));
|
1414
|
+
const mapIds = (values, keyName) => values.map((value) => (Object.assign({ [keyName]: generateId() }, value)));
|
1390
1415
|
const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
1391
1416
|
const methods = useFormContext();
|
1392
1417
|
{
|
@@ -1395,25 +1420,23 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1395
1420
|
}
|
1396
1421
|
}
|
1397
1422
|
const focusIndexRef = React.useRef(-1);
|
1398
|
-
const {
|
1423
|
+
const { updateWatchedValue, resetFieldArrayFunctionRef, fieldArrayNamesRef, fieldsRef, defaultValuesRef, removeFieldEventListener, formStateRef, shallowFieldsStateRef, updateFormState, readFormStateRef, validFieldsRef, fieldsWithValidationRef, fieldArrayDefaultValuesRef, validateResolver, getValues, shouldUnregister, } = control || methods.control;
|
1399
1424
|
const fieldArrayParentName = getFieldArrayParentName(name);
|
1400
|
-
const
|
1425
|
+
const memoizedDefaultValues = React.useRef([
|
1401
1426
|
...(get(fieldArrayDefaultValuesRef.current, fieldArrayParentName)
|
1402
1427
|
? get(fieldArrayDefaultValuesRef.current, name, [])
|
1403
1428
|
: get(shouldUnregister
|
1404
1429
|
? defaultValuesRef.current
|
1405
1430
|
: shallowFieldsStateRef.current, name, [])),
|
1406
|
-
];
|
1407
|
-
const memoizedDefaultValues = React.useRef(getDefaultValues());
|
1431
|
+
]);
|
1408
1432
|
const [fields, setFields] = React.useState(mapIds(memoizedDefaultValues.current, keyName));
|
1409
1433
|
const allFields = React.useRef(fields);
|
1410
|
-
const getCurrentFieldsValues = () => get(getValues()
|
1434
|
+
const getCurrentFieldsValues = () => get(getValues(), name, allFields.current).map((item, index) => (Object.assign(Object.assign({}, allFields.current[index]), item)));
|
1411
1435
|
allFields.current = fields;
|
1412
1436
|
fieldArrayNamesRef.current.add(name);
|
1413
1437
|
if (!get(fieldArrayDefaultValuesRef.current, fieldArrayParentName)) {
|
1414
1438
|
set(fieldArrayDefaultValuesRef.current, fieldArrayParentName, get(defaultValuesRef.current, fieldArrayParentName));
|
1415
1439
|
}
|
1416
|
-
const appendValueWithKey = (values) => values.map((value) => appendId(value, keyName));
|
1417
1440
|
const setFieldAndValidState = (fieldsValues) => {
|
1418
1441
|
setFields(fieldsValues);
|
1419
1442
|
if (readFormStateRef.current.isValid && validateResolver) {
|
@@ -1431,13 +1454,31 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1431
1454
|
}), get(defaultValuesRef.current, name)));
|
1432
1455
|
const resetFields = () => {
|
1433
1456
|
for (const key in fieldsRef.current) {
|
1434
|
-
|
1457
|
+
isMatchFieldArrayName(key, name) &&
|
1435
1458
|
removeFieldEventListener(fieldsRef.current[key], true);
|
1459
|
+
}
|
1460
|
+
};
|
1461
|
+
const cleanup = (ref) => !compact(get(ref, name, [])).length && unset(ref, name);
|
1462
|
+
const updateDirtyFieldsWithDefaultValues = (updatedFieldArrayValues) => {
|
1463
|
+
const defaultFieldArrayValues = get(defaultValuesRef.current, name, []);
|
1464
|
+
const updateDirtyFieldsBaseOnDefaultValues = (base, target) => {
|
1465
|
+
for (const key in base) {
|
1466
|
+
for (const innerKey in base[key]) {
|
1467
|
+
if (innerKey !== keyName &&
|
1468
|
+
(!target[key] ||
|
1469
|
+
!base[key] ||
|
1470
|
+
base[key][innerKey] !== target[key][innerKey])) {
|
1471
|
+
set(formStateRef.current.dirtyFields, `${name}[${key}]`, Object.assign(Object.assign({}, get(formStateRef.current.dirtyFields, `${name}[${key}]`, {})), { [innerKey]: true }));
|
1472
|
+
}
|
1473
|
+
}
|
1436
1474
|
}
|
1475
|
+
};
|
1476
|
+
if (updatedFieldArrayValues) {
|
1477
|
+
updateDirtyFieldsBaseOnDefaultValues(defaultFieldArrayValues, updatedFieldArrayValues);
|
1478
|
+
updateDirtyFieldsBaseOnDefaultValues(updatedFieldArrayValues, defaultFieldArrayValues);
|
1437
1479
|
}
|
1438
1480
|
};
|
1439
|
-
const
|
1440
|
-
const batchStateUpdate = (method, args, isDirty = true, shouldSet = true, shouldUpdateValid = false) => {
|
1481
|
+
const batchStateUpdate = (method, args, updatedFieldValues, isDirty = true, shouldSet = true, shouldUpdateValid = false) => {
|
1441
1482
|
if (get(shallowFieldsStateRef.current, name)) {
|
1442
1483
|
const output = method(get(shallowFieldsStateRef.current, name), args.argA, args.argB);
|
1443
1484
|
shouldSet && set(shallowFieldsStateRef.current, name, output);
|
@@ -1447,21 +1488,23 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1447
1488
|
shouldSet && set(fieldArrayDefaultValuesRef.current, name, output);
|
1448
1489
|
cleanup(fieldArrayDefaultValuesRef.current);
|
1449
1490
|
}
|
1450
|
-
if (isArray(get(formStateRef.current.errors, name))) {
|
1491
|
+
if (Array.isArray(get(formStateRef.current.errors, name))) {
|
1451
1492
|
const output = method(get(formStateRef.current.errors, name), args.argA, args.argB);
|
1452
1493
|
shouldSet && set(formStateRef.current.errors, name, output);
|
1453
1494
|
cleanup(formStateRef.current.errors);
|
1454
1495
|
}
|
1455
|
-
if (readFormStateRef.current.touched &&
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1496
|
+
if (readFormStateRef.current.touched &&
|
1497
|
+
get(formStateRef.current.touched, name)) {
|
1498
|
+
const output = method(get(formStateRef.current.touched, name), args.argA, args.argB);
|
1499
|
+
shouldSet && set(formStateRef.current.touched, name, output);
|
1500
|
+
cleanup(formStateRef.current.touched);
|
1459
1501
|
}
|
1460
1502
|
if (readFormStateRef.current.dirtyFields ||
|
1461
1503
|
readFormStateRef.current.isDirty) {
|
1462
|
-
const output = method(get(dirtyFields, name, []), args.argC, args.argD);
|
1463
|
-
shouldSet && set(dirtyFields, name, output);
|
1464
|
-
|
1504
|
+
const output = method(get(formStateRef.current.dirtyFields, name, []), args.argC, args.argD);
|
1505
|
+
shouldSet && set(formStateRef.current.dirtyFields, name, output);
|
1506
|
+
updateDirtyFieldsWithDefaultValues(updatedFieldValues);
|
1507
|
+
cleanup(formStateRef.current.dirtyFields);
|
1465
1508
|
}
|
1466
1509
|
if (shouldUpdateValid &&
|
1467
1510
|
readFormStateRef.current.isValid &&
|
@@ -1473,30 +1516,23 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1473
1516
|
}
|
1474
1517
|
updateFormState({
|
1475
1518
|
errors: formStateRef.current.errors,
|
1476
|
-
dirtyFields,
|
1519
|
+
dirtyFields: formStateRef.current.dirtyFields,
|
1477
1520
|
isDirty,
|
1478
|
-
touched,
|
1521
|
+
touched: formStateRef.current.touched,
|
1479
1522
|
});
|
1480
1523
|
};
|
1481
1524
|
const append = (value, shouldFocus = true) => {
|
1482
|
-
|
1525
|
+
const updateFormValues = [
|
1483
1526
|
...allFields.current,
|
1484
|
-
...(isArray(value)
|
1485
|
-
|
1486
|
-
|
1487
|
-
]);
|
1527
|
+
...mapIds(Array.isArray(value) ? value : [value], keyName),
|
1528
|
+
];
|
1529
|
+
setFieldAndValidState(updateFormValues);
|
1488
1530
|
if (readFormStateRef.current.dirtyFields ||
|
1489
1531
|
readFormStateRef.current.isDirty) {
|
1490
|
-
|
1491
|
-
set(dirtyFields, name, [
|
1492
|
-
...(allFields.current.length > dirtyInputs.length
|
1493
|
-
? (fillEmptyArray(allFields.current) || []).map((_, index) => dirtyInputs[index])
|
1494
|
-
: dirtyInputs),
|
1495
|
-
...filterBooleanArray(value),
|
1496
|
-
]);
|
1532
|
+
updateDirtyFieldsWithDefaultValues(updateFormValues);
|
1497
1533
|
updateFormState({
|
1498
1534
|
isDirty: true,
|
1499
|
-
dirtyFields,
|
1535
|
+
dirtyFields: formStateRef.current.dirtyFields,
|
1500
1536
|
});
|
1501
1537
|
}
|
1502
1538
|
if (!shouldUnregister) {
|
@@ -1509,34 +1545,37 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1509
1545
|
};
|
1510
1546
|
const prepend$1 = (value, shouldFocus = true) => {
|
1511
1547
|
const emptyArray = fillEmptyArray(value);
|
1512
|
-
|
1548
|
+
const updatedFieldArrayValues = prepend(getCurrentFieldsValues(), mapIds(Array.isArray(value) ? value : [value], keyName));
|
1549
|
+
setFieldAndValidState(updatedFieldArrayValues);
|
1513
1550
|
resetFields();
|
1514
1551
|
batchStateUpdate(prepend, {
|
1515
1552
|
argA: emptyArray,
|
1516
|
-
argC:
|
1517
|
-
});
|
1553
|
+
argC: fillBooleanArray(value),
|
1554
|
+
}, updatedFieldArrayValues);
|
1518
1555
|
focusIndexRef.current = shouldFocus ? 0 : -1;
|
1519
1556
|
};
|
1520
1557
|
const remove = (index) => {
|
1521
1558
|
const fieldValues = getCurrentFieldsValues();
|
1522
|
-
|
1559
|
+
const updatedFieldValues = removeArrayAt(fieldValues, index);
|
1560
|
+
setFieldAndValidState(updatedFieldValues);
|
1523
1561
|
resetFields();
|
1524
1562
|
batchStateUpdate(removeArrayAt, {
|
1525
1563
|
argA: index,
|
1526
1564
|
argC: index,
|
1527
|
-
}, getIsDirtyState(removeArrayAt(fieldValues, index)), true, true);
|
1565
|
+
}, updatedFieldValues, getIsDirtyState(removeArrayAt(fieldValues, index)), true, true);
|
1528
1566
|
};
|
1529
1567
|
const insert$1 = (index, value, shouldFocus = true) => {
|
1530
1568
|
const emptyArray = fillEmptyArray(value);
|
1531
1569
|
const fieldValues = getCurrentFieldsValues();
|
1532
|
-
|
1570
|
+
const updatedFieldArrayValues = insert(fieldValues, index, mapIds(Array.isArray(value) ? value : [value], keyName));
|
1571
|
+
setFieldAndValidState(updatedFieldArrayValues);
|
1533
1572
|
resetFields();
|
1534
1573
|
batchStateUpdate(insert, {
|
1535
1574
|
argA: index,
|
1536
1575
|
argB: emptyArray,
|
1537
1576
|
argC: index,
|
1538
|
-
argD:
|
1539
|
-
}, getIsDirtyState(insert(fieldValues, index)));
|
1577
|
+
argD: fillBooleanArray(value),
|
1578
|
+
}, updatedFieldArrayValues, getIsDirtyState(insert(fieldValues, index)));
|
1540
1579
|
focusIndexRef.current = shouldFocus ? index : -1;
|
1541
1580
|
};
|
1542
1581
|
const swap = (indexA, indexB) => {
|
@@ -1549,7 +1588,7 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1549
1588
|
argB: indexB,
|
1550
1589
|
argC: indexA,
|
1551
1590
|
argD: indexB,
|
1552
|
-
}, getIsDirtyState(fieldValues), false);
|
1591
|
+
}, undefined, getIsDirtyState(fieldValues), false);
|
1553
1592
|
};
|
1554
1593
|
const move = (from, to) => {
|
1555
1594
|
const fieldValues = getCurrentFieldsValues();
|
@@ -1561,7 +1600,7 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1561
1600
|
argB: to,
|
1562
1601
|
argC: from,
|
1563
1602
|
argD: to,
|
1564
|
-
}, getIsDirtyState(fieldValues), false);
|
1603
|
+
}, undefined, getIsDirtyState(fieldValues), false);
|
1565
1604
|
};
|
1566
1605
|
const reset = (data) => {
|
1567
1606
|
resetFields();
|
@@ -1581,20 +1620,7 @@ const useFieldArray = ({ control, name, keyName = 'id', }) => {
|
|
1581
1620
|
defaultValues.pop();
|
1582
1621
|
set(fieldArrayDefaultValuesRef.current, name, defaultValues);
|
1583
1622
|
}
|
1584
|
-
|
1585
|
-
updateFormState();
|
1586
|
-
}
|
1587
|
-
else if (watchFieldsRef) {
|
1588
|
-
let shouldRenderUseWatch = true;
|
1589
|
-
for (const watchField of watchFieldsRef.current) {
|
1590
|
-
if (watchField.startsWith(name)) {
|
1591
|
-
updateFormState();
|
1592
|
-
shouldRenderUseWatch = false;
|
1593
|
-
break;
|
1594
|
-
}
|
1595
|
-
}
|
1596
|
-
shouldRenderUseWatch && renderWatchedInputs(name);
|
1597
|
-
}
|
1623
|
+
updateWatchedValue(name);
|
1598
1624
|
if (focusIndexRef.current > -1) {
|
1599
1625
|
for (const key in fieldsRef.current) {
|
1600
1626
|
const field = fieldsRef.current[key];
|
@@ -1641,7 +1667,7 @@ function useWatch({ control, name, defaultValue, }) {
|
|
1641
1667
|
const [value, setValue] = React.useState(isUndefined(defaultValue)
|
1642
1668
|
? isString(name)
|
1643
1669
|
? get(defaultValuesRef.current, name)
|
1644
|
-
: isArray(name)
|
1670
|
+
: Array.isArray(name)
|
1645
1671
|
? name.reduce((previous, inputName) => (Object.assign(Object.assign({}, previous), { [inputName]: get(defaultValuesRef.current, inputName) })), {})
|
1646
1672
|
: defaultValuesRef.current
|
1647
1673
|
: defaultValue);
|
@@ -1649,7 +1675,10 @@ function useWatch({ control, name, defaultValue, }) {
|
|
1649
1675
|
const defaultValueRef = React.useRef(defaultValue);
|
1650
1676
|
const updateWatchValue = React.useCallback(() => {
|
1651
1677
|
const value = watchInternal(name, defaultValueRef.current, idRef.current);
|
1652
|
-
setValue(isObject(value)
|
1678
|
+
setValue(isObject(value)
|
1679
|
+
? Object.assign({}, value) : Array.isArray(value)
|
1680
|
+
? [...value]
|
1681
|
+
: value);
|
1653
1682
|
}, [setValue, watchInternal, defaultValueRef, name, idRef]);
|
1654
1683
|
React.useEffect(() => {
|
1655
1684
|
{
|
@@ -1736,9 +1765,7 @@ const Controller = (_a) => {
|
|
1736
1765
|
}
|
1737
1766
|
}
|
1738
1767
|
}, [rules, name, register]);
|
1739
|
-
React.useEffect(() => () =>
|
1740
|
-
!isNameInFieldArray(fieldArrayNamesRef.current, name) && unregister(name);
|
1741
|
-
}, [unregister, name, fieldArrayNamesRef]);
|
1768
|
+
React.useEffect(() => () => unregister(name), [unregister, name]);
|
1742
1769
|
React.useEffect(() => {
|
1743
1770
|
{
|
1744
1771
|
if (isUndefined(value)) {
|