react-hook-form 8.0.0-alpha.1 → 8.0.0-alpha.2
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 +10 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +183 -91
- 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/focusFieldBy.d.ts.map +1 -1
- package/dist/logic/getResolverOptions.d.ts +1 -1
- package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
- package/dist/types/fieldArray.d.ts +1 -1
- package/dist/types/validator.d.ts +1 -1
- package/dist/types/validator.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useFormContext.d.ts.map +1 -1
- package/dist/utils/unset.d.ts.map +1 -1
- package/package.json +17 -17
package/dist/index.esm.mjs
CHANGED
@@ -60,12 +60,6 @@ const INPUT_VALIDATION_RULES = {
|
|
60
60
|
validate: 'validate',
|
61
61
|
};
|
62
62
|
|
63
|
-
var omit = (source, key) => {
|
64
|
-
const copy = Object.assign({}, source);
|
65
|
-
delete copy[key];
|
66
|
-
return copy;
|
67
|
-
};
|
68
|
-
|
69
63
|
const HookFormContext = React.createContext(null);
|
70
64
|
/**
|
71
65
|
* This custom hook allows you to access the form context. useFormContext is intended to be used in deeply nested structures, where it would become inconvenient to pass the context as a prop. To be used with {@link FormProvider}.
|
@@ -128,7 +122,10 @@ const useFormContext = () => React.useContext(HookFormContext);
|
|
128
122
|
* }
|
129
123
|
* ```
|
130
124
|
*/
|
131
|
-
const FormProvider = (props) =>
|
125
|
+
const FormProvider = (props) => {
|
126
|
+
const { children, ...data } = props;
|
127
|
+
return (React.createElement(HookFormContext.Provider, { value: data }, props.children));
|
128
|
+
};
|
132
129
|
|
133
130
|
var getProxyFormState = (formState, _proxyFormState, localProxyFormState, isRoot = true) => {
|
134
131
|
const result = {};
|
@@ -150,7 +147,7 @@ var getProxyFormState = (formState, _proxyFormState, localProxyFormState, isRoot
|
|
150
147
|
var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
|
151
148
|
|
152
149
|
var shouldRenderFormState = (formStateData, _proxyFormState, isRoot) => {
|
153
|
-
const formState =
|
150
|
+
const { name, ...formState } = formStateData;
|
154
151
|
return (isEmptyObject(formState) ||
|
155
152
|
Object.keys(formState).length >= Object.keys(_proxyFormState).length ||
|
156
153
|
Object.keys(formState).find((key) => _proxyFormState[key] ===
|
@@ -233,14 +230,20 @@ function useFormState(props) {
|
|
233
230
|
const callback = React.useCallback((value) => _mounted.current &&
|
234
231
|
shouldSubscribeByName(_name.current, value.name, exact) &&
|
235
232
|
shouldRenderFormState(value, _localProxyFormState.current) &&
|
236
|
-
updateFormState(
|
233
|
+
updateFormState({
|
234
|
+
...control._formState,
|
235
|
+
...value,
|
236
|
+
}), [control, exact]);
|
237
237
|
useSubscribe({
|
238
238
|
disabled,
|
239
239
|
callback,
|
240
240
|
subject: control._subjects.state,
|
241
241
|
});
|
242
|
-
React.useEffect(() =>
|
243
|
-
_mounted.current =
|
242
|
+
React.useEffect(() => {
|
243
|
+
_mounted.current = true;
|
244
|
+
return () => {
|
245
|
+
_mounted.current = false;
|
246
|
+
};
|
244
247
|
}, []);
|
245
248
|
return getProxyFormState(formState, control._proxyFormState, _localProxyFormState.current, false);
|
246
249
|
}
|
@@ -295,11 +298,12 @@ function useWatch(props) {
|
|
295
298
|
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
296
299
|
updateValue(isUndefined(_name.current) ||
|
297
300
|
(isObject(fieldValues) && !objectHasFunction(fieldValues))
|
298
|
-
?
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
301
|
+
? { ...fieldValues }
|
302
|
+
: Array.isArray(fieldValues)
|
303
|
+
? [...fieldValues]
|
304
|
+
: isUndefined(fieldValues)
|
305
|
+
? defaultValue
|
306
|
+
: fieldValues);
|
303
307
|
}
|
304
308
|
}, [control, exact, defaultValue]);
|
305
309
|
useSubscribe({
|
@@ -354,7 +358,10 @@ function useController(props) {
|
|
354
358
|
control,
|
355
359
|
name,
|
356
360
|
});
|
357
|
-
const _registerProps = React.useRef(control.register(name,
|
361
|
+
const _registerProps = React.useRef(control.register(name, {
|
362
|
+
...props.rules,
|
363
|
+
value: value,
|
364
|
+
}));
|
358
365
|
React.useEffect(() => {
|
359
366
|
const updateMounted = (name, value) => {
|
360
367
|
const field = get(control._fields, name);
|
@@ -455,7 +462,14 @@ function useController(props) {
|
|
455
462
|
const Controller = (props) => props.render(useController(props));
|
456
463
|
|
457
464
|
var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
|
458
|
-
?
|
465
|
+
? {
|
466
|
+
...errors[name],
|
467
|
+
types: {
|
468
|
+
...(errors[name] && errors[name].types ? errors[name].types : {}),
|
469
|
+
[type]: message || true,
|
470
|
+
},
|
471
|
+
}
|
472
|
+
: {};
|
459
473
|
|
460
474
|
/**
|
461
475
|
* Function for joining two paths / path strings to a {@link TypedFieldPath}.
|
@@ -519,8 +533,7 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
|
|
519
533
|
for (const key of fieldsNames || Object.keys(fields)) {
|
520
534
|
const field = get(fields, key);
|
521
535
|
if (field) {
|
522
|
-
const _f = field
|
523
|
-
const current = omit(field, '_f');
|
536
|
+
const { _f, ...currentField } = field;
|
524
537
|
if (_f && callback(_f.name)) {
|
525
538
|
if (_f.ref.focus && isUndefined(_f.ref.focus())) {
|
526
539
|
break;
|
@@ -530,8 +543,8 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
|
|
530
543
|
break;
|
531
544
|
}
|
532
545
|
}
|
533
|
-
else if (isObject(
|
534
|
-
focusFieldBy(
|
546
|
+
else if (isObject(currentField)) {
|
547
|
+
focusFieldBy(currentField, callback);
|
535
548
|
}
|
536
549
|
}
|
537
550
|
}
|
@@ -761,13 +774,14 @@ function useFieldArray(props) {
|
|
761
774
|
}, false);
|
762
775
|
};
|
763
776
|
const update = (index, value) => {
|
777
|
+
const updateValue = cloneObject(value);
|
764
778
|
const updatedFieldArrayValues = updateAt(control._getFieldArray(name), index, value);
|
765
779
|
ids.current = [...updatedFieldArrayValues].map((item, i) => !item || i === index ? generateId() : ids.current[i]);
|
766
780
|
updateValues(updatedFieldArrayValues);
|
767
781
|
setFields([...updatedFieldArrayValues]);
|
768
782
|
control._updateFieldArray(name, updatedFieldArrayValues, updateAt, {
|
769
783
|
argA: index,
|
770
|
-
argB:
|
784
|
+
argB: updateValue,
|
771
785
|
}, true, false);
|
772
786
|
};
|
773
787
|
const replace = (value) => {
|
@@ -816,7 +830,10 @@ function useFieldArray(props) {
|
|
816
830
|
insert: React.useCallback(insert$1, [updateValues, name, control]),
|
817
831
|
update: React.useCallback(update, [updateValues, name, control]),
|
818
832
|
replace: React.useCallback(replace, [updateValues, name, control]),
|
819
|
-
fields: React.useMemo(() => fields.map((field, index) => (
|
833
|
+
fields: React.useMemo(() => fields.map((field, index) => ({
|
834
|
+
...field,
|
835
|
+
id: ids.current[index] || generateId(),
|
836
|
+
})), [fields]),
|
820
837
|
};
|
821
838
|
}
|
822
839
|
|
@@ -937,9 +954,7 @@ function unset(object, path) {
|
|
937
954
|
if (currentPathsLength === index &&
|
938
955
|
((isObject(objectRef) && isEmptyObject(objectRef)) ||
|
939
956
|
(Array.isArray(objectRef) &&
|
940
|
-
!objectRef.filter((data) =>
|
941
|
-
isBoolean(data) ||
|
942
|
-
(Array.isArray(data) && data.length)).length))) {
|
957
|
+
!objectRef.filter((data) => !isUndefined(data)).length))) {
|
943
958
|
previousObjRef ? delete previousObjRef[item] : delete object[item];
|
944
959
|
}
|
945
960
|
previousObjRef = objectRef;
|
@@ -974,7 +989,7 @@ function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues
|
|
974
989
|
isPrimitive(dirtyFieldsFromValues[key])) {
|
975
990
|
dirtyFieldsFromValues[key] = Array.isArray(data[key])
|
976
991
|
? markFieldsDirty(data[key], [])
|
977
|
-
:
|
992
|
+
: { ...markFieldsDirty(data[key]) };
|
978
993
|
}
|
979
994
|
else {
|
980
995
|
getDirtyFieldsFromDefaultValues(data[key], isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
|
@@ -1184,8 +1199,12 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1184
1199
|
const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
|
1185
1200
|
const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
|
1186
1201
|
const message = exceedMax ? maxLengthMessage : minLengthMessage;
|
1187
|
-
error[name] =
|
1188
|
-
|
1202
|
+
error[name] = {
|
1203
|
+
type: exceedMax ? maxType : minType,
|
1204
|
+
message,
|
1205
|
+
ref,
|
1206
|
+
...appendErrorsCurry(exceedMax ? maxType : minType, message),
|
1207
|
+
};
|
1189
1208
|
};
|
1190
1209
|
if (required &&
|
1191
1210
|
((!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue))) ||
|
@@ -1196,7 +1215,12 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1196
1215
|
? { value: !!required, message: required }
|
1197
1216
|
: getValueAndMessage(required);
|
1198
1217
|
if (value) {
|
1199
|
-
error[name] =
|
1218
|
+
error[name] = {
|
1219
|
+
type: INPUT_VALIDATION_RULES.required,
|
1220
|
+
message,
|
1221
|
+
ref: inputRef,
|
1222
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message),
|
1223
|
+
};
|
1200
1224
|
if (!validateAllFieldCriteria) {
|
1201
1225
|
setCustomValidity(message);
|
1202
1226
|
return error;
|
@@ -1252,8 +1276,12 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1252
1276
|
if (pattern && !isEmpty && isString(inputValue)) {
|
1253
1277
|
const { value: patternValue, message } = getValueAndMessage(pattern);
|
1254
1278
|
if (isRegex(patternValue) && !inputValue.match(patternValue)) {
|
1255
|
-
error[name] =
|
1256
|
-
|
1279
|
+
error[name] = {
|
1280
|
+
type: INPUT_VALIDATION_RULES.pattern,
|
1281
|
+
message,
|
1282
|
+
ref,
|
1283
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message),
|
1284
|
+
};
|
1257
1285
|
if (!validateAllFieldCriteria) {
|
1258
1286
|
setCustomValidity(message);
|
1259
1287
|
return error;
|
@@ -1265,7 +1293,10 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1265
1293
|
const result = await validate(inputValue);
|
1266
1294
|
const validateError = getValidateError(result, inputRef);
|
1267
1295
|
if (validateError) {
|
1268
|
-
error[name] =
|
1296
|
+
error[name] = {
|
1297
|
+
...validateError,
|
1298
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message),
|
1299
|
+
};
|
1269
1300
|
if (!validateAllFieldCriteria) {
|
1270
1301
|
setCustomValidity(validateError.message);
|
1271
1302
|
return error;
|
@@ -1280,7 +1311,10 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1280
1311
|
}
|
1281
1312
|
const validateError = getValidateError(await validate[key](inputValue), inputRef, key);
|
1282
1313
|
if (validateError) {
|
1283
|
-
validationResult =
|
1314
|
+
validationResult = {
|
1315
|
+
...validateError,
|
1316
|
+
...appendErrorsCurry(key, validateError.message),
|
1317
|
+
};
|
1284
1318
|
setCustomValidity(validateError.message);
|
1285
1319
|
if (validateAllFieldCriteria) {
|
1286
1320
|
error[name] = validationResult;
|
@@ -1288,7 +1322,10 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1288
1322
|
}
|
1289
1323
|
}
|
1290
1324
|
if (!isEmptyObject(validationResult)) {
|
1291
|
-
error[name] =
|
1325
|
+
error[name] = {
|
1326
|
+
ref: inputRef,
|
1327
|
+
...validationResult,
|
1328
|
+
};
|
1292
1329
|
if (!validateAllFieldCriteria) {
|
1293
1330
|
return error;
|
1294
1331
|
}
|
@@ -1305,7 +1342,10 @@ const defaultOptions = {
|
|
1305
1342
|
shouldFocusError: true,
|
1306
1343
|
};
|
1307
1344
|
function createFormControl(props = {}) {
|
1308
|
-
let _options =
|
1345
|
+
let _options = {
|
1346
|
+
...defaultOptions,
|
1347
|
+
...props,
|
1348
|
+
};
|
1309
1349
|
let _formState = {
|
1310
1350
|
isDirty: false,
|
1311
1351
|
isValidating: false,
|
@@ -1319,7 +1359,7 @@ function createFormControl(props = {}) {
|
|
1319
1359
|
errors: {},
|
1320
1360
|
};
|
1321
1361
|
let _fields = {};
|
1322
|
-
let _defaultValues = _options.defaultValues || {};
|
1362
|
+
let _defaultValues = cloneObject(_options.defaultValues) || {};
|
1323
1363
|
let _formValues = _options.shouldUnregister
|
1324
1364
|
? {}
|
1325
1365
|
: cloneObject(_defaultValues);
|
@@ -1372,21 +1412,22 @@ function createFormControl(props = {}) {
|
|
1372
1412
|
}
|
1373
1413
|
return isValid;
|
1374
1414
|
};
|
1375
|
-
const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true,
|
1415
|
+
const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
1376
1416
|
if (args && method) {
|
1377
1417
|
_stateFlags.action = true;
|
1378
|
-
if (
|
1418
|
+
if (shouldUpdateFieldsAndState && Array.isArray(get(_fields, name))) {
|
1379
1419
|
const fieldValues = method(get(_fields, name), args.argA, args.argB);
|
1380
1420
|
shouldSetValues && set(_fields, name, fieldValues);
|
1381
1421
|
}
|
1382
1422
|
if (_proxyFormState.errors &&
|
1383
|
-
|
1423
|
+
shouldUpdateFieldsAndState &&
|
1384
1424
|
Array.isArray(get(_formState.errors, name))) {
|
1385
1425
|
const errors = method(get(_formState.errors, name), args.argA, args.argB);
|
1386
1426
|
shouldSetValues && set(_formState.errors, name, errors);
|
1387
1427
|
unsetEmptyArray(_formState.errors, name);
|
1388
1428
|
}
|
1389
1429
|
if (_proxyFormState.touchedFields &&
|
1430
|
+
shouldUpdateFieldsAndState &&
|
1390
1431
|
Array.isArray(get(_formState.touchedFields, name))) {
|
1391
1432
|
const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
|
1392
1433
|
shouldSetValues && set(_formState.touchedFields, name, touchedFields);
|
@@ -1472,8 +1513,16 @@ function createFormControl(props = {}) {
|
|
1472
1513
|
!isEmptyObject(fieldState) ||
|
1473
1514
|
shouldUpdateValid) &&
|
1474
1515
|
!shouldSkipRender) {
|
1475
|
-
const updatedFormState =
|
1476
|
-
|
1516
|
+
const updatedFormState = {
|
1517
|
+
...fieldState,
|
1518
|
+
...(shouldUpdateValid ? { isValid } : {}),
|
1519
|
+
errors: _formState.errors,
|
1520
|
+
name,
|
1521
|
+
};
|
1522
|
+
_formState = {
|
1523
|
+
..._formState,
|
1524
|
+
...updatedFormState,
|
1525
|
+
};
|
1477
1526
|
_subjects.state.next(updatedFormState);
|
1478
1527
|
}
|
1479
1528
|
validateFields[name]--;
|
@@ -1486,7 +1535,7 @@ function createFormControl(props = {}) {
|
|
1486
1535
|
}
|
1487
1536
|
};
|
1488
1537
|
const _executeSchema = async (name) => _options.resolver
|
1489
|
-
? await _options.resolver(
|
1538
|
+
? await _options.resolver({ ..._formValues }, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation))
|
1490
1539
|
: {};
|
1491
1540
|
const executeSchemaAndUpdateState = async (names) => {
|
1492
1541
|
const { errors } = await _executeSchema();
|
@@ -1509,8 +1558,7 @@ function createFormControl(props = {}) {
|
|
1509
1558
|
for (const name in fields) {
|
1510
1559
|
const field = fields[name];
|
1511
1560
|
if (field) {
|
1512
|
-
const fieldReference = field
|
1513
|
-
const fieldValue = omit(field, '_f');
|
1561
|
+
const { _f: fieldReference, ...fieldValue } = field;
|
1514
1562
|
if (fieldReference) {
|
1515
1563
|
const fieldError = await validateField(field, get(_formValues, fieldReference.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation);
|
1516
1564
|
if (fieldError[fieldReference.name]) {
|
@@ -1545,13 +1593,15 @@ function createFormControl(props = {}) {
|
|
1545
1593
|
const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
|
1546
1594
|
!deepEqual(getValues(), _defaultValues));
|
1547
1595
|
const _getWatch = (names, defaultValue, isGlobal) => {
|
1548
|
-
const fieldValues =
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1596
|
+
const fieldValues = {
|
1597
|
+
...(_stateFlags.mount
|
1598
|
+
? _formValues
|
1599
|
+
: isUndefined(defaultValue)
|
1600
|
+
? _defaultValues
|
1601
|
+
: isString(names)
|
1602
|
+
? { [names]: defaultValue }
|
1603
|
+
: defaultValue),
|
1604
|
+
};
|
1555
1605
|
return generateWatchOutput(names, _names, fieldValues, isGlobal);
|
1556
1606
|
};
|
1557
1607
|
const _getFieldArray = (name) => compact(get(_stateFlags.mount ? _formValues : _defaultValues, name, props.shouldUnregister ? get(_defaultValues, name, []) : []));
|
@@ -1573,9 +1623,10 @@ function createFormControl(props = {}) {
|
|
1573
1623
|
else if (fieldReference.refs) {
|
1574
1624
|
if (isCheckBoxInput(fieldReference.ref)) {
|
1575
1625
|
fieldReference.refs.length > 1
|
1576
|
-
? fieldReference.refs.forEach((checkboxRef) =>
|
1577
|
-
|
1578
|
-
|
1626
|
+
? fieldReference.refs.forEach((checkboxRef) => !checkboxRef.disabled &&
|
1627
|
+
(checkboxRef.checked = Array.isArray(fieldValue)
|
1628
|
+
? !!fieldValue.find((data) => data === checkboxRef.value)
|
1629
|
+
: fieldValue === checkboxRef.value))
|
1579
1630
|
: fieldReference.refs[0] &&
|
1580
1631
|
(fieldReference.refs[0].checked = !!fieldValue);
|
1581
1632
|
}
|
@@ -1676,7 +1727,7 @@ function createFormControl(props = {}) {
|
|
1676
1727
|
});
|
1677
1728
|
if (shouldSkipValidation) {
|
1678
1729
|
return (shouldRender &&
|
1679
|
-
_subjects.state.next(
|
1730
|
+
_subjects.state.next({ name, ...(watched ? {} : fieldState) }));
|
1680
1731
|
}
|
1681
1732
|
!isBlurEvent && watched && _subjects.state.next({});
|
1682
1733
|
validateFields[name] = validateFields[name] ? +1 : 1;
|
@@ -1695,7 +1746,8 @@ function createFormControl(props = {}) {
|
|
1695
1746
|
error = (await validateField(field, get(_formValues, name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
|
1696
1747
|
isValid = await _updateValid(true);
|
1697
1748
|
}
|
1698
|
-
field._f.deps &&
|
1749
|
+
field._f.deps &&
|
1750
|
+
trigger(field._f.deps);
|
1699
1751
|
shouldRenderByError(false, name, isValid, error, fieldState);
|
1700
1752
|
}
|
1701
1753
|
};
|
@@ -1723,17 +1775,25 @@ function createFormControl(props = {}) {
|
|
1723
1775
|
else {
|
1724
1776
|
validationResult = isValid = await executeBuildInValidation(_fields);
|
1725
1777
|
}
|
1726
|
-
_subjects.state.next(
|
1727
|
-
(
|
1728
|
-
|
1729
|
-
|
1778
|
+
_subjects.state.next({
|
1779
|
+
...(!isString(name) ||
|
1780
|
+
(_proxyFormState.isValid && isValid !== _formState.isValid)
|
1781
|
+
? {}
|
1782
|
+
: { name }),
|
1783
|
+
...(_options.resolver ? { isValid } : {}),
|
1784
|
+
errors: _formState.errors,
|
1785
|
+
isValidating: false,
|
1786
|
+
});
|
1730
1787
|
options.shouldFocus &&
|
1731
1788
|
!validationResult &&
|
1732
1789
|
focusFieldBy(_fields, (key) => get(_formState.errors, key), name ? fieldNames : _names.mount);
|
1733
1790
|
return validationResult;
|
1734
1791
|
};
|
1735
1792
|
const getValues = (fieldNames) => {
|
1736
|
-
const values =
|
1793
|
+
const values = {
|
1794
|
+
..._defaultValues,
|
1795
|
+
...(_stateFlags.mount ? _formValues : {}),
|
1796
|
+
};
|
1737
1797
|
return isUndefined(fieldNames)
|
1738
1798
|
? values
|
1739
1799
|
: isString(fieldNames)
|
@@ -1756,7 +1816,10 @@ function createFormControl(props = {}) {
|
|
1756
1816
|
};
|
1757
1817
|
const setError = (name, error, options) => {
|
1758
1818
|
const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
|
1759
|
-
set(_formState.errors, name,
|
1819
|
+
set(_formState.errors, name, {
|
1820
|
+
...error,
|
1821
|
+
ref,
|
1822
|
+
});
|
1760
1823
|
_subjects.state.next({
|
1761
1824
|
name,
|
1762
1825
|
errors: _formState.errors,
|
@@ -1787,14 +1850,22 @@ function createFormControl(props = {}) {
|
|
1787
1850
|
}
|
1788
1851
|
}
|
1789
1852
|
_subjects.watch.next({});
|
1790
|
-
_subjects.state.next(
|
1853
|
+
_subjects.state.next({
|
1854
|
+
..._formState,
|
1855
|
+
...(!options.keepDirty ? {} : { isDirty: _getDirty() }),
|
1856
|
+
});
|
1791
1857
|
_proxyFormState.isValid && _updateValid();
|
1792
1858
|
};
|
1793
1859
|
const register = (name, options = {}) => {
|
1794
1860
|
let field = get(_fields, name);
|
1795
1861
|
const disabledIsDefined = isBoolean(options.disabled);
|
1796
1862
|
set(_fields, name, {
|
1797
|
-
_f:
|
1863
|
+
_f: {
|
1864
|
+
...(field && field._f ? field._f : { ref: { name } }),
|
1865
|
+
name,
|
1866
|
+
mount: true,
|
1867
|
+
...options,
|
1868
|
+
},
|
1798
1869
|
});
|
1799
1870
|
_names.mount.add(name);
|
1800
1871
|
field
|
@@ -1803,17 +1874,22 @@ function createFormControl(props = {}) {
|
|
1803
1874
|
? undefined
|
1804
1875
|
: get(_formValues, name, getFieldValue(field._f)))
|
1805
1876
|
: updateValidAndValue(name, true, options.value);
|
1806
|
-
return
|
1807
|
-
? {
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1877
|
+
return {
|
1878
|
+
...(disabledIsDefined ? { disabled: options.disabled } : {}),
|
1879
|
+
...(_options.shouldUseNativeValidation
|
1880
|
+
? {
|
1881
|
+
required: !!options.required,
|
1882
|
+
min: getRuleValue(options.min),
|
1883
|
+
max: getRuleValue(options.max),
|
1884
|
+
minLength: getRuleValue(options.minLength),
|
1885
|
+
maxLength: getRuleValue(options.maxLength),
|
1886
|
+
pattern: getRuleValue(options.pattern),
|
1887
|
+
}
|
1888
|
+
: {}),
|
1889
|
+
name,
|
1890
|
+
onChange,
|
1891
|
+
onBlur: onChange,
|
1892
|
+
ref: (ref) => {
|
1817
1893
|
if (ref) {
|
1818
1894
|
register(name, options);
|
1819
1895
|
field = get(_fields, name);
|
@@ -1830,12 +1906,15 @@ function createFormControl(props = {}) {
|
|
1830
1906
|
return;
|
1831
1907
|
}
|
1832
1908
|
set(_fields, name, {
|
1833
|
-
_f:
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1909
|
+
_f: {
|
1910
|
+
...field._f,
|
1911
|
+
...(radioOrCheckbox
|
1912
|
+
? {
|
1913
|
+
refs: [...refs.filter(live), fieldRef],
|
1914
|
+
ref: { type: fieldRef.type, name },
|
1915
|
+
}
|
1916
|
+
: { ref: fieldRef }),
|
1917
|
+
},
|
1839
1918
|
});
|
1840
1919
|
updateValidAndValue(name, false, undefined, fieldRef);
|
1841
1920
|
}
|
@@ -1848,7 +1927,8 @@ function createFormControl(props = {}) {
|
|
1848
1927
|
!(isNameInFieldArray(_names.array, name) && _stateFlags.action) &&
|
1849
1928
|
_names.unMount.add(name);
|
1850
1929
|
}
|
1851
|
-
}
|
1930
|
+
},
|
1931
|
+
};
|
1852
1932
|
};
|
1853
1933
|
const handleSubmit = (onValid, onInvalid) => async (e) => {
|
1854
1934
|
if (e) {
|
@@ -1879,7 +1959,7 @@ function createFormControl(props = {}) {
|
|
1879
1959
|
}
|
1880
1960
|
else {
|
1881
1961
|
if (onInvalid) {
|
1882
|
-
await onInvalid(
|
1962
|
+
await onInvalid({ ..._formState.errors }, e);
|
1883
1963
|
}
|
1884
1964
|
_options.shouldFocusError &&
|
1885
1965
|
focusFieldBy(_fields, (key) => get(_formState.errors, key), _names.mount);
|
@@ -1922,7 +2002,7 @@ function createFormControl(props = {}) {
|
|
1922
2002
|
unset(_formState.errors, name);
|
1923
2003
|
_proxyFormState.isValid && _updateValid();
|
1924
2004
|
}
|
1925
|
-
_subjects.state.next(
|
2005
|
+
_subjects.state.next({ ..._formState });
|
1926
2006
|
}
|
1927
2007
|
};
|
1928
2008
|
const reset = (formValues, keepStateOptions = {}) => {
|
@@ -1973,7 +2053,10 @@ function createFormControl(props = {}) {
|
|
1973
2053
|
dirtyFields: keepStateOptions.keepDirty
|
1974
2054
|
? _formState.dirtyFields
|
1975
2055
|
: (keepStateOptions.keepDefaultValues && formValues
|
1976
|
-
? Object.entries(formValues).reduce((previous, [key, value]) => (
|
2056
|
+
? Object.entries(formValues).reduce((previous, [key, value]) => ({
|
2057
|
+
...previous,
|
2058
|
+
[key]: value !== get(_defaultValues, key),
|
2059
|
+
}), {})
|
1977
2060
|
: {}),
|
1978
2061
|
touchedFields: keepStateOptions.keepTouched
|
1979
2062
|
? _formState.touchedFields
|
@@ -2035,7 +2118,10 @@ function createFormControl(props = {}) {
|
|
2035
2118
|
return _options;
|
2036
2119
|
},
|
2037
2120
|
set _options(value) {
|
2038
|
-
_options =
|
2121
|
+
_options = {
|
2122
|
+
..._options,
|
2123
|
+
...value,
|
2124
|
+
};
|
2039
2125
|
},
|
2040
2126
|
},
|
2041
2127
|
trigger,
|
@@ -2101,13 +2187,19 @@ function useForm(props = {}) {
|
|
2101
2187
|
_formControl.current.control._options = props;
|
2102
2188
|
}
|
2103
2189
|
else {
|
2104
|
-
_formControl.current =
|
2190
|
+
_formControl.current = {
|
2191
|
+
...createFormControl(props),
|
2192
|
+
formState,
|
2193
|
+
};
|
2105
2194
|
}
|
2106
2195
|
const control = _formControl.current.control;
|
2107
2196
|
const callback = React.useCallback((value) => {
|
2108
2197
|
if (shouldRenderFormState(value, control._proxyFormState, true)) {
|
2109
|
-
control._formState =
|
2110
|
-
|
2198
|
+
control._formState = {
|
2199
|
+
...control._formState,
|
2200
|
+
...value,
|
2201
|
+
};
|
2202
|
+
updateFormState({ ...control._formState });
|
2111
2203
|
}
|
2112
2204
|
}, [control]);
|
2113
2205
|
useSubscribe({
|