react-hook-form 7.44.0-next.0 → 7.44.0-rc.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 +11 -32
- package/dist/constants.d.ts +0 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/form.d.ts +18 -4
- package/dist/form.d.ts.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +192 -180
- package/dist/index.esm.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/logic/getDirtyFields.d.ts.map +1 -1
- package/dist/types/errors.d.ts +2 -2
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/fieldArray.d.ts +1 -1
- package/dist/types/form.d.ts +10 -11
- package/dist/types/form.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 +1 -1
- package/dist/useForm.d.ts.map +1 -1
- package/dist/useFormContext.d.ts +1 -1
- package/dist/useFormContext.d.ts.map +1 -1
- package/dist/useSubscribe.d.ts.map +1 -1
- package/dist/utils/get.d.ts +1 -1
- package/dist/utils/get.d.ts.map +1 -1
- package/dist/utils/isMessage.d.ts.map +1 -1
- package/package.json +4 -8
package/dist/index.esm.mjs
CHANGED
@@ -23,6 +23,42 @@ var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/))
|
|
23
23
|
|
24
24
|
var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
|
25
25
|
|
26
|
+
var isPlainObject = (tempObject) => {
|
27
|
+
const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
|
28
|
+
return (isObject(prototypeCopy) && prototypeCopy.hasOwnProperty('isPrototypeOf'));
|
29
|
+
};
|
30
|
+
|
31
|
+
var isWeb = typeof window !== 'undefined' &&
|
32
|
+
typeof window.HTMLElement !== 'undefined' &&
|
33
|
+
typeof document !== 'undefined';
|
34
|
+
|
35
|
+
function cloneObject(data) {
|
36
|
+
let copy;
|
37
|
+
const isArray = Array.isArray(data);
|
38
|
+
if (data instanceof Date) {
|
39
|
+
copy = new Date(data);
|
40
|
+
}
|
41
|
+
else if (data instanceof Set) {
|
42
|
+
copy = new Set(data);
|
43
|
+
}
|
44
|
+
else if (!(isWeb && (data instanceof Blob || data instanceof FileList)) &&
|
45
|
+
(isArray || isObject(data))) {
|
46
|
+
copy = isArray ? [] : {};
|
47
|
+
if (!Array.isArray(data) && !isPlainObject(data)) {
|
48
|
+
copy = data;
|
49
|
+
}
|
50
|
+
else {
|
51
|
+
for (const key in data) {
|
52
|
+
copy[key] = cloneObject(data[key]);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
else {
|
57
|
+
return data;
|
58
|
+
}
|
59
|
+
return copy;
|
60
|
+
}
|
61
|
+
|
26
62
|
var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
|
27
63
|
|
28
64
|
var isUndefined = (val) => val === undefined;
|
@@ -59,8 +95,7 @@ const INPUT_VALIDATION_RULES = {
|
|
59
95
|
pattern: 'pattern',
|
60
96
|
required: 'required',
|
61
97
|
validate: 'validate',
|
62
|
-
};
|
63
|
-
const SERVER_ERROR_TYPE = 'root.server';
|
98
|
+
};
|
64
99
|
|
65
100
|
const HookFormContext = React__default.createContext(null);
|
66
101
|
/**
|
@@ -175,6 +210,7 @@ function useSubscribe(props) {
|
|
175
210
|
_props.current = props;
|
176
211
|
React__default.useEffect(() => {
|
177
212
|
const subscription = !props.disabled &&
|
213
|
+
_props.current.subject &&
|
178
214
|
_props.current.subject.subscribe({
|
179
215
|
next: _props.current.next,
|
180
216
|
});
|
@@ -271,42 +307,6 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
|
|
271
307
|
return formValues;
|
272
308
|
};
|
273
309
|
|
274
|
-
var isPlainObject = (tempObject) => {
|
275
|
-
const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
|
276
|
-
return (isObject(prototypeCopy) && prototypeCopy.hasOwnProperty('isPrototypeOf'));
|
277
|
-
};
|
278
|
-
|
279
|
-
var isWeb = typeof window !== 'undefined' &&
|
280
|
-
typeof window.HTMLElement !== 'undefined' &&
|
281
|
-
typeof document !== 'undefined';
|
282
|
-
|
283
|
-
function cloneObject(data) {
|
284
|
-
let copy;
|
285
|
-
const isArray = Array.isArray(data);
|
286
|
-
if (data instanceof Date) {
|
287
|
-
copy = new Date(data);
|
288
|
-
}
|
289
|
-
else if (data instanceof Set) {
|
290
|
-
copy = new Set(data);
|
291
|
-
}
|
292
|
-
else if (!(isWeb && (data instanceof Blob || data instanceof FileList)) &&
|
293
|
-
(isArray || isObject(data))) {
|
294
|
-
copy = isArray ? [] : {};
|
295
|
-
if (!Array.isArray(data) && !isPlainObject(data)) {
|
296
|
-
copy = data;
|
297
|
-
}
|
298
|
-
else {
|
299
|
-
for (const key in data) {
|
300
|
-
copy[key] = cloneObject(data[key]);
|
301
|
-
}
|
302
|
-
}
|
303
|
-
}
|
304
|
-
else {
|
305
|
-
return data;
|
306
|
-
}
|
307
|
-
return copy;
|
308
|
-
}
|
309
|
-
|
310
310
|
/**
|
311
311
|
* Custom hook to subscribe to field change and isolate re-rendering at the component level.
|
312
312
|
*
|
@@ -330,7 +330,7 @@ function useWatch(props) {
|
|
330
330
|
_name.current = name;
|
331
331
|
useSubscribe({
|
332
332
|
disabled,
|
333
|
-
subject: control._subjects.
|
333
|
+
subject: control._subjects.values,
|
334
334
|
next: (formState) => {
|
335
335
|
if (shouldSubscribeByName(_name.current, formState.name, exact)) {
|
336
336
|
updateValue(cloneObject(generateWatchOutput(_name.current, control._names, formState.values || control._formValues, false, defaultValue)));
|
@@ -342,6 +342,33 @@ function useWatch(props) {
|
|
342
342
|
return value;
|
343
343
|
}
|
344
344
|
|
345
|
+
var isKey = (value) => /^\w*$/.test(value);
|
346
|
+
|
347
|
+
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, '').split(/\.|\[/));
|
348
|
+
|
349
|
+
function set(object, path, value) {
|
350
|
+
let index = -1;
|
351
|
+
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
352
|
+
const length = tempPath.length;
|
353
|
+
const lastIndex = length - 1;
|
354
|
+
while (++index < length) {
|
355
|
+
const key = tempPath[index];
|
356
|
+
let newValue = value;
|
357
|
+
if (index !== lastIndex) {
|
358
|
+
const objValue = object[key];
|
359
|
+
newValue =
|
360
|
+
isObject(objValue) || Array.isArray(objValue)
|
361
|
+
? objValue
|
362
|
+
: !isNaN(+tempPath[index + 1])
|
363
|
+
? []
|
364
|
+
: {};
|
365
|
+
}
|
366
|
+
object[key] = newValue;
|
367
|
+
object = object[key];
|
368
|
+
}
|
369
|
+
return object;
|
370
|
+
}
|
371
|
+
|
345
372
|
/**
|
346
373
|
* Custom hook to work with controlled component, this function provide you with both form and field level state. Re-render is isolated at the hook level.
|
347
374
|
*
|
@@ -385,6 +412,7 @@ function useController(props) {
|
|
385
412
|
value,
|
386
413
|
}));
|
387
414
|
React__default.useEffect(() => {
|
415
|
+
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
388
416
|
const updateMounted = (name, value) => {
|
389
417
|
const field = get(control._fields, name);
|
390
418
|
if (field) {
|
@@ -392,10 +420,12 @@ function useController(props) {
|
|
392
420
|
}
|
393
421
|
};
|
394
422
|
updateMounted(name, true);
|
423
|
+
if (_shouldUnregisterField) {
|
424
|
+
set(control._defaultValues, name, cloneObject(get(control._options.defaultValues, name)));
|
425
|
+
}
|
395
426
|
return () => {
|
396
|
-
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
397
427
|
(isArrayField
|
398
|
-
? _shouldUnregisterField && !control.
|
428
|
+
? _shouldUnregisterField && !control._state.action
|
399
429
|
: _shouldUnregisterField)
|
400
430
|
? control.unregister(name)
|
401
431
|
: updateMounted(name, false);
|
@@ -523,55 +553,59 @@ const POST_REQUEST = 'post';
|
|
523
553
|
function Form(props) {
|
524
554
|
const methods = useFormContext();
|
525
555
|
const [mounted, setMounted] = React.useState(false);
|
526
|
-
const { control = methods.control, onSubmit, children, action, method = POST_REQUEST, headers, encType, onError, render, onSuccess, validateStatus, ...rest } = props;
|
527
|
-
const
|
528
|
-
|
529
|
-
|
530
|
-
if (action) {
|
556
|
+
const { control = methods.control, onSubmit, children, action, method = POST_REQUEST, headers, encType, onError, render, onSuccess, validateStatus, fetcher, ...rest } = props;
|
557
|
+
const submit = async (event) => {
|
558
|
+
let serverError = false;
|
559
|
+
await control.handleSubmit(async (values) => {
|
531
560
|
const formData = new FormData();
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
561
|
+
const formDataJson = JSON.stringify(values);
|
562
|
+
control._names.mount.forEach((name) => formData.append(name, get(values, name)));
|
563
|
+
onSubmit && onSubmit(values);
|
564
|
+
if (action) {
|
565
|
+
try {
|
566
|
+
if (fetcher) {
|
567
|
+
await fetcher(action, {
|
568
|
+
method,
|
569
|
+
values,
|
570
|
+
event,
|
571
|
+
formData,
|
572
|
+
formDataJson,
|
573
|
+
});
|
574
|
+
}
|
575
|
+
else {
|
576
|
+
const shouldStringifySubmissionData = headers && headers['Content-Type'].includes('json');
|
577
|
+
const response = await fetch(action, {
|
578
|
+
method,
|
579
|
+
headers: {
|
580
|
+
...headers,
|
581
|
+
...(encType ? { 'Content-Type': encType } : {}),
|
582
|
+
},
|
583
|
+
body: shouldStringifySubmissionData ? formDataJson : formData,
|
584
|
+
});
|
585
|
+
if (response &&
|
586
|
+
(validateStatus
|
587
|
+
? !validateStatus(response.status)
|
588
|
+
: response.status < 200 || response.status >= 300)) {
|
589
|
+
serverError = true;
|
590
|
+
onError && onError({ response });
|
552
591
|
}
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
: response.status < 200 || response.status >= 300) {
|
558
|
-
control.setError(SERVER_ERROR_TYPE, {
|
559
|
-
type: String(response.status),
|
560
|
-
});
|
561
|
-
onError && onError({ response });
|
592
|
+
else {
|
593
|
+
onSuccess && onSuccess({ response });
|
594
|
+
}
|
595
|
+
}
|
562
596
|
}
|
563
|
-
|
564
|
-
|
597
|
+
catch (error) {
|
598
|
+
serverError = true;
|
599
|
+
onError && onError({ error });
|
565
600
|
}
|
566
601
|
}
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
}
|
573
|
-
|
574
|
-
});
|
602
|
+
})(event);
|
603
|
+
serverError &&
|
604
|
+
props.control &&
|
605
|
+
props.control._subjects.state.next({
|
606
|
+
isSubmitSuccessful: false,
|
607
|
+
});
|
608
|
+
};
|
575
609
|
React.useEffect(() => {
|
576
610
|
setMounted(true);
|
577
611
|
}, []);
|
@@ -590,33 +624,6 @@ var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => va
|
|
590
624
|
}
|
591
625
|
: {};
|
592
626
|
|
593
|
-
var isKey = (value) => /^\w*$/.test(value);
|
594
|
-
|
595
|
-
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, '').split(/\.|\[/));
|
596
|
-
|
597
|
-
function set(object, path, value) {
|
598
|
-
let index = -1;
|
599
|
-
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
600
|
-
const length = tempPath.length;
|
601
|
-
const lastIndex = length - 1;
|
602
|
-
while (++index < length) {
|
603
|
-
const key = tempPath[index];
|
604
|
-
let newValue = value;
|
605
|
-
if (index !== lastIndex) {
|
606
|
-
const objValue = object[key];
|
607
|
-
newValue =
|
608
|
-
isObject(objValue) || Array.isArray(objValue)
|
609
|
-
? objValue
|
610
|
-
: !isNaN(+tempPath[index + 1])
|
611
|
-
? []
|
612
|
-
: {};
|
613
|
-
}
|
614
|
-
object[key] = newValue;
|
615
|
-
object = object[key];
|
616
|
-
}
|
617
|
-
return object;
|
618
|
-
}
|
619
|
-
|
620
627
|
const focusFieldBy = (fields, callback, fieldsNames) => {
|
621
628
|
for (const key of fieldsNames || Object.keys(fields)) {
|
622
629
|
const field = get(fields, key);
|
@@ -688,7 +695,7 @@ var isHTMLElement = (value) => {
|
|
688
695
|
(owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement));
|
689
696
|
};
|
690
697
|
|
691
|
-
var isMessage = (value) => isString(value)
|
698
|
+
var isMessage = (value) => isString(value);
|
692
699
|
|
693
700
|
var isRadioInput = (element) => element.type === 'radio';
|
694
701
|
|
@@ -1167,8 +1174,11 @@ function useFieldArray(props) {
|
|
1167
1174
|
control._updateFieldArray(name, [...updatedFieldArrayValues], (data) => data, {}, true, false);
|
1168
1175
|
};
|
1169
1176
|
React__default.useEffect(() => {
|
1170
|
-
control.
|
1171
|
-
isWatched(name, control._names) &&
|
1177
|
+
control._state.action = false;
|
1178
|
+
isWatched(name, control._names) &&
|
1179
|
+
control._subjects.state.next({
|
1180
|
+
...control._formState,
|
1181
|
+
});
|
1172
1182
|
if (_actioned.current &&
|
1173
1183
|
(!getValidationModes(control._options.mode).isOnSubmit ||
|
1174
1184
|
control._formState.isSubmitted)) {
|
@@ -1196,9 +1206,9 @@ function useFieldArray(props) {
|
|
1196
1206
|
}
|
1197
1207
|
}
|
1198
1208
|
}
|
1199
|
-
control._subjects.
|
1209
|
+
control._subjects.values.next({
|
1200
1210
|
name,
|
1201
|
-
values: control._formValues,
|
1211
|
+
values: { ...control._formValues },
|
1202
1212
|
});
|
1203
1213
|
control._names.focus &&
|
1204
1214
|
focusFieldBy(control._fields, (key) => !!key && key.startsWith(control._names.focus || ''));
|
@@ -1232,7 +1242,7 @@ function createSubject() {
|
|
1232
1242
|
let _observers = [];
|
1233
1243
|
const next = (value) => {
|
1234
1244
|
for (const observer of _observers) {
|
1235
|
-
observer.next(value);
|
1245
|
+
observer.next && observer.next(value);
|
1236
1246
|
}
|
1237
1247
|
};
|
1238
1248
|
const subscribe = (observer) => {
|
@@ -1337,9 +1347,7 @@ function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues
|
|
1337
1347
|
}
|
1338
1348
|
}
|
1339
1349
|
else {
|
1340
|
-
deepEqual(data[key], formValues[key])
|
1341
|
-
? delete dirtyFieldsFromValues[key]
|
1342
|
-
: (dirtyFieldsFromValues[key] = true);
|
1350
|
+
dirtyFieldsFromValues[key] = !deepEqual(data[key], formValues[key]);
|
1343
1351
|
}
|
1344
1352
|
}
|
1345
1353
|
}
|
@@ -1471,7 +1479,6 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1471
1479
|
...defaultOptions,
|
1472
1480
|
...props,
|
1473
1481
|
};
|
1474
|
-
const shouldCaptureDirtyFields = props.resetOptions && props.resetOptions.keepDirtyValues;
|
1475
1482
|
let _formState = {
|
1476
1483
|
submitCount: 0,
|
1477
1484
|
isDirty: false,
|
@@ -1492,7 +1499,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1492
1499
|
let _formValues = _options.shouldUnregister
|
1493
1500
|
? {}
|
1494
1501
|
: cloneObject(_defaultValues);
|
1495
|
-
let
|
1502
|
+
let _state = {
|
1496
1503
|
action: false,
|
1497
1504
|
mount: false,
|
1498
1505
|
watch: false,
|
@@ -1514,16 +1521,17 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1514
1521
|
errors: false,
|
1515
1522
|
};
|
1516
1523
|
const _subjects = {
|
1517
|
-
|
1524
|
+
values: createSubject(),
|
1518
1525
|
array: createSubject(),
|
1519
1526
|
state: createSubject(),
|
1520
1527
|
};
|
1528
|
+
const shouldCaptureDirtyFields = props.resetOptions && props.resetOptions.keepDirtyValues;
|
1521
1529
|
const validationModeBeforeSubmit = getValidationModes(_options.mode);
|
1522
1530
|
const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
1523
1531
|
const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
|
1524
1532
|
const debounce = (callback) => (wait) => {
|
1525
1533
|
clearTimeout(timer);
|
1526
|
-
timer =
|
1534
|
+
timer = setTimeout(callback, wait);
|
1527
1535
|
};
|
1528
1536
|
const _updateValid = async (shouldUpdateValid) => {
|
1529
1537
|
if (_proxyFormState.isValid || shouldUpdateValid) {
|
@@ -1543,7 +1551,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1543
1551
|
});
|
1544
1552
|
const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
1545
1553
|
if (args && method) {
|
1546
|
-
|
1554
|
+
_state.action = true;
|
1547
1555
|
if (shouldUpdateFieldsAndState && Array.isArray(get(_fields, name))) {
|
1548
1556
|
const fieldValues = method(get(_fields, name), args.argA, args.argB);
|
1549
1557
|
shouldSetValues && set(_fields, name, fieldValues);
|
@@ -1590,7 +1598,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1590
1598
|
shouldSkipSetValueAs
|
1591
1599
|
? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
|
1592
1600
|
: setFieldValue(name, defaultValue);
|
1593
|
-
|
1601
|
+
_state.mount && _updateValid();
|
1594
1602
|
}
|
1595
1603
|
};
|
1596
1604
|
const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
|
@@ -1663,7 +1671,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1663
1671
|
}
|
1664
1672
|
_updateIsValidating(false);
|
1665
1673
|
};
|
1666
|
-
const _executeSchema = async (name) =>
|
1674
|
+
const _executeSchema = async (name) => _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
|
1667
1675
|
const executeSchemaAndUpdateState = async (names) => {
|
1668
1676
|
const { errors } = await _executeSchema();
|
1669
1677
|
if (names) {
|
@@ -1688,7 +1696,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1688
1696
|
const { _f, ...fieldValue } = field;
|
1689
1697
|
if (_f) {
|
1690
1698
|
const isFieldArrayRoot = _names.array.has(_f.name);
|
1691
|
-
const fieldError = await validateField(field, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation, isFieldArrayRoot);
|
1699
|
+
const fieldError = await validateField(field, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
|
1692
1700
|
if (fieldError[_f.name]) {
|
1693
1701
|
context.valid = false;
|
1694
1702
|
if (shouldOnlyCheckValid) {
|
@@ -1722,7 +1730,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1722
1730
|
const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
|
1723
1731
|
!deepEqual(getValues(), _defaultValues));
|
1724
1732
|
const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
|
1725
|
-
...(
|
1733
|
+
...(_state.mount
|
1726
1734
|
? _formValues
|
1727
1735
|
: isUndefined(defaultValue)
|
1728
1736
|
? _defaultValues
|
@@ -1730,7 +1738,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1730
1738
|
? { [names]: defaultValue }
|
1731
1739
|
: defaultValue),
|
1732
1740
|
}, isGlobal, defaultValue);
|
1733
|
-
const _getFieldArray = (name) => compact(get(
|
1741
|
+
const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, props.shouldUnregister ? get(_defaultValues, name, []) : []));
|
1734
1742
|
const setFieldValue = (name, value, options = {}) => {
|
1735
1743
|
const field = get(_fields, name);
|
1736
1744
|
let fieldValue = value;
|
@@ -1766,8 +1774,9 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1766
1774
|
else {
|
1767
1775
|
fieldReference.ref.value = fieldValue;
|
1768
1776
|
if (!fieldReference.ref.type) {
|
1769
|
-
_subjects.
|
1777
|
+
_subjects.values.next({
|
1770
1778
|
name,
|
1779
|
+
values: { ..._formValues },
|
1771
1780
|
});
|
1772
1781
|
}
|
1773
1782
|
}
|
@@ -1798,7 +1807,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1798
1807
|
if (isFieldArray) {
|
1799
1808
|
_subjects.array.next({
|
1800
1809
|
name,
|
1801
|
-
values: _formValues,
|
1810
|
+
values: { ..._formValues },
|
1802
1811
|
});
|
1803
1812
|
if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields) &&
|
1804
1813
|
options.shouldDirty) {
|
@@ -1814,15 +1823,17 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1814
1823
|
? setValues(name, cloneValue, options)
|
1815
1824
|
: setFieldValue(name, cloneValue, options);
|
1816
1825
|
}
|
1817
|
-
isWatched(name, _names) && _subjects.state.next({});
|
1818
|
-
_subjects.
|
1826
|
+
isWatched(name, _names) && _subjects.state.next({ ..._formState });
|
1827
|
+
_subjects.values.next({
|
1819
1828
|
name,
|
1829
|
+
values: { ..._formValues },
|
1820
1830
|
});
|
1821
|
-
!
|
1831
|
+
!_state.mount && flushRootRender();
|
1822
1832
|
};
|
1823
1833
|
const onChange = async (event) => {
|
1824
1834
|
const target = event.target;
|
1825
1835
|
let name = target.name;
|
1836
|
+
let isFieldValueUpdated = true;
|
1826
1837
|
const field = get(_fields, name);
|
1827
1838
|
const getCurrentFieldValue = () => target.type ? getFieldValue(field._f) : getEventValue(event);
|
1828
1839
|
if (field) {
|
@@ -1847,16 +1858,17 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1847
1858
|
const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, false);
|
1848
1859
|
const shouldRender = !isEmptyObject(fieldState) || watched;
|
1849
1860
|
!isBlurEvent &&
|
1850
|
-
_subjects.
|
1861
|
+
_subjects.values.next({
|
1851
1862
|
name,
|
1852
1863
|
type: event.type,
|
1864
|
+
values: { ..._formValues },
|
1853
1865
|
});
|
1854
1866
|
if (shouldSkipValidation) {
|
1855
1867
|
_proxyFormState.isValid && _updateValid();
|
1856
1868
|
return (shouldRender &&
|
1857
1869
|
_subjects.state.next({ name, ...(watched ? {} : fieldState) }));
|
1858
1870
|
}
|
1859
|
-
!isBlurEvent && watched && _subjects.state.next({});
|
1871
|
+
!isBlurEvent && watched && _subjects.state.next({ ..._formState });
|
1860
1872
|
_updateIsValidating(true);
|
1861
1873
|
if (_options.resolver) {
|
1862
1874
|
const { errors } = await _executeSchema([name]);
|
@@ -1868,16 +1880,21 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1868
1880
|
}
|
1869
1881
|
else {
|
1870
1882
|
error = (await validateField(field, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1883
|
+
isFieldValueUpdated = fieldValue === get(_formValues, name, fieldValue);
|
1884
|
+
if (isFieldValueUpdated) {
|
1885
|
+
if (error) {
|
1886
|
+
isValid = false;
|
1887
|
+
}
|
1888
|
+
else if (_proxyFormState.isValid) {
|
1889
|
+
isValid = await executeBuiltInValidation(_fields, true);
|
1890
|
+
}
|
1876
1891
|
}
|
1877
1892
|
}
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1893
|
+
if (isFieldValueUpdated) {
|
1894
|
+
field._f.deps &&
|
1895
|
+
trigger(field._f.deps);
|
1896
|
+
shouldRenderByError(name, isValid, error, fieldState);
|
1897
|
+
}
|
1881
1898
|
}
|
1882
1899
|
};
|
1883
1900
|
const trigger = async (name, options = {}) => {
|
@@ -1919,7 +1936,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1919
1936
|
const getValues = (fieldNames) => {
|
1920
1937
|
const values = {
|
1921
1938
|
..._defaultValues,
|
1922
|
-
...(
|
1939
|
+
...(_state.mount ? _formValues : {}),
|
1923
1940
|
};
|
1924
1941
|
return isUndefined(fieldNames)
|
1925
1942
|
? values
|
@@ -1950,14 +1967,11 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1950
1967
|
name,
|
1951
1968
|
errors: _formState.errors,
|
1952
1969
|
isValid: false,
|
1953
|
-
...(error.type === SERVER_ERROR_TYPE
|
1954
|
-
? { isSubmitSuccessful: false }
|
1955
|
-
: {}),
|
1956
1970
|
});
|
1957
1971
|
options && options.shouldFocus && ref && ref.focus && ref.focus();
|
1958
1972
|
};
|
1959
1973
|
const watch = (name, defaultValue) => isFunction(name)
|
1960
|
-
? _subjects.
|
1974
|
+
? _subjects.values.subscribe({
|
1961
1975
|
next: (payload) => name(_getWatch(undefined, defaultValue), payload),
|
1962
1976
|
})
|
1963
1977
|
: _getWatch(name, defaultValue, true);
|
@@ -1978,7 +1992,9 @@ function createFormControl(props = {}, flushRootRender) {
|
|
1978
1992
|
unset(_defaultValues, fieldName);
|
1979
1993
|
}
|
1980
1994
|
}
|
1981
|
-
_subjects.
|
1995
|
+
_subjects.values.next({
|
1996
|
+
values: { ..._formValues },
|
1997
|
+
});
|
1982
1998
|
_subjects.state.next({
|
1983
1999
|
..._formState,
|
1984
2000
|
...(!options.keepDirty ? {} : { isDirty: _getDirty() }),
|
@@ -2058,7 +2074,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
2058
2074
|
field._f.mount = false;
|
2059
2075
|
}
|
2060
2076
|
(_options.shouldUnregister || options.shouldUnregister) &&
|
2061
|
-
!(isNameInFieldArray(_names.array, name) &&
|
2077
|
+
!(isNameInFieldArray(_names.array, name) && _state.action) &&
|
2062
2078
|
_names.unMount.add(name);
|
2063
2079
|
}
|
2064
2080
|
},
|
@@ -2095,6 +2111,7 @@ function createFormControl(props = {}, flushRootRender) {
|
|
2095
2111
|
await onInvalid({ ..._formState.errors }, e);
|
2096
2112
|
}
|
2097
2113
|
_focusError();
|
2114
|
+
setTimeout(_focusError);
|
2098
2115
|
}
|
2099
2116
|
_subjects.state.next({
|
2100
2117
|
isSubmitted: true,
|
@@ -2172,10 +2189,10 @@ function createFormControl(props = {}, flushRootRender) {
|
|
2172
2189
|
: {}
|
2173
2190
|
: cloneUpdatedValues;
|
2174
2191
|
_subjects.array.next({
|
2175
|
-
values,
|
2192
|
+
values: { ...values },
|
2176
2193
|
});
|
2177
|
-
_subjects.
|
2178
|
-
values,
|
2194
|
+
_subjects.values.next({
|
2195
|
+
values: { ...values },
|
2179
2196
|
});
|
2180
2197
|
}
|
2181
2198
|
_names = {
|
@@ -2186,22 +2203,21 @@ function createFormControl(props = {}, flushRootRender) {
|
|
2186
2203
|
watchAll: false,
|
2187
2204
|
focus: '',
|
2188
2205
|
};
|
2189
|
-
!
|
2190
|
-
|
2191
|
-
|
2192
|
-
_stateFlags.watch = !!props.shouldUnregister;
|
2206
|
+
!_state.mount && flushRootRender();
|
2207
|
+
_state.mount = !_proxyFormState.isValid || !!keepStateOptions.keepIsValid;
|
2208
|
+
_state.watch = !!props.shouldUnregister;
|
2193
2209
|
_subjects.state.next({
|
2194
2210
|
submitCount: keepStateOptions.keepSubmitCount
|
2195
2211
|
? _formState.submitCount
|
2196
2212
|
: 0,
|
2197
|
-
isDirty: keepStateOptions.keepDirty
|
2213
|
+
isDirty: keepStateOptions.keepDirty
|
2198
2214
|
? _formState.isDirty
|
2199
2215
|
: !!(keepStateOptions.keepDefaultValues &&
|
2200
2216
|
!deepEqual(formValues, _defaultValues)),
|
2201
2217
|
isSubmitted: keepStateOptions.keepIsSubmitted
|
2202
2218
|
? _formState.isSubmitted
|
2203
2219
|
: false,
|
2204
|
-
dirtyFields: keepStateOptions.
|
2220
|
+
dirtyFields: keepStateOptions.keepDirtyValues
|
2205
2221
|
? _formState.dirtyFields
|
2206
2222
|
: keepStateOptions.keepDefaultValues && formValues
|
2207
2223
|
? getDirtyFields(_defaultValues, formValues)
|
@@ -2252,7 +2268,6 @@ function createFormControl(props = {}, flushRootRender) {
|
|
2252
2268
|
handleSubmit,
|
2253
2269
|
setError,
|
2254
2270
|
_executeSchema,
|
2255
|
-
_focusError,
|
2256
2271
|
_getWatch,
|
2257
2272
|
_getDirty,
|
2258
2273
|
_updateValid,
|
@@ -2269,11 +2284,11 @@ function createFormControl(props = {}, flushRootRender) {
|
|
2269
2284
|
get _formValues() {
|
2270
2285
|
return _formValues;
|
2271
2286
|
},
|
2272
|
-
get
|
2273
|
-
return
|
2287
|
+
get _state() {
|
2288
|
+
return _state;
|
2274
2289
|
},
|
2275
|
-
set
|
2276
|
-
|
2290
|
+
set _state(value) {
|
2291
|
+
_state = value;
|
2277
2292
|
},
|
2278
2293
|
get _defaultValues() {
|
2279
2294
|
return _defaultValues;
|
@@ -2379,25 +2394,22 @@ function useForm(props = {}) {
|
|
2379
2394
|
}
|
2380
2395
|
},
|
2381
2396
|
});
|
2382
|
-
React__default.useEffect(() => {
|
2383
|
-
if (!control._stateFlags.mount) {
|
2384
|
-
control._updateValid();
|
2385
|
-
control._stateFlags.mount = true;
|
2386
|
-
}
|
2387
|
-
if (control._stateFlags.watch) {
|
2388
|
-
control._stateFlags.watch = false;
|
2389
|
-
control._subjects.state.next({});
|
2390
|
-
}
|
2391
|
-
control._removeUnmounted();
|
2392
|
-
});
|
2393
2397
|
React__default.useEffect(() => {
|
2394
2398
|
if (props.values && !deepEqual(props.values, control._defaultValues)) {
|
2395
2399
|
control._reset(props.values, control._options.resetOptions);
|
2396
2400
|
}
|
2397
2401
|
}, [props.values, control]);
|
2398
2402
|
React__default.useEffect(() => {
|
2399
|
-
|
2400
|
-
|
2403
|
+
if (!control._state.mount) {
|
2404
|
+
control._updateValid();
|
2405
|
+
control._state.mount = true;
|
2406
|
+
}
|
2407
|
+
if (control._state.watch) {
|
2408
|
+
control._state.watch = false;
|
2409
|
+
control._subjects.state.next({ ...control._formState });
|
2410
|
+
}
|
2411
|
+
control._removeUnmounted();
|
2412
|
+
});
|
2401
2413
|
_formControl.current.formState = getProxyFormState(formState, control);
|
2402
2414
|
return _formControl.current;
|
2403
2415
|
}
|