@depup/react-hook-form 7.84.0-depup.0 → 7.86.0-depup.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 +2 -2
- package/changes.json +1 -1
- package/dist/controller.d.ts +1 -2
- package/dist/controller.d.ts.map +1 -1
- package/dist/form.d.ts +1 -2
- package/dist/form.d.ts.map +1 -1
- package/dist/{formStateSubscribe.d.ts → formState.d.ts} +1 -1
- package/dist/formState.d.ts.map +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.mjs +323 -170
- 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/generateId.d.ts.map +1 -1
- package/dist/logic/getCheckboxValue.d.ts.map +1 -1
- package/dist/logic/getFieldArrayItemNames.d.ts +4 -0
- package/dist/logic/getFieldArrayItemNames.d.ts.map +1 -0
- package/dist/logic/getProxyFormState.d.ts +1 -1
- package/dist/logic/getProxyFormState.d.ts.map +1 -1
- package/dist/logic/hasValidation.d.ts +1 -1
- package/dist/logic/hasValidation.d.ts.map +1 -1
- package/dist/logic/unsetEmptyArray.d.ts +1 -1
- package/dist/logic/unsetEmptyArray.d.ts.map +1 -1
- package/dist/logic/validateField.d.ts.map +1 -1
- package/dist/types/errors.d.ts +6 -1
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/form.d.ts +49 -3
- package/dist/types/form.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +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/useFormState.d.ts.map +1 -1
- package/dist/useResyncOnReconnect.d.ts +5 -0
- package/dist/useResyncOnReconnect.d.ts.map +1 -0
- package/dist/useWatch.d.ts.map +1 -1
- package/dist/utils/cloneObject.d.ts.map +1 -1
- package/dist/utils/deepEqual.d.ts +1 -1
- package/dist/utils/deepEqual.d.ts.map +1 -1
- package/dist/utils/flatten.d.ts.map +1 -1
- package/dist/utils/has.d.ts +3 -0
- package/dist/utils/has.d.ts.map +1 -0
- package/dist/utils/json.d.ts +2 -2
- package/dist/utils/json.d.ts.map +1 -1
- package/package.json +4 -8
- package/dist/formStateSubscribe.d.ts.map +0 -1
- package/dist/index.react-server.d.ts +0 -3
- package/dist/index.react-server.d.ts.map +0 -1
- package/dist/logic/getNodeParentName.d.ts +0 -3
- package/dist/logic/getNodeParentName.d.ts.map +0 -1
- package/dist/react-server.esm.mjs +0 -2319
- package/dist/react-server.esm.mjs.map +0 -1
- package/dist/utils/deepMerge.d.ts +0 -2
- package/dist/utils/deepMerge.d.ts.map +0 -1
package/dist/index.esm.mjs
CHANGED
|
@@ -26,16 +26,14 @@ var isNameInFieldArray = (names, name) => name
|
|
|
26
26
|
.split('.')
|
|
27
27
|
.some((part, index, arr) => !isNaN(Number(part)) && names.has(arr.slice(0, index).join('.')));
|
|
28
28
|
|
|
29
|
-
var isPlainObject = (tempObject) => {
|
|
30
|
-
const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
|
|
31
|
-
return (isObject(prototypeCopy) && prototypeCopy.hasOwnProperty('isPrototypeOf'));
|
|
32
|
-
};
|
|
33
|
-
|
|
34
29
|
var isWeb = typeof window !== 'undefined' &&
|
|
35
30
|
typeof window.HTMLElement !== 'undefined' &&
|
|
36
31
|
typeof document !== 'undefined';
|
|
37
32
|
|
|
38
33
|
function cloneObject(data) {
|
|
34
|
+
if (data === null || typeof data !== 'object') {
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
39
37
|
if (data instanceof Date) {
|
|
40
38
|
return new Date(data);
|
|
41
39
|
}
|
|
@@ -44,7 +42,7 @@ function cloneObject(data) {
|
|
|
44
42
|
return data;
|
|
45
43
|
}
|
|
46
44
|
const isArray = Array.isArray(data);
|
|
47
|
-
if (!isArray &&
|
|
45
|
+
if (!isArray && data.constructor !== Object) {
|
|
48
46
|
return data;
|
|
49
47
|
}
|
|
50
48
|
const copy = isArray ? [] : Object.create(Object.getPrototypeOf(data));
|
|
@@ -170,6 +168,87 @@ const useIsomorphicLayoutEffect = isWeb
|
|
|
170
168
|
? React.useLayoutEffect
|
|
171
169
|
: React.useEffect;
|
|
172
170
|
|
|
171
|
+
var isPlainObject = (tempObject) => {
|
|
172
|
+
const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
|
|
173
|
+
return (isObject(prototypeCopy) && prototypeCopy.hasOwnProperty('isPrototypeOf'));
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
177
|
+
|
|
178
|
+
const isEmptyObjectWithCustomPrototype = (object, keys) => keys.length === 0 && !Array.isArray(object) && !isPlainObject(object);
|
|
179
|
+
function deepEqual(object1, object2, visited = new WeakMap()) {
|
|
180
|
+
if (object1 === object2) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
184
|
+
return Object.is(object1, object2);
|
|
185
|
+
}
|
|
186
|
+
if (isDateObject(object1) && isDateObject(object2)) {
|
|
187
|
+
return Object.is(object1.getTime(), object2.getTime());
|
|
188
|
+
}
|
|
189
|
+
const keys1 = Object.keys(object1);
|
|
190
|
+
const keys2 = Object.keys(object2);
|
|
191
|
+
if (keys1.length !== keys2.length) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
if (isEmptyObjectWithCustomPrototype(object1, keys1) ||
|
|
195
|
+
isEmptyObjectWithCustomPrototype(object2, keys2)) {
|
|
196
|
+
return Object.is(object1, object2);
|
|
197
|
+
}
|
|
198
|
+
if (!keys1.length && Array.isArray(object1) !== Array.isArray(object2)) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
const visitedPairs = visited.get(object1);
|
|
202
|
+
if (visitedPairs && visitedPairs.has(object2)) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
if (visitedPairs) {
|
|
206
|
+
visitedPairs.add(object2);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
const ws = new WeakSet();
|
|
210
|
+
ws.add(object2);
|
|
211
|
+
visited.set(object1, ws);
|
|
212
|
+
}
|
|
213
|
+
for (const key of keys1) {
|
|
214
|
+
const val1 = object1[key];
|
|
215
|
+
if (!(key in object2)) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
if (key !== 'ref') {
|
|
219
|
+
const val2 = object2[key];
|
|
220
|
+
if ((isDateObject(val1) && isDateObject(val2)) ||
|
|
221
|
+
((isObject(val1) || Array.isArray(val1)) &&
|
|
222
|
+
(isObject(val2) || Array.isArray(val2)))
|
|
223
|
+
? !deepEqual(val1, val2, visited)
|
|
224
|
+
: !Object.is(val1, val2)) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function useResyncOnReconnect() {
|
|
233
|
+
const _connected = React.useRef(false);
|
|
234
|
+
const _prevValue = React.useRef(undefined);
|
|
235
|
+
const resyncIfNeeded = React.useCallback((enabled, getCurrentValue, setValue) => {
|
|
236
|
+
if (enabled && _connected.current) {
|
|
237
|
+
const currentValue = getCurrentValue();
|
|
238
|
+
if (!deepEqual(_prevValue.current, currentValue)) {
|
|
239
|
+
setValue(currentValue);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
_connected.current = true;
|
|
243
|
+
}, []);
|
|
244
|
+
const snapshot = React.useCallback((enabled, getCurrentValue) => {
|
|
245
|
+
if (enabled) {
|
|
246
|
+
_prevValue.current = cloneObject(getCurrentValue());
|
|
247
|
+
}
|
|
248
|
+
}, []);
|
|
249
|
+
return { resyncIfNeeded, snapshot };
|
|
250
|
+
}
|
|
251
|
+
|
|
173
252
|
/**
|
|
174
253
|
* Subscribes to each form state and isolates re-renders at the custom hook level. It has its own scope for form state subscriptions, so it will not affect other useFormState or useForm instances. Using this hook can reduce the re-render impact on large and complex form applications.
|
|
175
254
|
*
|
|
@@ -217,19 +296,31 @@ function useFormState(props) {
|
|
|
217
296
|
isValid: false,
|
|
218
297
|
errors: false,
|
|
219
298
|
});
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
299
|
+
const { resyncIfNeeded, snapshot } = useResyncOnReconnect();
|
|
300
|
+
useIsomorphicLayoutEffect(() => {
|
|
301
|
+
const getCurrentFormState = () => ({
|
|
302
|
+
...control._formState,
|
|
303
|
+
defaultValues: control._defaultValues,
|
|
304
|
+
});
|
|
305
|
+
resyncIfNeeded(!disabled, getCurrentFormState, updateFormState);
|
|
306
|
+
const unsubscribe = control._subscribe({
|
|
307
|
+
name,
|
|
308
|
+
formState: _localProxyFormState.current,
|
|
309
|
+
exact,
|
|
310
|
+
callback: (formState) => {
|
|
311
|
+
!disabled &&
|
|
312
|
+
updateFormState({
|
|
313
|
+
...control._formState,
|
|
314
|
+
...formState,
|
|
315
|
+
defaultValues: control._defaultValues,
|
|
316
|
+
});
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
return () => {
|
|
320
|
+
unsubscribe();
|
|
321
|
+
snapshot(!disabled, getCurrentFormState);
|
|
322
|
+
};
|
|
323
|
+
}, [name, disabled, exact, resyncIfNeeded, snapshot]);
|
|
233
324
|
React.useEffect(() => {
|
|
234
325
|
_localProxyFormState.current.isValid && control._setValid(true);
|
|
235
326
|
}, [control]);
|
|
@@ -251,62 +342,6 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
|
|
|
251
342
|
return formValues;
|
|
252
343
|
};
|
|
253
344
|
|
|
254
|
-
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
255
|
-
|
|
256
|
-
const isEmptyObjectWithCustomPrototype = (object, keys) => keys.length === 0 && !Array.isArray(object) && !isPlainObject(object);
|
|
257
|
-
function deepEqual(object1, object2, visited = new WeakMap()) {
|
|
258
|
-
if (object1 === object2) {
|
|
259
|
-
return true;
|
|
260
|
-
}
|
|
261
|
-
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
262
|
-
return Object.is(object1, object2);
|
|
263
|
-
}
|
|
264
|
-
if (isDateObject(object1) && isDateObject(object2)) {
|
|
265
|
-
return Object.is(object1.getTime(), object2.getTime());
|
|
266
|
-
}
|
|
267
|
-
const keys1 = Object.keys(object1);
|
|
268
|
-
const keys2 = Object.keys(object2);
|
|
269
|
-
if (keys1.length !== keys2.length) {
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
|
-
if (isEmptyObjectWithCustomPrototype(object1, keys1) ||
|
|
273
|
-
isEmptyObjectWithCustomPrototype(object2, keys2)) {
|
|
274
|
-
return Object.is(object1, object2);
|
|
275
|
-
}
|
|
276
|
-
if (!keys1.length && Array.isArray(object1) !== Array.isArray(object2)) {
|
|
277
|
-
return false;
|
|
278
|
-
}
|
|
279
|
-
const visitedPairs = visited.get(object1);
|
|
280
|
-
if (visitedPairs && visitedPairs.has(object2)) {
|
|
281
|
-
return true;
|
|
282
|
-
}
|
|
283
|
-
if (visitedPairs) {
|
|
284
|
-
visitedPairs.add(object2);
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
const ws = new WeakSet();
|
|
288
|
-
ws.add(object2);
|
|
289
|
-
visited.set(object1, ws);
|
|
290
|
-
}
|
|
291
|
-
for (const key of keys1) {
|
|
292
|
-
const val1 = object1[key];
|
|
293
|
-
if (!(key in object2)) {
|
|
294
|
-
return false;
|
|
295
|
-
}
|
|
296
|
-
if (key !== 'ref') {
|
|
297
|
-
const val2 = object2[key];
|
|
298
|
-
if ((isDateObject(val1) && isDateObject(val2)) ||
|
|
299
|
-
((isObject(val1) || Array.isArray(val1)) &&
|
|
300
|
-
(isObject(val2) || Array.isArray(val2)))
|
|
301
|
-
? !deepEqual(val1, val2, visited)
|
|
302
|
-
: !Object.is(val1, val2)) {
|
|
303
|
-
return false;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
return true;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
345
|
/**
|
|
311
346
|
* Custom hook to subscribe to field changes and isolate re-rendering at the component level.
|
|
312
347
|
*
|
|
@@ -355,24 +390,39 @@ function useWatch(props) {
|
|
|
355
390
|
}
|
|
356
391
|
}
|
|
357
392
|
}, [control._formValues, control._names, disabled, name]);
|
|
393
|
+
const { resyncIfNeeded, snapshot } = useResyncOnReconnect();
|
|
394
|
+
const _refreshValue = React.useRef(refreshValue);
|
|
395
|
+
_refreshValue.current = refreshValue;
|
|
396
|
+
const _getCurrentOutput = React.useRef(getCurrentOutput);
|
|
397
|
+
_getCurrentOutput.current = getCurrentOutput;
|
|
358
398
|
useIsomorphicLayoutEffect(() => {
|
|
359
399
|
if (_prevControl.current !== control ||
|
|
360
400
|
!deepEqual(_prevName.current, name)) {
|
|
361
401
|
_prevControl.current = control;
|
|
362
402
|
_prevName.current = name;
|
|
363
|
-
|
|
403
|
+
_refreshValue.current();
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
resyncIfNeeded(!disabled, () => _getCurrentOutput.current(), (currentValue) => {
|
|
407
|
+
updateValue(currentValue);
|
|
408
|
+
_computeFormValues.current = currentValue;
|
|
409
|
+
});
|
|
364
410
|
}
|
|
365
|
-
|
|
411
|
+
const unsubscribe = control._subscribe({
|
|
366
412
|
name,
|
|
367
413
|
formState: {
|
|
368
414
|
values: true,
|
|
369
415
|
},
|
|
370
416
|
exact,
|
|
371
417
|
callback: (formState) => {
|
|
372
|
-
|
|
418
|
+
_refreshValue.current(formState.values);
|
|
373
419
|
},
|
|
374
420
|
});
|
|
375
|
-
|
|
421
|
+
return () => {
|
|
422
|
+
unsubscribe();
|
|
423
|
+
snapshot(!disabled, () => _getCurrentOutput.current());
|
|
424
|
+
};
|
|
425
|
+
}, [control, exact, name, disabled, resyncIfNeeded, snapshot]);
|
|
376
426
|
React.useEffect(() => control._removeUnmounted());
|
|
377
427
|
// If name or control changed for this render, synchronously reflect the
|
|
378
428
|
// latest value so callers (like useController) see the correct value
|
|
@@ -380,17 +430,17 @@ function useWatch(props) {
|
|
|
380
430
|
// Optimize: Check control reference first before expensive deepEqual
|
|
381
431
|
const controlChanged = _prevControl.current !== control;
|
|
382
432
|
const prevName = _prevName.current;
|
|
383
|
-
//
|
|
384
|
-
//
|
|
385
|
-
|
|
433
|
+
// `null`/`undefined` are valid watched values, so a boolean flag (rather
|
|
434
|
+
// than a sentinel return value) decides whether to return the freshly
|
|
435
|
+
// computed output instead of the possibly-stale state value.
|
|
436
|
+
const shouldReturnImmediate = React.useMemo(() => {
|
|
386
437
|
if (disabled) {
|
|
387
|
-
return
|
|
438
|
+
return false;
|
|
388
439
|
}
|
|
389
440
|
const nameChanged = !controlChanged && !deepEqual(prevName, name);
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
return computedOutput !== null ? computedOutput : value;
|
|
441
|
+
return controlChanged || nameChanged;
|
|
442
|
+
}, [disabled, controlChanged, name, prevName]);
|
|
443
|
+
return shouldReturnImmediate ? getCurrentOutput() : value;
|
|
394
444
|
}
|
|
395
445
|
|
|
396
446
|
/**
|
|
@@ -606,16 +656,12 @@ function useController(props) {
|
|
|
606
656
|
*/
|
|
607
657
|
const Controller = (props) => props.render(useController(props));
|
|
608
658
|
|
|
609
|
-
var generateId = () =>
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
615
|
-
const r = ((Math.random() * 16 + d) % 16) | 0;
|
|
616
|
-
return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
|
|
659
|
+
var generateId = () => typeof crypto !== 'undefined' && crypto.randomUUID
|
|
660
|
+
? crypto.randomUUID()
|
|
661
|
+
: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
662
|
+
const r = (Math.random() * 16) | 0;
|
|
663
|
+
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
|
|
617
664
|
});
|
|
618
|
-
};
|
|
619
665
|
|
|
620
666
|
var getFocusFieldName = (name, index, options = {}) => options.shouldFocus || isUndefined(options.shouldFocus)
|
|
621
667
|
? options.focusName ||
|
|
@@ -712,23 +758,25 @@ const defaultResult = {
|
|
|
712
758
|
};
|
|
713
759
|
const validResult = { value: true, isValid: true };
|
|
714
760
|
var getCheckboxValue = (options) => {
|
|
715
|
-
if (Array.isArray(options)) {
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
return
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
}
|
|
731
|
-
return
|
|
761
|
+
if (!Array.isArray(options)) {
|
|
762
|
+
return defaultResult;
|
|
763
|
+
}
|
|
764
|
+
if (options.length > 1) {
|
|
765
|
+
const values = options
|
|
766
|
+
.filter((option) => option && option.checked && !option.disabled)
|
|
767
|
+
.map((option) => option.value);
|
|
768
|
+
return { value: values, isValid: !!values.length };
|
|
769
|
+
}
|
|
770
|
+
const option = options[0];
|
|
771
|
+
if (!option || !option.checked || option.disabled) {
|
|
772
|
+
return defaultResult;
|
|
773
|
+
}
|
|
774
|
+
if (!option.attributes || !('value' in option.attributes)) {
|
|
775
|
+
return validResult;
|
|
776
|
+
}
|
|
777
|
+
return isUndefined(option.value) || option.value === ''
|
|
778
|
+
? validResult
|
|
779
|
+
: { value: option.value, isValid: true };
|
|
732
780
|
};
|
|
733
781
|
|
|
734
782
|
const defaultReturn = {
|
|
@@ -830,7 +878,9 @@ var validateField = async (field, disabledFieldNames, formValues, validateAllFie
|
|
|
830
878
|
let exceedMin;
|
|
831
879
|
const maxOutput = getValueAndMessage(max);
|
|
832
880
|
const minOutput = getValueAndMessage(min);
|
|
833
|
-
if (!isNullOrUndefined(inputValue) &&
|
|
881
|
+
if (!isNullOrUndefined(inputValue) &&
|
|
882
|
+
!isDateObject(inputValue) &&
|
|
883
|
+
!isNaN(inputValue)) {
|
|
834
884
|
const valueNumber = ref.valueAsNumber ||
|
|
835
885
|
(inputValue ? +inputValue : inputValue);
|
|
836
886
|
if (!isNullOrUndefined(maxOutput.value)) {
|
|
@@ -944,7 +994,8 @@ var validateField = async (field, disabledFieldNames, formValues, validateAllFie
|
|
|
944
994
|
}
|
|
945
995
|
}
|
|
946
996
|
}
|
|
947
|
-
|
|
997
|
+
const fieldError = error[name];
|
|
998
|
+
setCustomValidity(fieldError ? fieldError.message : true);
|
|
948
999
|
return error;
|
|
949
1000
|
};
|
|
950
1001
|
|
|
@@ -1223,8 +1274,8 @@ function useFieldArray(props) {
|
|
|
1223
1274
|
setFields([...updatedFieldArrayValues]);
|
|
1224
1275
|
control._setFieldArray(name, updatedFieldArrayValues, updateAt, {
|
|
1225
1276
|
argA: index,
|
|
1226
|
-
argB:
|
|
1227
|
-
}
|
|
1277
|
+
argB: fillEmptyArray(value),
|
|
1278
|
+
});
|
|
1228
1279
|
};
|
|
1229
1280
|
const replace = (value) => {
|
|
1230
1281
|
if (disabled) {
|
|
@@ -1238,9 +1289,11 @@ function useFieldArray(props) {
|
|
|
1238
1289
|
};
|
|
1239
1290
|
React.useEffect(() => {
|
|
1240
1291
|
if (disabled) {
|
|
1292
|
+
control._state.actionArrayLengths.delete(name);
|
|
1241
1293
|
return;
|
|
1242
1294
|
}
|
|
1243
1295
|
control._state.action = false;
|
|
1296
|
+
control._state.actionArrayLengths.delete(name);
|
|
1244
1297
|
isWatched(name, control._names) &&
|
|
1245
1298
|
control._subjects.state.next({
|
|
1246
1299
|
...control._formState,
|
|
@@ -1282,10 +1335,7 @@ function useFieldArray(props) {
|
|
|
1282
1335
|
}
|
|
1283
1336
|
else {
|
|
1284
1337
|
const field = get(control._fields, name);
|
|
1285
|
-
if (field &&
|
|
1286
|
-
field._f &&
|
|
1287
|
-
!(getValidationModes(control._options.reValidateMode).isOnSubmit &&
|
|
1288
|
-
getValidationModes(control._options.mode).isOnSubmit)) {
|
|
1338
|
+
if (field && field._f) {
|
|
1289
1339
|
validateField(field, control._names.disabled, control._formValues, control._options.criteriaMode === VALIDATION_MODE.all, control._options.shouldUseNativeValidation, true).then((error) => !isEmptyObject(error) &&
|
|
1290
1340
|
control._subjects.state.next({
|
|
1291
1341
|
errors: updateFieldArrayRootError(control._formState.errors, error, name),
|
|
@@ -1320,6 +1370,7 @@ function useFieldArray(props) {
|
|
|
1320
1370
|
!get(control._formValues, name) && control._setFieldArray(name);
|
|
1321
1371
|
}
|
|
1322
1372
|
return () => {
|
|
1373
|
+
control._state.actionArrayLengths.delete(name);
|
|
1323
1374
|
if (disabled) {
|
|
1324
1375
|
return;
|
|
1325
1376
|
}
|
|
@@ -1402,12 +1453,15 @@ function useFieldArray(props) {
|
|
|
1402
1453
|
*/
|
|
1403
1454
|
const FieldArray = (props) => props.render(useFieldArray(props));
|
|
1404
1455
|
|
|
1456
|
+
const isFileLike = (value) => (typeof Blob !== 'undefined' && value instanceof Blob) ||
|
|
1457
|
+
(typeof File !== 'undefined' && value instanceof File);
|
|
1405
1458
|
const flatten = (obj) => {
|
|
1406
1459
|
const output = {};
|
|
1407
1460
|
for (const key of Object.keys(obj)) {
|
|
1408
1461
|
if (isObjectType(obj[key]) &&
|
|
1409
1462
|
obj[key] !== null &&
|
|
1410
|
-
!isDateObject(obj[key])
|
|
1463
|
+
!isDateObject(obj[key]) &&
|
|
1464
|
+
!isFileLike(obj[key])) {
|
|
1411
1465
|
const nested = flatten(obj[key]);
|
|
1412
1466
|
for (const nestedKey of Object.keys(nested)) {
|
|
1413
1467
|
output[`${key}.${nestedKey}`] = nested[nestedKey];
|
|
@@ -1503,10 +1557,11 @@ const useFormContext = () => React.useContext(HookFormContext);
|
|
|
1503
1557
|
* }
|
|
1504
1558
|
* ```
|
|
1505
1559
|
*/
|
|
1506
|
-
const FormProvider = ({ children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, resetDefaultValues, handleSubmit, unregister, control, register, setFocus, subscribe, }) => {
|
|
1560
|
+
const FormProvider = ({ children, watch, getValues, getErrors, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, resetDefaultValues, handleSubmit, unregister, control, register, setFocus, subscribe, }) => {
|
|
1507
1561
|
const memoizedValue = React.useMemo(() => ({
|
|
1508
1562
|
watch,
|
|
1509
1563
|
getValues,
|
|
1564
|
+
getErrors,
|
|
1510
1565
|
getFieldState,
|
|
1511
1566
|
setError,
|
|
1512
1567
|
clearErrors,
|
|
@@ -1527,6 +1582,7 @@ const FormProvider = ({ children, watch, getValues, getFieldState, setError, cle
|
|
|
1527
1582
|
clearErrors,
|
|
1528
1583
|
control,
|
|
1529
1584
|
formState,
|
|
1585
|
+
getErrors,
|
|
1530
1586
|
getFieldState,
|
|
1531
1587
|
getValues,
|
|
1532
1588
|
handleSubmit,
|
|
@@ -1714,6 +1770,24 @@ function extractFormValues(fieldsState, formValues) {
|
|
|
1714
1770
|
return values;
|
|
1715
1771
|
}
|
|
1716
1772
|
|
|
1773
|
+
const hasOwn = (value, key) => value !== null &&
|
|
1774
|
+
isObjectType(value) &&
|
|
1775
|
+
Object.prototype.hasOwnProperty.call(value, key);
|
|
1776
|
+
var has = (object, path) => {
|
|
1777
|
+
if (!path) {
|
|
1778
|
+
return false;
|
|
1779
|
+
}
|
|
1780
|
+
let result = object;
|
|
1781
|
+
for (const key of isKey(path) ? [path] : stringToPath(path)) {
|
|
1782
|
+
if (!hasOwn(result, key)) {
|
|
1783
|
+
// `get` also resolves a path held as a single literal key, eg `{ 'a.b': 1 }`
|
|
1784
|
+
return hasOwn(object, path);
|
|
1785
|
+
}
|
|
1786
|
+
result = result[key];
|
|
1787
|
+
}
|
|
1788
|
+
return true;
|
|
1789
|
+
};
|
|
1790
|
+
|
|
1717
1791
|
var isMultipleSelect = (element) => element.type === `select-multiple`;
|
|
1718
1792
|
|
|
1719
1793
|
var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
|
|
@@ -1813,6 +1887,18 @@ function getDirtyFields(data, formValues, dirtyFieldsFromValues, fieldRefs) {
|
|
|
1813
1887
|
return dirtyFieldsFromValues;
|
|
1814
1888
|
}
|
|
1815
1889
|
|
|
1890
|
+
var getFieldArrayItemNames = (names, name) => {
|
|
1891
|
+
const segments = name.split('.');
|
|
1892
|
+
const matches = [];
|
|
1893
|
+
let prefix = segments[0];
|
|
1894
|
+
for (let i = 1; i < segments.length; prefix += '.' + segments[i++]) {
|
|
1895
|
+
if (!isNaN(+segments[i]) && names.has(prefix)) {
|
|
1896
|
+
matches.push(`${prefix}.${segments[i]}`);
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
return matches;
|
|
1900
|
+
};
|
|
1901
|
+
|
|
1816
1902
|
var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isUndefined(value)
|
|
1817
1903
|
? value
|
|
1818
1904
|
: valueAsNumber
|
|
@@ -1888,10 +1974,11 @@ var hasPromiseValidation = (fieldReference) => {
|
|
|
1888
1974
|
|
|
1889
1975
|
var hasValidation = (options) => options.mount &&
|
|
1890
1976
|
(options.required ||
|
|
1891
|
-
options.
|
|
1892
|
-
options.
|
|
1893
|
-
options.
|
|
1894
|
-
options.
|
|
1977
|
+
(!isUndefined(options.required) && options.required !== false) ||
|
|
1978
|
+
!isUndefined(options.min) ||
|
|
1979
|
+
!isUndefined(options.max) ||
|
|
1980
|
+
!isUndefined(options.maxLength) ||
|
|
1981
|
+
!isUndefined(options.minLength) ||
|
|
1895
1982
|
options.pattern ||
|
|
1896
1983
|
options.validate);
|
|
1897
1984
|
|
|
@@ -1964,7 +2051,12 @@ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode)
|
|
|
1964
2051
|
return true;
|
|
1965
2052
|
};
|
|
1966
2053
|
|
|
1967
|
-
var unsetEmptyArray = (ref, name) =>
|
|
2054
|
+
var unsetEmptyArray = (ref, name) => {
|
|
2055
|
+
const array = get(ref, name);
|
|
2056
|
+
!compact(array).length &&
|
|
2057
|
+
!(array === null || array === void 0 ? void 0 : array.root) &&
|
|
2058
|
+
unset(ref, name);
|
|
2059
|
+
};
|
|
1968
2060
|
|
|
1969
2061
|
const defaultOptions = {
|
|
1970
2062
|
mode: VALIDATION_MODE.onSubmit,
|
|
@@ -2013,6 +2105,7 @@ function createFormControl(props = {}) {
|
|
|
2013
2105
|
: cloneObject(_defaultValues);
|
|
2014
2106
|
let _state = {
|
|
2015
2107
|
action: false,
|
|
2108
|
+
actionArrayLengths: new Map(),
|
|
2016
2109
|
mount: false,
|
|
2017
2110
|
watch: false,
|
|
2018
2111
|
keepIsValid: false,
|
|
@@ -2089,7 +2182,7 @@ function createFormControl(props = {}) {
|
|
|
2089
2182
|
_proxyFormState.validatingFields ||
|
|
2090
2183
|
_proxySubscribeFormState.isValidating ||
|
|
2091
2184
|
_proxySubscribeFormState.validatingFields)) {
|
|
2092
|
-
(names ||
|
|
2185
|
+
(names || _names.mount).forEach((name) => {
|
|
2093
2186
|
if (name) {
|
|
2094
2187
|
isValidating
|
|
2095
2188
|
? set(_formState.validatingFields, name, isValidating)
|
|
@@ -2108,21 +2201,30 @@ function createFormControl(props = {}) {
|
|
|
2108
2201
|
const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
|
2109
2202
|
if (args && method && !_options.disabled) {
|
|
2110
2203
|
_state.action = true;
|
|
2111
|
-
|
|
2112
|
-
|
|
2204
|
+
const fields = get(_fields, name);
|
|
2205
|
+
if (!_state.actionArrayLengths.has(name)) {
|
|
2206
|
+
_state.actionArrayLengths.set(name, Array.isArray(fields) ? fields.length : 0);
|
|
2207
|
+
}
|
|
2208
|
+
if (shouldUpdateFieldsAndState && Array.isArray(fields)) {
|
|
2209
|
+
const fieldValues = method(fields, args.argA, args.argB);
|
|
2113
2210
|
shouldSetValues && set(_fields, name, fieldValues);
|
|
2114
2211
|
}
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
const
|
|
2212
|
+
const fieldArrayErrors = get(_formState.errors, name);
|
|
2213
|
+
if (shouldUpdateFieldsAndState && Array.isArray(fieldArrayErrors)) {
|
|
2214
|
+
const rootError = fieldArrayErrors.root;
|
|
2215
|
+
const errors = method(fieldArrayErrors, args.argA, args.argB) || fieldArrayErrors;
|
|
2216
|
+
if (rootError) {
|
|
2217
|
+
errors.root = rootError;
|
|
2218
|
+
}
|
|
2118
2219
|
shouldSetValues && set(_formState.errors, name, errors);
|
|
2119
2220
|
unsetEmptyArray(_formState.errors, name);
|
|
2120
2221
|
}
|
|
2222
|
+
const touchedFieldsArray = get(_formState.touchedFields, name);
|
|
2121
2223
|
if ((_proxyFormState.touchedFields ||
|
|
2122
2224
|
_proxySubscribeFormState.touchedFields) &&
|
|
2123
2225
|
shouldUpdateFieldsAndState &&
|
|
2124
|
-
Array.isArray(
|
|
2125
|
-
const touchedFields = method(
|
|
2226
|
+
Array.isArray(touchedFieldsArray)) {
|
|
2227
|
+
const touchedFields = method(touchedFieldsArray, args.argA, args.argB);
|
|
2126
2228
|
shouldSetValues && set(_formState.touchedFields, name, touchedFields);
|
|
2127
2229
|
}
|
|
2128
2230
|
if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
|
|
@@ -2170,10 +2272,40 @@ function createFormControl(props = {}) {
|
|
|
2170
2272
|
}
|
|
2171
2273
|
return false;
|
|
2172
2274
|
};
|
|
2275
|
+
const isStaleArrayIndex = (name) => {
|
|
2276
|
+
if (!_state.actionArrayLengths.size) {
|
|
2277
|
+
return false;
|
|
2278
|
+
}
|
|
2279
|
+
const segments = isKey(name) ? [name] : stringToPath(name);
|
|
2280
|
+
let node = _formValues;
|
|
2281
|
+
let path = '';
|
|
2282
|
+
let ownerDepth = -1;
|
|
2283
|
+
let ownerPreActionLength = 0;
|
|
2284
|
+
for (let i = 0; i < segments.length; i++) {
|
|
2285
|
+
if (isNullOrUndefined(node)) {
|
|
2286
|
+
return false;
|
|
2287
|
+
}
|
|
2288
|
+
const key = segments[i];
|
|
2289
|
+
path = path ? `${path}.${key}` : key;
|
|
2290
|
+
if (Array.isArray(node) && +key >= node.length) {
|
|
2291
|
+
return ownerDepth === -1
|
|
2292
|
+
? false
|
|
2293
|
+
: i === ownerDepth
|
|
2294
|
+
? +key < ownerPreActionLength
|
|
2295
|
+
: true;
|
|
2296
|
+
}
|
|
2297
|
+
if (_state.actionArrayLengths.has(path)) {
|
|
2298
|
+
ownerDepth = i + 1;
|
|
2299
|
+
ownerPreActionLength = _state.actionArrayLengths.get(path);
|
|
2300
|
+
}
|
|
2301
|
+
node = node[key];
|
|
2302
|
+
}
|
|
2303
|
+
return false;
|
|
2304
|
+
};
|
|
2173
2305
|
const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
|
|
2174
2306
|
const field = get(_fields, name);
|
|
2175
2307
|
if (field) {
|
|
2176
|
-
if (hasExplicitNullIntermediate(name)) {
|
|
2308
|
+
if (hasExplicitNullIntermediate(name) || isStaleArrayIndex(name)) {
|
|
2177
2309
|
return;
|
|
2178
2310
|
}
|
|
2179
2311
|
const wasUnsetInFormValues = isUndefined(get(_formValues, name));
|
|
@@ -2278,10 +2410,6 @@ function createFormControl(props = {}) {
|
|
|
2278
2410
|
errors: _formState.errors,
|
|
2279
2411
|
name,
|
|
2280
2412
|
};
|
|
2281
|
-
_formState = {
|
|
2282
|
-
..._formState,
|
|
2283
|
-
...updatedFormState,
|
|
2284
|
-
};
|
|
2285
2413
|
_subjects.state.next(updatedFormState);
|
|
2286
2414
|
}
|
|
2287
2415
|
};
|
|
@@ -2421,14 +2549,12 @@ function createFormControl(props = {}) {
|
|
|
2421
2549
|
const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
|
|
2422
2550
|
...(_state.mount
|
|
2423
2551
|
? _formValues
|
|
2424
|
-
: isUndefined(defaultValue)
|
|
2552
|
+
: isUndefined(defaultValue) || isString(names)
|
|
2425
2553
|
? _defaultValues
|
|
2426
|
-
:
|
|
2427
|
-
? { [names]: defaultValue }
|
|
2428
|
-
: defaultValue),
|
|
2554
|
+
: defaultValue),
|
|
2429
2555
|
}, isGlobal, defaultValue);
|
|
2430
2556
|
const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
|
|
2431
|
-
const setFieldValue = (name, value, options = {}, skipClone = false, skipRender = false) => {
|
|
2557
|
+
const setFieldValue = (name, value, options = {}, skipClone = false, skipRender = false, skipValueRender = false) => {
|
|
2432
2558
|
const field = get(_fields, name);
|
|
2433
2559
|
let fieldValue = value;
|
|
2434
2560
|
if (field) {
|
|
@@ -2466,7 +2592,7 @@ function createFormControl(props = {}) {
|
|
|
2466
2592
|
}
|
|
2467
2593
|
else {
|
|
2468
2594
|
fieldReference.ref.value = fieldValue;
|
|
2469
|
-
if (!fieldReference.ref.type && !skipRender) {
|
|
2595
|
+
if (!fieldReference.ref.type && !skipRender && !skipValueRender) {
|
|
2470
2596
|
_subjects.state.next({
|
|
2471
2597
|
name,
|
|
2472
2598
|
values: skipClone ? _formValues : cloneObject(_formValues),
|
|
@@ -2482,7 +2608,7 @@ function createFormControl(props = {}) {
|
|
|
2482
2608
|
delayError: options.delayError,
|
|
2483
2609
|
});
|
|
2484
2610
|
};
|
|
2485
|
-
const setFieldValues = (name, value, options, skipClone = false, skipRender = false) => {
|
|
2611
|
+
const setFieldValues = (name, value, options, skipClone = false, skipRender = false, skipValueRender = false) => {
|
|
2486
2612
|
if (_names.array.has(name)) {
|
|
2487
2613
|
_subjects.array.next({
|
|
2488
2614
|
name,
|
|
@@ -2500,8 +2626,8 @@ function createFormControl(props = {}) {
|
|
|
2500
2626
|
isObject(fieldValue) ||
|
|
2501
2627
|
(field && !field._f)) &&
|
|
2502
2628
|
!isDateObject(fieldValue)
|
|
2503
|
-
? setFieldValues(fieldName, fieldValue, options, skipClone, skipRender)
|
|
2504
|
-
: setFieldValue(fieldName, fieldValue, options, skipClone, skipRender);
|
|
2629
|
+
? setFieldValues(fieldName, fieldValue, options, skipClone, skipRender, skipValueRender)
|
|
2630
|
+
: setFieldValue(fieldName, fieldValue, options, skipClone, skipRender, skipValueRender);
|
|
2505
2631
|
}
|
|
2506
2632
|
};
|
|
2507
2633
|
const _setValue = (name, value, options, skipClone, skipStateEmit = false) => {
|
|
@@ -2536,11 +2662,12 @@ function createFormControl(props = {}) {
|
|
|
2536
2662
|
else {
|
|
2537
2663
|
const isEmpty = (Array.isArray(cloneValue) && !cloneValue.length) ||
|
|
2538
2664
|
isEmptyObject(cloneValue);
|
|
2665
|
+
const skipValueRender = !isValueUnchanged && !skipStateEmit;
|
|
2539
2666
|
if (!field || field._f || isNullOrUndefined(cloneValue) || isEmpty) {
|
|
2540
|
-
setFieldValue(name, cloneValue, options, skipClone, skipStateEmit);
|
|
2667
|
+
setFieldValue(name, cloneValue, options, skipClone, skipStateEmit, skipValueRender);
|
|
2541
2668
|
}
|
|
2542
2669
|
else {
|
|
2543
|
-
setFieldValues(name, cloneValue, options, skipClone, skipStateEmit);
|
|
2670
|
+
setFieldValues(name, cloneValue, options, skipClone, skipStateEmit, skipValueRender);
|
|
2544
2671
|
}
|
|
2545
2672
|
}
|
|
2546
2673
|
if (!isValueUnchanged && !skipStateEmit) {
|
|
@@ -2551,6 +2678,11 @@ function createFormControl(props = {}) {
|
|
|
2551
2678
|
name: _state.mount || watched ? name : undefined,
|
|
2552
2679
|
values,
|
|
2553
2680
|
});
|
|
2681
|
+
if (!isFieldArray) {
|
|
2682
|
+
for (const itemName of getFieldArrayItemNames(_names.array, name)) {
|
|
2683
|
+
_subjects.state.next({ name: itemName, values });
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2554
2686
|
}
|
|
2555
2687
|
};
|
|
2556
2688
|
const setValue = (name, value, options = {}) => _setValue(name, value, options, false);
|
|
@@ -2563,10 +2695,9 @@ function createFormControl(props = {}) {
|
|
|
2563
2695
|
..._formValues,
|
|
2564
2696
|
...updatedFormValues,
|
|
2565
2697
|
};
|
|
2566
|
-
const flattenedUpdates = flatten(updatedFormValues);
|
|
2567
2698
|
for (const fieldName of _names.mount) {
|
|
2568
|
-
if (fieldName
|
|
2569
|
-
_setValue(fieldName,
|
|
2699
|
+
if (has(updatedFormValues, fieldName)) {
|
|
2700
|
+
_setValue(fieldName, get(updatedFormValues, fieldName), options, true, true);
|
|
2570
2701
|
}
|
|
2571
2702
|
}
|
|
2572
2703
|
_subjects.state.next({
|
|
@@ -2766,13 +2897,22 @@ function createFormControl(props = {}) {
|
|
|
2766
2897
|
? get(values, fieldNames)
|
|
2767
2898
|
: fieldNames.map((name) => get(values, name));
|
|
2768
2899
|
};
|
|
2769
|
-
const
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2900
|
+
const getErrors = (fieldNames) => isUndefined(fieldNames)
|
|
2901
|
+
? { ..._formState.errors }
|
|
2902
|
+
: isString(fieldNames)
|
|
2903
|
+
? get(_formState.errors, fieldNames)
|
|
2904
|
+
: fieldNames.map((name) => get(_formState.errors, name));
|
|
2905
|
+
const getFieldState = (name, formState) => {
|
|
2906
|
+
const targetFormState = formState || _formState;
|
|
2907
|
+
const error = get(targetFormState.errors, name);
|
|
2908
|
+
return {
|
|
2909
|
+
invalid: !!error,
|
|
2910
|
+
isDirty: !!get(targetFormState.dirtyFields, name),
|
|
2911
|
+
error,
|
|
2912
|
+
isValidating: !!get(_formState.validatingFields, name),
|
|
2913
|
+
isTouched: !!get(targetFormState.touchedFields, name),
|
|
2914
|
+
};
|
|
2915
|
+
};
|
|
2776
2916
|
const clearErrors = (name) => {
|
|
2777
2917
|
const names = name ? convertToArrayPayload(name) : undefined;
|
|
2778
2918
|
names === null || names === void 0 ? void 0 : names.forEach((inputName) => unset(_formState.errors, inputName));
|
|
@@ -2892,12 +3032,13 @@ function createFormControl(props = {}) {
|
|
|
2892
3032
|
!options.keepDefaultValue &&
|
|
2893
3033
|
unset(_defaultValues, fieldName);
|
|
2894
3034
|
}
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
3035
|
+
_valuesSubscriberCount &&
|
|
3036
|
+
_subjects.state.next({
|
|
3037
|
+
values: cloneObject(_formValues),
|
|
3038
|
+
});
|
|
2898
3039
|
_subjects.state.next({
|
|
2899
3040
|
..._formState,
|
|
2900
|
-
...(
|
|
3041
|
+
...(options.keepDirty ? {} : { isDirty: _getDirty() }),
|
|
2901
3042
|
});
|
|
2902
3043
|
!options.keepIsValid && _setValid();
|
|
2903
3044
|
};
|
|
@@ -3123,7 +3264,7 @@ function createFormControl(props = {}) {
|
|
|
3123
3264
|
..._names.mount,
|
|
3124
3265
|
...collectDirtyFieldNames(getDirtyFields(_defaultValues, _formValues, undefined, fieldRefs), _formState.dirtyFields),
|
|
3125
3266
|
]);
|
|
3126
|
-
for (const fieldName of
|
|
3267
|
+
for (const fieldName of fieldsToCheck) {
|
|
3127
3268
|
const isDirty = get(_formState.dirtyFields, fieldName);
|
|
3128
3269
|
const existingValue = get(_formValues, fieldName);
|
|
3129
3270
|
const newValue = get(values, fieldName);
|
|
@@ -3202,6 +3343,7 @@ function createFormControl(props = {}) {
|
|
|
3202
3343
|
_state.watch = !!_options.shouldUnregister;
|
|
3203
3344
|
_state.keepIsValid = !!keepStateOptions.keepIsValid;
|
|
3204
3345
|
_state.action = false;
|
|
3346
|
+
_state.actionArrayLengths.clear();
|
|
3205
3347
|
if (!keepStateOptions.keepErrors) {
|
|
3206
3348
|
_formState.errors = {};
|
|
3207
3349
|
}
|
|
@@ -3274,6 +3416,7 @@ function createFormControl(props = {}) {
|
|
|
3274
3416
|
...formState,
|
|
3275
3417
|
};
|
|
3276
3418
|
};
|
|
3419
|
+
_subjects.state.subscribe({ next: _setFormState });
|
|
3277
3420
|
const _resetDefaultValues = () => isFunction(_options.defaultValues) &&
|
|
3278
3421
|
_options.defaultValues().then((values) => {
|
|
3279
3422
|
reset(values, _options.resetOptions);
|
|
@@ -3364,6 +3507,7 @@ function createFormControl(props = {}) {
|
|
|
3364
3507
|
setValue,
|
|
3365
3508
|
setValues,
|
|
3366
3509
|
getValues,
|
|
3510
|
+
getErrors,
|
|
3367
3511
|
reset,
|
|
3368
3512
|
resetField,
|
|
3369
3513
|
resetDefaultValues,
|
|
@@ -3443,8 +3587,14 @@ function useForm(props = {}) {
|
|
|
3443
3587
|
}
|
|
3444
3588
|
const control = _formControl.current.control;
|
|
3445
3589
|
control._options = props;
|
|
3590
|
+
const { resyncIfNeeded, snapshot } = useResyncOnReconnect();
|
|
3446
3591
|
useIsomorphicLayoutEffect(() => {
|
|
3447
|
-
const
|
|
3592
|
+
const getCurrentFormState = () => ({
|
|
3593
|
+
...control._formState,
|
|
3594
|
+
defaultValues: control._defaultValues,
|
|
3595
|
+
});
|
|
3596
|
+
resyncIfNeeded(true, getCurrentFormState, updateFormState);
|
|
3597
|
+
const unsubscribe = control._subscribe({
|
|
3448
3598
|
formState: control._proxyFormState,
|
|
3449
3599
|
callback: () => updateFormState({
|
|
3450
3600
|
...control._formState,
|
|
@@ -3457,8 +3607,11 @@ function useForm(props = {}) {
|
|
|
3457
3607
|
isReady: true,
|
|
3458
3608
|
}));
|
|
3459
3609
|
control._formState.isReady = true;
|
|
3460
|
-
return
|
|
3461
|
-
|
|
3610
|
+
return () => {
|
|
3611
|
+
unsubscribe();
|
|
3612
|
+
snapshot(true, getCurrentFormState);
|
|
3613
|
+
};
|
|
3614
|
+
}, [control, resyncIfNeeded, snapshot]);
|
|
3462
3615
|
React.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
|
|
3463
3616
|
React.useEffect(() => {
|
|
3464
3617
|
if (props.mode) {
|