react-hook-form 7.22.5 → 7.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +193 -181
- package/dist/index.esm.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/types/fieldArray.d.ts +1 -1
- package/dist/types/fieldArray.d.ts.map +1 -1
- package/dist/types/form.d.ts +6 -5
- package/dist/types/form.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/path/common.d.ts +316 -0
- package/dist/types/path/common.d.ts.map +1 -0
- package/dist/types/path/eager.d.ts +82 -0
- package/dist/types/path/eager.d.ts.map +1 -0
- package/dist/types/path/index.d.ts +4 -0
- package/dist/types/path/index.d.ts.map +1 -0
- package/dist/types/utils.d.ts +19 -25
- package/dist/types/utils.d.ts.map +1 -1
- package/dist/types/validator.d.ts +1 -1
- package/dist/types/validator.d.ts.map +1 -1
- package/dist/useController.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useForm.d.ts.map +1 -1
- package/dist/useFormState.d.ts.map +1 -1
- package/dist/utils/compact.d.ts +1 -1
- package/dist/utils/compact.d.ts.map +1 -1
- package/dist/utils/get.d.ts.map +1 -1
- package/dist/utils/isDateObject.d.ts +1 -1
- package/dist/utils/isDateObject.d.ts.map +1 -1
- package/dist/utils/live.d.ts.map +1 -1
- package/dist/utils/move.d.ts.map +1 -1
- package/dist/utils/update.d.ts +1 -1
- package/dist/utils/update.d.ts.map +1 -1
- package/package.json +11 -11
- package/dist/logic/mapCurrentIds.d.ts +0 -6
- package/dist/logic/mapCurrentIds.d.ts.map +0 -1
- package/dist/logic/mapId.d.ts +0 -4
- package/dist/logic/mapId.d.ts.map +0 -1
package/dist/index.esm.mjs
CHANGED
@@ -2,7 +2,7 @@ import React from 'react';
|
|
2
2
|
|
3
3
|
var isCheckBoxInput = (element) => element.type === 'checkbox';
|
4
4
|
|
5
|
-
var isDateObject = (
|
5
|
+
var isDateObject = (value) => value instanceof Date;
|
6
6
|
|
7
7
|
var isNullOrUndefined = (value) => value == null;
|
8
8
|
|
@@ -22,20 +22,20 @@ var getNodeParentName = (name) => name.substring(0, name.search(/.\d/)) || name;
|
|
22
22
|
|
23
23
|
var isNameInFieldArray = (names, name) => [...names].some((current) => getNodeParentName(name) === current);
|
24
24
|
|
25
|
-
var compact = (value) =>
|
25
|
+
var compact = (value) => value.filter(Boolean);
|
26
26
|
|
27
27
|
var isUndefined = (val) => val === undefined;
|
28
28
|
|
29
29
|
var get = (obj, path, defaultValue) => {
|
30
|
-
if (isObject(obj)
|
31
|
-
|
32
|
-
return isUndefined(result) || result === obj
|
33
|
-
? isUndefined(obj[path])
|
34
|
-
? defaultValue
|
35
|
-
: obj[path]
|
36
|
-
: result;
|
30
|
+
if (!path || !isObject(obj)) {
|
31
|
+
return defaultValue;
|
37
32
|
}
|
38
|
-
|
33
|
+
const result = compact(path.split(/[,[\].]+?/)).reduce((result, key) => isNullOrUndefined(result) ? result : result[key], obj);
|
34
|
+
return isUndefined(result) || result === obj
|
35
|
+
? isUndefined(obj[path])
|
36
|
+
? defaultValue
|
37
|
+
: obj[path]
|
38
|
+
: result;
|
39
39
|
};
|
40
40
|
|
41
41
|
const EVENTS = {
|
@@ -142,14 +142,20 @@ function useFormState(props) {
|
|
142
142
|
errors: false,
|
143
143
|
});
|
144
144
|
const _name = React.useRef(name);
|
145
|
+
const _mounted = React.useRef(true);
|
145
146
|
_name.current = name;
|
147
|
+
const callback = React.useCallback((value) => _mounted.current &&
|
148
|
+
shouldSubscribeByName(_name.current, value.name, exact) &&
|
149
|
+
shouldRenderFormState(value, _localProxyFormState.current) &&
|
150
|
+
updateFormState(Object.assign(Object.assign({}, control._formState), value)), [control, exact]);
|
146
151
|
useSubscribe({
|
147
152
|
disabled,
|
148
|
-
callback
|
149
|
-
shouldRenderFormState(value, _localProxyFormState.current) &&
|
150
|
-
updateFormState(Object.assign(Object.assign({}, control._formState), value)),
|
153
|
+
callback,
|
151
154
|
subject: control._subjects.state,
|
152
155
|
});
|
156
|
+
React.useEffect(() => () => {
|
157
|
+
_mounted.current = false;
|
158
|
+
}, []);
|
153
159
|
return getProxyFormState(formState, control._proxyFormState, _localProxyFormState.current, false);
|
154
160
|
}
|
155
161
|
|
@@ -185,21 +191,22 @@ function useWatch(props) {
|
|
185
191
|
const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
|
186
192
|
const _name = React.useRef(name);
|
187
193
|
_name.current = name;
|
194
|
+
const callback = React.useCallback((formState) => {
|
195
|
+
if (shouldSubscribeByName(_name.current, formState.name, exact)) {
|
196
|
+
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
197
|
+
updateValue(isUndefined(_name.current) ||
|
198
|
+
(isObject(fieldValues) && !objectHasFunction(fieldValues))
|
199
|
+
? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
|
200
|
+
? [...fieldValues]
|
201
|
+
: isUndefined(fieldValues)
|
202
|
+
? defaultValue
|
203
|
+
: fieldValues);
|
204
|
+
}
|
205
|
+
}, [control, exact, defaultValue]);
|
188
206
|
useSubscribe({
|
189
207
|
disabled,
|
190
208
|
subject: control._subjects.watch,
|
191
|
-
callback
|
192
|
-
if (shouldSubscribeByName(_name.current, formState.name, exact)) {
|
193
|
-
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
194
|
-
updateValue(isUndefined(_name.current) ||
|
195
|
-
(isObject(fieldValues) && !objectHasFunction(fieldValues))
|
196
|
-
? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
|
197
|
-
? [...fieldValues]
|
198
|
-
: isUndefined(fieldValues)
|
199
|
-
? defaultValue
|
200
|
-
: fieldValues);
|
201
|
-
}
|
202
|
-
},
|
209
|
+
callback,
|
203
210
|
});
|
204
211
|
const [value, updateValue] = React.useState(isUndefined(defaultValue)
|
205
212
|
? control._getWatch(name)
|
@@ -224,9 +231,7 @@ function useController(props) {
|
|
224
231
|
control,
|
225
232
|
name,
|
226
233
|
});
|
227
|
-
const
|
228
|
-
_name.current = name;
|
229
|
-
const registerProps = control.register(name, Object.assign(Object.assign({}, props.rules), { value }));
|
234
|
+
const _registerProps = React.useRef(control.register(name, Object.assign(Object.assign({}, props.rules), { value })));
|
230
235
|
React.useEffect(() => {
|
231
236
|
const updateMounted = (name, value) => {
|
232
237
|
const field = get(control._fields, name);
|
@@ -246,27 +251,27 @@ function useController(props) {
|
|
246
251
|
}, [name, control, isArrayField, shouldUnregister]);
|
247
252
|
return {
|
248
253
|
field: {
|
249
|
-
|
250
|
-
|
254
|
+
name,
|
255
|
+
value,
|
256
|
+
onChange: React.useCallback((event) => {
|
257
|
+
_registerProps.current.onChange({
|
251
258
|
target: {
|
252
259
|
value: getEventValue(event),
|
253
260
|
name: name,
|
254
261
|
},
|
255
262
|
type: EVENTS.CHANGE,
|
256
263
|
});
|
257
|
-
},
|
258
|
-
onBlur: () => {
|
259
|
-
|
264
|
+
}, [name]),
|
265
|
+
onBlur: React.useCallback(() => {
|
266
|
+
_registerProps.current.onBlur({
|
260
267
|
target: {
|
261
268
|
value: get(control._formValues, name),
|
262
269
|
name: name,
|
263
270
|
},
|
264
271
|
type: EVENTS.BLUR,
|
265
272
|
});
|
266
|
-
},
|
267
|
-
|
268
|
-
value,
|
269
|
-
ref: (elm) => {
|
273
|
+
}, [name, control]),
|
274
|
+
ref: React.useCallback((elm) => {
|
270
275
|
const field = get(control._fields, name);
|
271
276
|
if (elm && field && elm.focus) {
|
272
277
|
field._f.ref = {
|
@@ -275,7 +280,7 @@ function useController(props) {
|
|
275
280
|
reportValidity: () => elm.reportValidity(),
|
276
281
|
};
|
277
282
|
}
|
278
|
-
},
|
283
|
+
}, [name, control]),
|
279
284
|
},
|
280
285
|
formState,
|
281
286
|
fieldState: {
|
@@ -341,6 +346,14 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
|
|
341
346
|
}
|
342
347
|
};
|
343
348
|
|
349
|
+
var generateId = () => {
|
350
|
+
const d = typeof performance === 'undefined' ? Date.now() : performance.now() * 1000;
|
351
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
352
|
+
const r = (Math.random() * 16 + d) % 16 | 0;
|
353
|
+
return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
|
354
|
+
});
|
355
|
+
};
|
356
|
+
|
344
357
|
var getFocusFieldName = (name, index, options = {}) => options.shouldFocus || isUndefined(options.shouldFocus)
|
345
358
|
? options.focusName ||
|
346
359
|
`${name}.${isUndefined(options.focusIndex) ? index : options.focusIndex}.`
|
@@ -352,23 +365,8 @@ var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
|
|
352
365
|
[..._names.watch].some((watchName) => name.startsWith(watchName) &&
|
353
366
|
/^\.\w+/.test(name.slice(watchName.length))));
|
354
367
|
|
355
|
-
var mapCurrentIds = (values, _fieldIds, keyName) => values.map((value, index) => {
|
356
|
-
const output = _fieldIds.current[index];
|
357
|
-
return Object.assign(Object.assign({}, value), (output ? { [keyName]: output[keyName] } : {}));
|
358
|
-
});
|
359
|
-
|
360
|
-
var generateId = () => {
|
361
|
-
const d = typeof performance === 'undefined' ? Date.now() : performance.now() * 1000;
|
362
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
363
|
-
const r = (Math.random() * 16 + d) % 16 | 0;
|
364
|
-
return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
|
365
|
-
});
|
366
|
-
};
|
367
|
-
|
368
|
-
var mapIds = (values = [], keyName) => values.map((value) => (Object.assign(Object.assign({}, (value[keyName] ? {} : { [keyName]: generateId() })), value)));
|
369
|
-
|
370
368
|
function append(data, value) {
|
371
|
-
return [...
|
369
|
+
return [...data, ...convertToArrayPayload(value)];
|
372
370
|
}
|
373
371
|
|
374
372
|
function cloneObject(data) {
|
@@ -407,18 +405,16 @@ function insert(data, index, value) {
|
|
407
405
|
}
|
408
406
|
|
409
407
|
var moveArrayAt = (data, from, to) => {
|
410
|
-
if (Array.isArray(data)) {
|
411
|
-
|
412
|
-
data[to] = undefined;
|
413
|
-
}
|
414
|
-
data.splice(to, 0, data.splice(from, 1)[0]);
|
415
|
-
return data;
|
408
|
+
if (!Array.isArray(data)) {
|
409
|
+
return [];
|
416
410
|
}
|
417
|
-
|
411
|
+
if (isUndefined(data[to])) {
|
412
|
+
data[to] = undefined;
|
413
|
+
}
|
414
|
+
data.splice(to, 0, data.splice(from, 1)[0]);
|
415
|
+
return data;
|
418
416
|
};
|
419
417
|
|
420
|
-
var omitKeys = (fields, keyName) => fields.map((field = {}) => omit(field, keyName));
|
421
|
-
|
422
418
|
function prepend(data, value) {
|
423
419
|
return [...convertToArrayPayload(value), ...convertToArrayPayload(data)];
|
424
420
|
}
|
@@ -448,100 +444,110 @@ var updateAt = (fieldValues, index, value) => {
|
|
448
444
|
const useFieldArray = (props) => {
|
449
445
|
const methods = useFormContext();
|
450
446
|
const { control = methods.control, name, keyName = 'id', shouldUnregister, } = props;
|
451
|
-
const [fields, setFields] = React.useState(
|
447
|
+
const [fields, setFields] = React.useState(control._getFieldArray(name));
|
448
|
+
const ids = React.useRef(control._getFieldArray(name).map(generateId));
|
452
449
|
const _fieldIds = React.useRef(fields);
|
453
450
|
const _name = React.useRef(name);
|
454
451
|
const _actioned = React.useRef(false);
|
455
452
|
_name.current = name;
|
456
453
|
_fieldIds.current = fields;
|
457
454
|
control._names.array.add(name);
|
455
|
+
const callback = React.useCallback(({ values, name: fieldArrayName }) => {
|
456
|
+
if (fieldArrayName === _name.current || !fieldArrayName) {
|
457
|
+
const fieldValues = get(values, _name.current, []);
|
458
|
+
setFields(fieldValues);
|
459
|
+
ids.current = fieldValues.map(generateId);
|
460
|
+
}
|
461
|
+
}, []);
|
458
462
|
useSubscribe({
|
459
|
-
callback
|
460
|
-
if (fieldArrayName === _name.current || !fieldArrayName) {
|
461
|
-
setFields(mapIds(get(values, _name.current), keyName));
|
462
|
-
}
|
463
|
-
},
|
463
|
+
callback,
|
464
464
|
subject: control._subjects.array,
|
465
465
|
});
|
466
|
-
const updateValues = React.useCallback((
|
467
|
-
const updatedFieldArrayValues = omitKeys(updatedFieldArrayValuesWithKey, keyName);
|
466
|
+
const updateValues = React.useCallback((updatedFieldArrayValues) => {
|
468
467
|
_actioned.current = true;
|
469
468
|
set(control._formValues, name, updatedFieldArrayValues);
|
470
|
-
|
471
|
-
}, [control, name, keyName]);
|
469
|
+
}, [control, name]);
|
472
470
|
const append$1 = (value, options) => {
|
473
471
|
const appendValue = convertToArrayPayload(cloneObject(value));
|
474
|
-
const
|
475
|
-
|
476
|
-
|
477
|
-
setFields(
|
472
|
+
const updatedFieldArrayValues = append(control._getFieldArray(name), appendValue);
|
473
|
+
control._names.focus = getFocusFieldName(name, updatedFieldArrayValues.length - 1, options);
|
474
|
+
ids.current = append(ids.current, appendValue.map(generateId));
|
475
|
+
setFields(updatedFieldArrayValues);
|
476
|
+
updateValues(updatedFieldArrayValues);
|
478
477
|
control._updateFieldArray(name, append, {
|
479
478
|
argA: fillEmptyArray(value),
|
480
|
-
},
|
479
|
+
}, updatedFieldArrayValues);
|
481
480
|
};
|
482
481
|
const prepend$1 = (value, options) => {
|
483
|
-
const
|
484
|
-
const
|
482
|
+
const prependValue = convertToArrayPayload(cloneObject(value));
|
483
|
+
const updatedFieldArrayValues = prepend(control._getFieldArray(name), prependValue);
|
485
484
|
control._names.focus = getFocusFieldName(name, 0, options);
|
486
|
-
|
485
|
+
ids.current = prepend(ids.current, prependValue.map(generateId));
|
486
|
+
setFields(updatedFieldArrayValues);
|
487
|
+
updateValues(updatedFieldArrayValues);
|
487
488
|
control._updateFieldArray(name, prepend, {
|
488
489
|
argA: fillEmptyArray(value),
|
489
|
-
},
|
490
|
+
}, updatedFieldArrayValues);
|
490
491
|
};
|
491
492
|
const remove = (index) => {
|
492
|
-
const
|
493
|
-
|
494
|
-
setFields(
|
493
|
+
const updatedFieldArrayValues = removeArrayAt(control._getFieldArray(name), index);
|
494
|
+
ids.current = removeArrayAt(ids.current, index);
|
495
|
+
setFields(updatedFieldArrayValues);
|
496
|
+
updateValues(updatedFieldArrayValues);
|
495
497
|
control._updateFieldArray(name, removeArrayAt, {
|
496
498
|
argA: index,
|
497
|
-
},
|
499
|
+
}, updatedFieldArrayValues);
|
498
500
|
};
|
499
501
|
const insert$1 = (index, value, options) => {
|
500
|
-
const
|
501
|
-
const
|
502
|
+
const insertValue = convertToArrayPayload(cloneObject(value));
|
503
|
+
const updatedFieldArrayValues = insert(control._getFieldArray(name), index, insertValue);
|
504
|
+
updateValues(updatedFieldArrayValues);
|
502
505
|
control._names.focus = getFocusFieldName(name, index, options);
|
503
|
-
|
506
|
+
ids.current = insert(ids.current, index, insertValue.map(generateId));
|
507
|
+
setFields(updatedFieldArrayValues);
|
504
508
|
control._updateFieldArray(name, insert, {
|
505
509
|
argA: index,
|
506
510
|
argB: fillEmptyArray(value),
|
507
|
-
},
|
511
|
+
}, updatedFieldArrayValues);
|
508
512
|
};
|
509
513
|
const swap = (indexA, indexB) => {
|
510
|
-
const
|
511
|
-
swapArrayAt(
|
512
|
-
|
513
|
-
setFields(
|
514
|
+
const updatedFieldArrayValues = control._getFieldArray(name);
|
515
|
+
swapArrayAt(updatedFieldArrayValues, indexA, indexB);
|
516
|
+
swapArrayAt(ids.current, indexA, indexB);
|
517
|
+
setFields(updatedFieldArrayValues);
|
518
|
+
updateValues(updatedFieldArrayValues);
|
514
519
|
control._updateFieldArray(name, swapArrayAt, {
|
515
520
|
argA: indexA,
|
516
521
|
argB: indexB,
|
517
|
-
},
|
522
|
+
}, updatedFieldArrayValues, false);
|
518
523
|
};
|
519
524
|
const move = (from, to) => {
|
520
|
-
const
|
521
|
-
moveArrayAt(
|
522
|
-
|
523
|
-
setFields(
|
525
|
+
const updatedFieldArrayValues = control._getFieldArray(name);
|
526
|
+
moveArrayAt(updatedFieldArrayValues, from, to);
|
527
|
+
moveArrayAt(ids.current, from, to);
|
528
|
+
setFields(updatedFieldArrayValues);
|
529
|
+
updateValues(updatedFieldArrayValues);
|
524
530
|
control._updateFieldArray(name, moveArrayAt, {
|
525
531
|
argA: from,
|
526
532
|
argB: to,
|
527
|
-
},
|
533
|
+
}, updatedFieldArrayValues, false);
|
528
534
|
};
|
529
535
|
const update = (index, value) => {
|
530
|
-
const
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
setFields(_fieldIds.current);
|
536
|
+
const updatedFieldArrayValues = updateAt(control._getFieldArray(name), index, value);
|
537
|
+
ids.current = [...updatedFieldArrayValues].map((item, i) => !item || i === index ? generateId() : ids.current[i]);
|
538
|
+
setFields([...updatedFieldArrayValues]);
|
539
|
+
updateValues(updatedFieldArrayValues);
|
535
540
|
control._updateFieldArray(name, updateAt, {
|
536
541
|
argA: index,
|
537
542
|
argB: value,
|
538
|
-
},
|
543
|
+
}, updatedFieldArrayValues, true, false);
|
539
544
|
};
|
540
545
|
const replace = (value) => {
|
541
|
-
const
|
542
|
-
|
543
|
-
|
544
|
-
|
546
|
+
const updatedFieldArrayValues = convertToArrayPayload(value);
|
547
|
+
ids.current = updatedFieldArrayValues.map(generateId);
|
548
|
+
updateValues([...updatedFieldArrayValues]);
|
549
|
+
setFields([...updatedFieldArrayValues]);
|
550
|
+
control._updateFieldArray(name, () => updatedFieldArrayValues, {}, [...updatedFieldArrayValues], true, false);
|
545
551
|
};
|
546
552
|
React.useEffect(() => {
|
547
553
|
control._stateFlags.action = false;
|
@@ -565,25 +571,24 @@ const useFieldArray = (props) => {
|
|
565
571
|
focusFieldBy(control._fields, (key) => key.startsWith(control._names.focus));
|
566
572
|
control._names.focus = '';
|
567
573
|
control._proxyFormState.isValid && control._updateValid();
|
568
|
-
}, [fields, name, control
|
574
|
+
}, [fields, name, control]);
|
569
575
|
React.useEffect(() => {
|
570
576
|
!get(control._formValues, name) && set(control._formValues, name, []);
|
571
577
|
return () => {
|
572
|
-
|
578
|
+
(control._options.shouldUnregister || shouldUnregister) &&
|
573
579
|
control.unregister(name);
|
574
|
-
}
|
575
580
|
};
|
576
581
|
}, [name, control, keyName, shouldUnregister]);
|
577
582
|
return {
|
578
|
-
swap: React.useCallback(swap, [updateValues, name, control
|
579
|
-
move: React.useCallback(move, [updateValues, name, control
|
580
|
-
prepend: React.useCallback(prepend$1, [updateValues, name, control
|
581
|
-
append: React.useCallback(append$1, [updateValues, name, control
|
582
|
-
remove: React.useCallback(remove, [updateValues, name, control
|
583
|
-
insert: React.useCallback(insert$1, [updateValues, name, control
|
584
|
-
update: React.useCallback(update, [updateValues, name, control
|
585
|
-
replace: React.useCallback(replace, [updateValues, name, control
|
586
|
-
fields: fields,
|
583
|
+
swap: React.useCallback(swap, [updateValues, name, control]),
|
584
|
+
move: React.useCallback(move, [updateValues, name, control]),
|
585
|
+
prepend: React.useCallback(prepend$1, [updateValues, name, control]),
|
586
|
+
append: React.useCallback(append$1, [updateValues, name, control]),
|
587
|
+
remove: React.useCallback(remove, [updateValues, name, control]),
|
588
|
+
insert: React.useCallback(insert$1, [updateValues, name, control]),
|
589
|
+
update: React.useCallback(update, [updateValues, name, control]),
|
590
|
+
replace: React.useCallback(replace, [updateValues, name, control]),
|
591
|
+
fields: React.useMemo(() => fields.map((field, index) => (Object.assign(Object.assign({}, field), { [keyName]: ids.current[index] || generateId() }))), [fields, keyName]),
|
587
592
|
};
|
588
593
|
};
|
589
594
|
|
@@ -672,7 +677,7 @@ var isWeb = typeof window !== 'undefined' &&
|
|
672
677
|
typeof window.HTMLElement !== 'undefined' &&
|
673
678
|
typeof document !== 'undefined';
|
674
679
|
|
675
|
-
var live = (ref) => isHTMLElement(ref) &&
|
680
|
+
var live = (ref) => isHTMLElement(ref) && ref.isConnected;
|
676
681
|
|
677
682
|
function baseGet(object, updatePath) {
|
678
683
|
const length = updatePath.slice(0, -1).length;
|
@@ -1138,24 +1143,25 @@ function createFormControl(props = {}) {
|
|
1138
1143
|
}
|
1139
1144
|
return isValid;
|
1140
1145
|
};
|
1141
|
-
const _updateFieldArray = (name, method, args, values = [], shouldSetValues = true, shouldSetFields = true
|
1146
|
+
const _updateFieldArray = (name, method, args, values = [], shouldSetValues = true, shouldSetFields = true) => {
|
1142
1147
|
_stateFlags.action = true;
|
1143
|
-
if (shouldSetFields && get(_fields, name)) {
|
1148
|
+
if (shouldSetFields && Array.isArray(get(_fields, name))) {
|
1144
1149
|
const fieldValues = method(get(_fields, name), args.argA, args.argB);
|
1145
1150
|
shouldSetValues && set(_fields, name, fieldValues);
|
1146
1151
|
}
|
1147
|
-
if (
|
1152
|
+
if (_proxyFormState.errors &&
|
1153
|
+
shouldSetFields &&
|
1154
|
+
Array.isArray(get(_formState.errors, name))) {
|
1148
1155
|
const errors = method(get(_formState.errors, name), args.argA, args.argB);
|
1149
1156
|
shouldSetValues && set(_formState.errors, name, errors);
|
1150
1157
|
unsetEmptyArray(_formState.errors, name);
|
1151
1158
|
}
|
1152
|
-
if (_proxyFormState.touchedFields &&
|
1159
|
+
if (_proxyFormState.touchedFields &&
|
1160
|
+
Array.isArray(get(_formState.touchedFields, name))) {
|
1153
1161
|
const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
|
1154
|
-
shouldSetValues &&
|
1155
|
-
set(_formState.touchedFields, name, touchedFields);
|
1156
|
-
unsetEmptyArray(_formState.touchedFields, name);
|
1162
|
+
shouldSetValues && set(_formState.touchedFields, name, touchedFields);
|
1157
1163
|
}
|
1158
|
-
if (_proxyFormState.dirtyFields
|
1164
|
+
if (_proxyFormState.dirtyFields) {
|
1159
1165
|
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
1160
1166
|
}
|
1161
1167
|
_subjects.state.next({
|
@@ -1169,19 +1175,19 @@ function createFormControl(props = {}) {
|
|
1169
1175
|
_subjects.state.next({
|
1170
1176
|
errors: _formState.errors,
|
1171
1177
|
}));
|
1172
|
-
const updateValidAndValue = (name, shouldSkipSetValueAs, ref) => {
|
1178
|
+
const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
|
1173
1179
|
const field = get(_fields, name);
|
1174
1180
|
if (field) {
|
1175
|
-
const defaultValue = get(_formValues, name, get(_defaultValues, name));
|
1181
|
+
const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
|
1176
1182
|
isUndefined(defaultValue) ||
|
1177
1183
|
(ref && ref.defaultChecked) ||
|
1178
1184
|
shouldSkipSetValueAs
|
1179
1185
|
? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
|
1180
1186
|
: setFieldValue(name, defaultValue);
|
1187
|
+
_stateFlags.mount && _updateValid();
|
1181
1188
|
}
|
1182
|
-
_stateFlags.mount && _updateValid();
|
1183
1189
|
};
|
1184
|
-
const updateTouchAndDirty = (name, fieldValue,
|
1190
|
+
const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
|
1185
1191
|
let isFieldDirty = false;
|
1186
1192
|
const output = {
|
1187
1193
|
name,
|
@@ -1192,7 +1198,7 @@ function createFormControl(props = {}) {
|
|
1192
1198
|
_formState.isDirty = output.isDirty = _getDirty();
|
1193
1199
|
isFieldDirty = isPreviousFormDirty !== output.isDirty;
|
1194
1200
|
}
|
1195
|
-
if (_proxyFormState.dirtyFields && !
|
1201
|
+
if (_proxyFormState.dirtyFields && (!isBlurEvent || shouldDirty)) {
|
1196
1202
|
const isPreviousFieldDirty = get(_formState.dirtyFields, name);
|
1197
1203
|
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
1198
1204
|
isCurrentFieldPristine
|
@@ -1203,13 +1209,13 @@ function createFormControl(props = {}) {
|
|
1203
1209
|
isFieldDirty ||
|
1204
1210
|
isPreviousFieldDirty !== get(_formState.dirtyFields, name);
|
1205
1211
|
}
|
1206
|
-
if (
|
1207
|
-
set(_formState.touchedFields, name,
|
1212
|
+
if (isBlurEvent && !isPreviousFieldTouched) {
|
1213
|
+
set(_formState.touchedFields, name, isBlurEvent);
|
1208
1214
|
output.touchedFields = _formState.touchedFields;
|
1209
1215
|
isFieldDirty =
|
1210
1216
|
isFieldDirty ||
|
1211
1217
|
(_proxyFormState.touchedFields &&
|
1212
|
-
isPreviousFieldTouched !==
|
1218
|
+
isPreviousFieldTouched !== isBlurEvent);
|
1213
1219
|
}
|
1214
1220
|
isFieldDirty && shouldRender && _subjects.state.next(output);
|
1215
1221
|
return isFieldDirty ? output : {};
|
@@ -1335,7 +1341,8 @@ function createFormControl(props = {}) {
|
|
1335
1341
|
? fieldReference.refs.forEach((checkboxRef) => (checkboxRef.checked = Array.isArray(fieldValue)
|
1336
1342
|
? !!fieldValue.find((data) => data === checkboxRef.value)
|
1337
1343
|
: fieldValue === checkboxRef.value))
|
1338
|
-
:
|
1344
|
+
: fieldReference.refs[0] &&
|
1345
|
+
(fieldReference.refs[0].checked = !!fieldValue);
|
1339
1346
|
}
|
1340
1347
|
else {
|
1341
1348
|
fieldReference.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
|
@@ -1352,7 +1359,7 @@ function createFormControl(props = {}) {
|
|
1352
1359
|
}
|
1353
1360
|
}
|
1354
1361
|
(options.shouldDirty || options.shouldTouch) &&
|
1355
|
-
updateTouchAndDirty(name, fieldValue, options.shouldTouch);
|
1362
|
+
updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
|
1356
1363
|
options.shouldValidate && trigger(name);
|
1357
1364
|
};
|
1358
1365
|
const setValues = (name, value, options) => {
|
@@ -1414,13 +1421,13 @@ function createFormControl(props = {}) {
|
|
1414
1421
|
!field._f.deps) ||
|
1415
1422
|
skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
|
1416
1423
|
const watched = isWatched(name, _names, isBlurEvent);
|
1424
|
+
set(_formValues, name, fieldValue);
|
1417
1425
|
if (isBlurEvent) {
|
1418
1426
|
field._f.onBlur && field._f.onBlur(event);
|
1419
1427
|
}
|
1420
1428
|
else if (field._f.onChange) {
|
1421
1429
|
field._f.onChange(event);
|
1422
1430
|
}
|
1423
|
-
set(_formValues, name, fieldValue);
|
1424
1431
|
const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, false);
|
1425
1432
|
const shouldRender = !isEmptyObject(fieldState) || watched;
|
1426
1433
|
!isBlurEvent &&
|
@@ -1501,7 +1508,6 @@ function createFormControl(props = {}) {
|
|
1501
1508
|
: (_formState.errors = {});
|
1502
1509
|
_subjects.state.next({
|
1503
1510
|
errors: _formState.errors,
|
1504
|
-
isValid: true,
|
1505
1511
|
});
|
1506
1512
|
};
|
1507
1513
|
const setError = (name, error, options) => {
|
@@ -1542,20 +1548,18 @@ function createFormControl(props = {}) {
|
|
1542
1548
|
};
|
1543
1549
|
const register = (name, options = {}) => {
|
1544
1550
|
let field = get(_fields, name);
|
1551
|
+
const disabledIsDefined = isBoolean(options.disabled);
|
1545
1552
|
set(_fields, name, {
|
1546
1553
|
_f: Object.assign(Object.assign(Object.assign({}, (field && field._f ? field._f : { ref: { name } })), { name, mount: true }), options),
|
1547
1554
|
});
|
1548
1555
|
_names.mount.add(name);
|
1549
|
-
!isUndefined(options.value) &&
|
1550
|
-
!options.disabled &&
|
1551
|
-
set(_formValues, name, get(_formValues, name, options.value));
|
1552
1556
|
field
|
1553
|
-
?
|
1557
|
+
? disabledIsDefined &&
|
1554
1558
|
set(_formValues, name, options.disabled
|
1555
1559
|
? undefined
|
1556
1560
|
: get(_formValues, name, getFieldValue(field._f)))
|
1557
|
-
: updateValidAndValue(name, true);
|
1558
|
-
return Object.assign(Object.assign(Object.assign({}, (
|
1561
|
+
: updateValidAndValue(name, true, options.value);
|
1562
|
+
return Object.assign(Object.assign(Object.assign({}, (disabledIsDefined ? { disabled: options.disabled } : {})), (_options.shouldUseNativeValidation
|
1559
1563
|
? {
|
1560
1564
|
required: !!options.required,
|
1561
1565
|
min: getRuleValue(options.min),
|
@@ -1575,16 +1579,21 @@ function createFormControl(props = {}) {
|
|
1575
1579
|
: ref
|
1576
1580
|
: ref;
|
1577
1581
|
const radioOrCheckbox = isRadioOrCheckbox(fieldRef);
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1582
|
+
const refs = field._f.refs || [];
|
1583
|
+
if (radioOrCheckbox
|
1584
|
+
? refs.find((option) => option === fieldRef)
|
1585
|
+
: fieldRef === field._f.ref) {
|
1581
1586
|
return;
|
1582
1587
|
}
|
1583
1588
|
set(_fields, name, {
|
1584
|
-
_f: radioOrCheckbox
|
1585
|
-
?
|
1589
|
+
_f: Object.assign(Object.assign({}, field._f), (radioOrCheckbox
|
1590
|
+
? {
|
1591
|
+
refs: refs.concat(fieldRef).filter(live),
|
1592
|
+
ref: { type: fieldRef.type, name },
|
1593
|
+
}
|
1594
|
+
: { ref: fieldRef })),
|
1586
1595
|
});
|
1587
|
-
updateValidAndValue(name, false, fieldRef);
|
1596
|
+
updateValidAndValue(name, false, undefined, fieldRef);
|
1588
1597
|
}
|
1589
1598
|
else {
|
1590
1599
|
field = get(_fields, name, {});
|
@@ -1648,27 +1657,29 @@ function createFormControl(props = {}) {
|
|
1648
1657
|
}
|
1649
1658
|
};
|
1650
1659
|
const resetField = (name, options = {}) => {
|
1651
|
-
if (
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1660
|
+
if (get(_fields, name)) {
|
1661
|
+
if (isUndefined(options.defaultValue)) {
|
1662
|
+
setValue(name, get(_defaultValues, name));
|
1663
|
+
}
|
1664
|
+
else {
|
1665
|
+
setValue(name, options.defaultValue);
|
1666
|
+
set(_defaultValues, name, options.defaultValue);
|
1667
|
+
}
|
1668
|
+
if (!options.keepTouched) {
|
1669
|
+
unset(_formState.touchedFields, name);
|
1670
|
+
}
|
1671
|
+
if (!options.keepDirty) {
|
1672
|
+
unset(_formState.dirtyFields, name);
|
1673
|
+
_formState.isDirty = options.defaultValue
|
1674
|
+
? _getDirty(name, get(_defaultValues, name))
|
1675
|
+
: _getDirty();
|
1676
|
+
}
|
1677
|
+
if (!options.keepError) {
|
1678
|
+
unset(_formState.errors, name);
|
1679
|
+
_proxyFormState.isValid && _updateValid();
|
1680
|
+
}
|
1681
|
+
_subjects.state.next(Object.assign({}, _formState));
|
1670
1682
|
}
|
1671
|
-
_subjects.state.next(Object.assign({}, _formState));
|
1672
1683
|
};
|
1673
1684
|
const reset = (formValues, keepStateOptions = {}) => {
|
1674
1685
|
const updatedValues = formValues || _defaultValues;
|
@@ -1843,14 +1854,15 @@ function useForm(props = {}) {
|
|
1843
1854
|
_formControl.current = Object.assign(Object.assign({}, createFormControl(props)), { formState });
|
1844
1855
|
}
|
1845
1856
|
const control = _formControl.current.control;
|
1857
|
+
const callback = React.useCallback((value) => {
|
1858
|
+
if (shouldRenderFormState(value, control._proxyFormState, true)) {
|
1859
|
+
control._formState = Object.assign(Object.assign({}, control._formState), value);
|
1860
|
+
updateFormState(Object.assign({}, control._formState));
|
1861
|
+
}
|
1862
|
+
}, [control]);
|
1846
1863
|
useSubscribe({
|
1847
1864
|
subject: control._subjects.state,
|
1848
|
-
callback
|
1849
|
-
if (shouldRenderFormState(value, control._proxyFormState, true)) {
|
1850
|
-
control._formState = Object.assign(Object.assign({}, control._formState), value);
|
1851
|
-
updateFormState(Object.assign({}, control._formState));
|
1852
|
-
}
|
1853
|
-
},
|
1865
|
+
callback,
|
1854
1866
|
});
|
1855
1867
|
React.useEffect(() => {
|
1856
1868
|
if (!control._stateFlags.mount) {
|