react-hook-form 7.28.1 → 7.31.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 +10 -3
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +250 -152
- 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/getNodeParentName.d.ts.map +1 -1
- package/dist/logic/isNameInFieldArray.d.ts.map +1 -1
- package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
- package/dist/types/controller.d.ts +6 -0
- package/dist/types/controller.d.ts.map +1 -1
- package/dist/types/form.d.ts +7 -0
- package/dist/types/form.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useFormContext.d.ts.map +1 -1
- package/dist/utils/cloneObject.d.ts.map +1 -1
- package/dist/utils/compact.d.ts.map +1 -1
- package/package.json +19 -15
- package/dist/utils/omitKeys.d.ts +0 -3
- package/dist/utils/omitKeys.d.ts.map +0 -1
package/dist/index.esm.mjs
CHANGED
@@ -18,11 +18,11 @@ var getEventValue = (event) => isObject(event) && event.target
|
|
18
18
|
: event.target.value
|
19
19
|
: event;
|
20
20
|
|
21
|
-
var getNodeParentName = (name) => name.substring(0, name.search(
|
21
|
+
var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
|
22
22
|
|
23
|
-
var isNameInFieldArray = (names, name) =>
|
23
|
+
var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
|
24
24
|
|
25
|
-
var compact = (value) => value.filter(Boolean);
|
25
|
+
var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
|
26
26
|
|
27
27
|
var isUndefined = (val) => val === undefined;
|
28
28
|
|
@@ -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
|
}
|
@@ -298,11 +301,12 @@ function useWatch(props) {
|
|
298
301
|
const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
|
299
302
|
updateValue(isUndefined(_name.current) ||
|
300
303
|
(isObject(fieldValues) && !objectHasFunction(fieldValues))
|
301
|
-
?
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
304
|
+
? { ...fieldValues }
|
305
|
+
: Array.isArray(fieldValues)
|
306
|
+
? [...fieldValues]
|
307
|
+
: isUndefined(fieldValues)
|
308
|
+
? defaultValue
|
309
|
+
: fieldValues);
|
306
310
|
}
|
307
311
|
}, [control, exact, defaultValue]);
|
308
312
|
useSubscribe({
|
@@ -357,7 +361,10 @@ function useController(props) {
|
|
357
361
|
control,
|
358
362
|
name,
|
359
363
|
});
|
360
|
-
const _registerProps = React.useRef(control.register(name,
|
364
|
+
const _registerProps = React.useRef(control.register(name, {
|
365
|
+
...props.rules,
|
366
|
+
value,
|
367
|
+
}));
|
361
368
|
React.useEffect(() => {
|
362
369
|
const updateMounted = (name, value) => {
|
363
370
|
const field = get(control._fields, name);
|
@@ -458,7 +465,14 @@ function useController(props) {
|
|
458
465
|
const Controller = (props) => props.render(useController(props));
|
459
466
|
|
460
467
|
var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
|
461
|
-
?
|
468
|
+
? {
|
469
|
+
...errors[name],
|
470
|
+
types: {
|
471
|
+
...(errors[name] && errors[name].types ? errors[name].types : {}),
|
472
|
+
[type]: message || true,
|
473
|
+
},
|
474
|
+
}
|
475
|
+
: {};
|
462
476
|
|
463
477
|
var isKey = (value) => /^\w*$/.test(value);
|
464
478
|
|
@@ -491,8 +505,7 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
|
|
491
505
|
for (const key of fieldsNames || Object.keys(fields)) {
|
492
506
|
const field = get(fields, key);
|
493
507
|
if (field) {
|
494
|
-
const _f = field
|
495
|
-
const current = omit(field, '_f');
|
508
|
+
const { _f, ...currentField } = field;
|
496
509
|
if (_f && callback(_f.name)) {
|
497
510
|
if (_f.ref.focus && isUndefined(_f.ref.focus())) {
|
498
511
|
break;
|
@@ -502,8 +515,8 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
|
|
502
515
|
break;
|
503
516
|
}
|
504
517
|
}
|
505
|
-
else if (isObject(
|
506
|
-
focusFieldBy(
|
518
|
+
else if (isObject(currentField)) {
|
519
|
+
focusFieldBy(currentField, callback);
|
507
520
|
}
|
508
521
|
}
|
509
522
|
}
|
@@ -544,11 +557,7 @@ function cloneObject(data) {
|
|
544
557
|
else if (isArray || isObject(data)) {
|
545
558
|
copy = isArray ? [] : {};
|
546
559
|
for (const key in data) {
|
547
|
-
|
548
|
-
copy = data;
|
549
|
-
break;
|
550
|
-
}
|
551
|
-
copy[key] = cloneObject(data[key]);
|
560
|
+
copy[key] = isFunction(data[key]) ? data[key] : cloneObject(data[key]);
|
552
561
|
}
|
553
562
|
}
|
554
563
|
else {
|
@@ -599,6 +608,45 @@ var swapArrayAt = (data, indexA, indexB) => {
|
|
599
608
|
data[indexA] = [data[indexB], (data[indexB] = data[indexA])][0];
|
600
609
|
};
|
601
610
|
|
611
|
+
function baseGet(object, updatePath) {
|
612
|
+
const length = updatePath.slice(0, -1).length;
|
613
|
+
let index = 0;
|
614
|
+
while (index < length) {
|
615
|
+
object = isUndefined(object) ? index++ : object[updatePath[index++]];
|
616
|
+
}
|
617
|
+
return object;
|
618
|
+
}
|
619
|
+
function unset(object, path) {
|
620
|
+
const updatePath = isKey(path) ? [path] : stringToPath(path);
|
621
|
+
const childObject = updatePath.length == 1 ? object : baseGet(object, updatePath);
|
622
|
+
const key = updatePath[updatePath.length - 1];
|
623
|
+
let previousObjRef;
|
624
|
+
if (childObject) {
|
625
|
+
delete childObject[key];
|
626
|
+
}
|
627
|
+
for (let k = 0; k < updatePath.slice(0, -1).length; k++) {
|
628
|
+
let index = -1;
|
629
|
+
let objectRef;
|
630
|
+
const currentPaths = updatePath.slice(0, -(k + 1));
|
631
|
+
const currentPathsLength = currentPaths.length - 1;
|
632
|
+
if (k > 0) {
|
633
|
+
previousObjRef = object;
|
634
|
+
}
|
635
|
+
while (++index < currentPaths.length) {
|
636
|
+
const item = currentPaths[index];
|
637
|
+
objectRef = objectRef ? objectRef[item] : object[item];
|
638
|
+
if (currentPathsLength === index &&
|
639
|
+
((isObject(objectRef) && isEmptyObject(objectRef)) ||
|
640
|
+
(Array.isArray(objectRef) &&
|
641
|
+
!objectRef.filter((data) => !isUndefined(data)).length))) {
|
642
|
+
previousObjRef ? delete previousObjRef[item] : delete object[item];
|
643
|
+
}
|
644
|
+
previousObjRef = objectRef;
|
645
|
+
}
|
646
|
+
}
|
647
|
+
return object;
|
648
|
+
}
|
649
|
+
|
602
650
|
var updateAt = (fieldValues, index, value) => {
|
603
651
|
fieldValues[index] = value;
|
604
652
|
return fieldValues;
|
@@ -756,8 +804,11 @@ function useFieldArray(props) {
|
|
756
804
|
if (_actioned.current) {
|
757
805
|
control._executeSchema([name]).then((result) => {
|
758
806
|
const error = get(result.errors, name);
|
759
|
-
|
760
|
-
|
807
|
+
const existingError = get(control._formState.errors, name);
|
808
|
+
if (existingError ? !error && existingError.type : error && error.type) {
|
809
|
+
error
|
810
|
+
? set(control._formState.errors, name, error)
|
811
|
+
: unset(control._formState.errors, name);
|
761
812
|
control._subjects.state.next({
|
762
813
|
errors: control._formState.errors,
|
763
814
|
});
|
@@ -789,7 +840,10 @@ function useFieldArray(props) {
|
|
789
840
|
insert: React.useCallback(insert$1, [updateValues, name, control]),
|
790
841
|
update: React.useCallback(update, [updateValues, name, control]),
|
791
842
|
replace: React.useCallback(replace, [updateValues, name, control]),
|
792
|
-
fields: React.useMemo(() => fields.map((field, index) => (
|
843
|
+
fields: React.useMemo(() => fields.map((field, index) => ({
|
844
|
+
...field,
|
845
|
+
[keyName]: ids.current[index] || generateId(),
|
846
|
+
})), [fields, keyName]),
|
793
847
|
};
|
794
848
|
}
|
795
849
|
|
@@ -880,45 +934,6 @@ var isWeb = typeof window !== 'undefined' &&
|
|
880
934
|
|
881
935
|
var live = (ref) => isHTMLElement(ref) && ref.isConnected;
|
882
936
|
|
883
|
-
function baseGet(object, updatePath) {
|
884
|
-
const length = updatePath.slice(0, -1).length;
|
885
|
-
let index = 0;
|
886
|
-
while (index < length) {
|
887
|
-
object = isUndefined(object) ? index++ : object[updatePath[index++]];
|
888
|
-
}
|
889
|
-
return object;
|
890
|
-
}
|
891
|
-
function unset(object, path) {
|
892
|
-
const updatePath = isKey(path) ? [path] : stringToPath(path);
|
893
|
-
const childObject = updatePath.length == 1 ? object : baseGet(object, updatePath);
|
894
|
-
const key = updatePath[updatePath.length - 1];
|
895
|
-
let previousObjRef;
|
896
|
-
if (childObject) {
|
897
|
-
delete childObject[key];
|
898
|
-
}
|
899
|
-
for (let k = 0; k < updatePath.slice(0, -1).length; k++) {
|
900
|
-
let index = -1;
|
901
|
-
let objectRef;
|
902
|
-
const currentPaths = updatePath.slice(0, -(k + 1));
|
903
|
-
const currentPathsLength = currentPaths.length - 1;
|
904
|
-
if (k > 0) {
|
905
|
-
previousObjRef = object;
|
906
|
-
}
|
907
|
-
while (++index < currentPaths.length) {
|
908
|
-
const item = currentPaths[index];
|
909
|
-
objectRef = objectRef ? objectRef[item] : object[item];
|
910
|
-
if (currentPathsLength === index &&
|
911
|
-
((isObject(objectRef) && isEmptyObject(objectRef)) ||
|
912
|
-
(Array.isArray(objectRef) &&
|
913
|
-
!objectRef.filter((data) => !isUndefined(data)).length))) {
|
914
|
-
previousObjRef ? delete previousObjRef[item] : delete object[item];
|
915
|
-
}
|
916
|
-
previousObjRef = objectRef;
|
917
|
-
}
|
918
|
-
}
|
919
|
-
return object;
|
920
|
-
}
|
921
|
-
|
922
937
|
function markFieldsDirty(data, fields = {}) {
|
923
938
|
const isParentNodeArray = Array.isArray(data);
|
924
939
|
if (isObject(data) || isParentNodeArray) {
|
@@ -945,7 +960,7 @@ function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues
|
|
945
960
|
isPrimitive(dirtyFieldsFromValues[key])) {
|
946
961
|
dirtyFieldsFromValues[key] = Array.isArray(data[key])
|
947
962
|
? markFieldsDirty(data[key], [])
|
948
|
-
:
|
963
|
+
: { ...markFieldsDirty(data[key]) };
|
949
964
|
}
|
950
965
|
else {
|
951
966
|
getDirtyFieldsFromDefaultValues(data[key], isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
|
@@ -1155,8 +1170,12 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1155
1170
|
const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
|
1156
1171
|
const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
|
1157
1172
|
const message = exceedMax ? maxLengthMessage : minLengthMessage;
|
1158
|
-
error[name] =
|
1159
|
-
|
1173
|
+
error[name] = {
|
1174
|
+
type: exceedMax ? maxType : minType,
|
1175
|
+
message,
|
1176
|
+
ref,
|
1177
|
+
...appendErrorsCurry(exceedMax ? maxType : minType, message),
|
1178
|
+
};
|
1160
1179
|
};
|
1161
1180
|
if (required &&
|
1162
1181
|
((!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue))) ||
|
@@ -1167,7 +1186,12 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1167
1186
|
? { value: !!required, message: required }
|
1168
1187
|
: getValueAndMessage(required);
|
1169
1188
|
if (value) {
|
1170
|
-
error[name] =
|
1189
|
+
error[name] = {
|
1190
|
+
type: INPUT_VALIDATION_RULES.required,
|
1191
|
+
message,
|
1192
|
+
ref: inputRef,
|
1193
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message),
|
1194
|
+
};
|
1171
1195
|
if (!validateAllFieldCriteria) {
|
1172
1196
|
setCustomValidity(message);
|
1173
1197
|
return error;
|
@@ -1223,8 +1247,12 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1223
1247
|
if (pattern && !isEmpty && isString(inputValue)) {
|
1224
1248
|
const { value: patternValue, message } = getValueAndMessage(pattern);
|
1225
1249
|
if (isRegex(patternValue) && !inputValue.match(patternValue)) {
|
1226
|
-
error[name] =
|
1227
|
-
|
1250
|
+
error[name] = {
|
1251
|
+
type: INPUT_VALIDATION_RULES.pattern,
|
1252
|
+
message,
|
1253
|
+
ref,
|
1254
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message),
|
1255
|
+
};
|
1228
1256
|
if (!validateAllFieldCriteria) {
|
1229
1257
|
setCustomValidity(message);
|
1230
1258
|
return error;
|
@@ -1236,7 +1264,10 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1236
1264
|
const result = await validate(inputValue);
|
1237
1265
|
const validateError = getValidateError(result, inputRef);
|
1238
1266
|
if (validateError) {
|
1239
|
-
error[name] =
|
1267
|
+
error[name] = {
|
1268
|
+
...validateError,
|
1269
|
+
...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message),
|
1270
|
+
};
|
1240
1271
|
if (!validateAllFieldCriteria) {
|
1241
1272
|
setCustomValidity(validateError.message);
|
1242
1273
|
return error;
|
@@ -1251,7 +1282,10 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1251
1282
|
}
|
1252
1283
|
const validateError = getValidateError(await validate[key](inputValue), inputRef, key);
|
1253
1284
|
if (validateError) {
|
1254
|
-
validationResult =
|
1285
|
+
validationResult = {
|
1286
|
+
...validateError,
|
1287
|
+
...appendErrorsCurry(key, validateError.message),
|
1288
|
+
};
|
1255
1289
|
setCustomValidity(validateError.message);
|
1256
1290
|
if (validateAllFieldCriteria) {
|
1257
1291
|
error[name] = validationResult;
|
@@ -1259,7 +1293,10 @@ var validateField = async (field, inputValue, validateAllFieldCriteria, shouldUs
|
|
1259
1293
|
}
|
1260
1294
|
}
|
1261
1295
|
if (!isEmptyObject(validationResult)) {
|
1262
|
-
error[name] =
|
1296
|
+
error[name] = {
|
1297
|
+
ref: inputRef,
|
1298
|
+
...validationResult,
|
1299
|
+
};
|
1263
1300
|
if (!validateAllFieldCriteria) {
|
1264
1301
|
return error;
|
1265
1302
|
}
|
@@ -1276,7 +1313,10 @@ const defaultOptions = {
|
|
1276
1313
|
shouldFocusError: true,
|
1277
1314
|
};
|
1278
1315
|
function createFormControl(props = {}) {
|
1279
|
-
let _options =
|
1316
|
+
let _options = {
|
1317
|
+
...defaultOptions,
|
1318
|
+
...props,
|
1319
|
+
};
|
1280
1320
|
let _formState = {
|
1281
1321
|
isDirty: false,
|
1282
1322
|
isValidating: false,
|
@@ -1290,7 +1330,7 @@ function createFormControl(props = {}) {
|
|
1290
1330
|
errors: {},
|
1291
1331
|
};
|
1292
1332
|
let _fields = {};
|
1293
|
-
let _defaultValues = _options.defaultValues || {};
|
1333
|
+
let _defaultValues = cloneObject(_options.defaultValues) || {};
|
1294
1334
|
let _formValues = _options.shouldUnregister
|
1295
1335
|
? {}
|
1296
1336
|
: cloneObject(_defaultValues);
|
@@ -1444,8 +1484,16 @@ function createFormControl(props = {}) {
|
|
1444
1484
|
!isEmptyObject(fieldState) ||
|
1445
1485
|
shouldUpdateValid) &&
|
1446
1486
|
!shouldSkipRender) {
|
1447
|
-
const updatedFormState =
|
1448
|
-
|
1487
|
+
const updatedFormState = {
|
1488
|
+
...fieldState,
|
1489
|
+
...(shouldUpdateValid ? { isValid } : {}),
|
1490
|
+
errors: _formState.errors,
|
1491
|
+
name,
|
1492
|
+
};
|
1493
|
+
_formState = {
|
1494
|
+
..._formState,
|
1495
|
+
...updatedFormState,
|
1496
|
+
};
|
1449
1497
|
_subjects.state.next(updatedFormState);
|
1450
1498
|
}
|
1451
1499
|
validateFields[name]--;
|
@@ -1458,7 +1506,7 @@ function createFormControl(props = {}) {
|
|
1458
1506
|
}
|
1459
1507
|
};
|
1460
1508
|
const _executeSchema = async (name) => _options.resolver
|
1461
|
-
? await _options.resolver(
|
1509
|
+
? await _options.resolver({ ..._formValues }, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation))
|
1462
1510
|
: {};
|
1463
1511
|
const executeSchemaAndUpdateState = async (names) => {
|
1464
1512
|
const { errors } = await _executeSchema();
|
@@ -1481,8 +1529,7 @@ function createFormControl(props = {}) {
|
|
1481
1529
|
for (const name in fields) {
|
1482
1530
|
const field = fields[name];
|
1483
1531
|
if (field) {
|
1484
|
-
const fieldReference = field
|
1485
|
-
const fieldValue = omit(field, '_f');
|
1532
|
+
const { _f: fieldReference, ...fieldValue } = field;
|
1486
1533
|
if (fieldReference) {
|
1487
1534
|
const fieldError = await validateField(field, get(_formValues, fieldReference.name), shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation);
|
1488
1535
|
if (fieldError[fieldReference.name]) {
|
@@ -1517,13 +1564,15 @@ function createFormControl(props = {}) {
|
|
1517
1564
|
const _getDirty = (name, data) => (name && data && set(_formValues, name, data),
|
1518
1565
|
!deepEqual(getValues(), _defaultValues));
|
1519
1566
|
const _getWatch = (names, defaultValue, isGlobal) => {
|
1520
|
-
const fieldValues =
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1567
|
+
const fieldValues = {
|
1568
|
+
...(_stateFlags.mount
|
1569
|
+
? _formValues
|
1570
|
+
: isUndefined(defaultValue)
|
1571
|
+
? _defaultValues
|
1572
|
+
: isString(names)
|
1573
|
+
? { [names]: defaultValue }
|
1574
|
+
: defaultValue),
|
1575
|
+
};
|
1527
1576
|
return generateWatchOutput(names, _names, fieldValues, isGlobal);
|
1528
1577
|
};
|
1529
1578
|
const _getFieldArray = (name) => compact(get(_stateFlags.mount ? _formValues : _defaultValues, name, props.shouldUnregister ? get(_defaultValues, name, []) : []));
|
@@ -1649,7 +1698,7 @@ function createFormControl(props = {}) {
|
|
1649
1698
|
});
|
1650
1699
|
if (shouldSkipValidation) {
|
1651
1700
|
return (shouldRender &&
|
1652
|
-
_subjects.state.next(
|
1701
|
+
_subjects.state.next({ name, ...(watched ? {} : fieldState) }));
|
1653
1702
|
}
|
1654
1703
|
!isBlurEvent && watched && _subjects.state.next({});
|
1655
1704
|
validateFields[name] = validateFields[name] ? +1 : 1;
|
@@ -1697,17 +1746,25 @@ function createFormControl(props = {}) {
|
|
1697
1746
|
else {
|
1698
1747
|
validationResult = isValid = await executeBuildInValidation(_fields);
|
1699
1748
|
}
|
1700
|
-
_subjects.state.next(
|
1701
|
-
(
|
1702
|
-
|
1703
|
-
|
1749
|
+
_subjects.state.next({
|
1750
|
+
...(!isString(name) ||
|
1751
|
+
(_proxyFormState.isValid && isValid !== _formState.isValid)
|
1752
|
+
? {}
|
1753
|
+
: { name }),
|
1754
|
+
...(_options.resolver ? { isValid } : {}),
|
1755
|
+
errors: _formState.errors,
|
1756
|
+
isValidating: false,
|
1757
|
+
});
|
1704
1758
|
options.shouldFocus &&
|
1705
1759
|
!validationResult &&
|
1706
1760
|
focusFieldBy(_fields, (key) => get(_formState.errors, key), name ? fieldNames : _names.mount);
|
1707
1761
|
return validationResult;
|
1708
1762
|
};
|
1709
1763
|
const getValues = (fieldNames) => {
|
1710
|
-
const values =
|
1764
|
+
const values = {
|
1765
|
+
..._defaultValues,
|
1766
|
+
...(_stateFlags.mount ? _formValues : {}),
|
1767
|
+
};
|
1711
1768
|
return isUndefined(fieldNames)
|
1712
1769
|
? values
|
1713
1770
|
: isString(fieldNames)
|
@@ -1730,7 +1787,10 @@ function createFormControl(props = {}) {
|
|
1730
1787
|
};
|
1731
1788
|
const setError = (name, error, options) => {
|
1732
1789
|
const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
|
1733
|
-
set(_formState.errors, name,
|
1790
|
+
set(_formState.errors, name, {
|
1791
|
+
...error,
|
1792
|
+
ref,
|
1793
|
+
});
|
1734
1794
|
_subjects.state.next({
|
1735
1795
|
name,
|
1736
1796
|
errors: _formState.errors,
|
@@ -1761,14 +1821,22 @@ function createFormControl(props = {}) {
|
|
1761
1821
|
}
|
1762
1822
|
}
|
1763
1823
|
_subjects.watch.next({});
|
1764
|
-
_subjects.state.next(
|
1824
|
+
_subjects.state.next({
|
1825
|
+
..._formState,
|
1826
|
+
...(!options.keepDirty ? {} : { isDirty: _getDirty() }),
|
1827
|
+
});
|
1765
1828
|
!options.keepIsValid && _updateValid();
|
1766
1829
|
};
|
1767
1830
|
const register = (name, options = {}) => {
|
1768
1831
|
let field = get(_fields, name);
|
1769
1832
|
const disabledIsDefined = isBoolean(options.disabled);
|
1770
1833
|
set(_fields, name, {
|
1771
|
-
_f:
|
1834
|
+
_f: {
|
1835
|
+
...(field && field._f ? field._f : { ref: { name } }),
|
1836
|
+
name,
|
1837
|
+
mount: true,
|
1838
|
+
...options,
|
1839
|
+
},
|
1772
1840
|
});
|
1773
1841
|
_names.mount.add(name);
|
1774
1842
|
field
|
@@ -1777,17 +1845,22 @@ function createFormControl(props = {}) {
|
|
1777
1845
|
? undefined
|
1778
1846
|
: get(_formValues, name, getFieldValue(field._f)))
|
1779
1847
|
: updateValidAndValue(name, true, options.value);
|
1780
|
-
return
|
1781
|
-
? {
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1848
|
+
return {
|
1849
|
+
...(disabledIsDefined ? { disabled: options.disabled } : {}),
|
1850
|
+
...(_options.shouldUseNativeValidation
|
1851
|
+
? {
|
1852
|
+
required: !!options.required,
|
1853
|
+
min: getRuleValue(options.min),
|
1854
|
+
max: getRuleValue(options.max),
|
1855
|
+
minLength: getRuleValue(options.minLength),
|
1856
|
+
maxLength: getRuleValue(options.maxLength),
|
1857
|
+
pattern: getRuleValue(options.pattern),
|
1858
|
+
}
|
1859
|
+
: {}),
|
1860
|
+
name,
|
1861
|
+
onChange,
|
1862
|
+
onBlur: onChange,
|
1863
|
+
ref: (ref) => {
|
1791
1864
|
if (ref) {
|
1792
1865
|
register(name, options);
|
1793
1866
|
field = get(_fields, name);
|
@@ -1804,12 +1877,21 @@ function createFormControl(props = {}) {
|
|
1804
1877
|
return;
|
1805
1878
|
}
|
1806
1879
|
set(_fields, name, {
|
1807
|
-
_f:
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1880
|
+
_f: {
|
1881
|
+
...field._f,
|
1882
|
+
...(radioOrCheckbox
|
1883
|
+
? {
|
1884
|
+
refs: [
|
1885
|
+
...refs.filter(live),
|
1886
|
+
fieldRef,
|
1887
|
+
...(!!Array.isArray(get(_defaultValues, name))
|
1888
|
+
? [{}]
|
1889
|
+
: []),
|
1890
|
+
],
|
1891
|
+
ref: { type: fieldRef.type, name },
|
1892
|
+
}
|
1893
|
+
: { ref: fieldRef }),
|
1894
|
+
},
|
1813
1895
|
});
|
1814
1896
|
updateValidAndValue(name, false, undefined, fieldRef);
|
1815
1897
|
}
|
@@ -1822,7 +1904,8 @@ function createFormControl(props = {}) {
|
|
1822
1904
|
!(isNameInFieldArray(_names.array, name) && _stateFlags.action) &&
|
1823
1905
|
_names.unMount.add(name);
|
1824
1906
|
}
|
1825
|
-
}
|
1907
|
+
},
|
1908
|
+
};
|
1826
1909
|
};
|
1827
1910
|
const handleSubmit = (onValid, onInvalid) => async (e) => {
|
1828
1911
|
if (e) {
|
@@ -1853,7 +1936,7 @@ function createFormControl(props = {}) {
|
|
1853
1936
|
}
|
1854
1937
|
else {
|
1855
1938
|
if (onInvalid) {
|
1856
|
-
await onInvalid(
|
1939
|
+
await onInvalid({ ..._formState.errors }, e);
|
1857
1940
|
}
|
1858
1941
|
_options.shouldFocusError &&
|
1859
1942
|
focusFieldBy(_fields, (key) => get(_formState.errors, key), _names.mount);
|
@@ -1896,7 +1979,7 @@ function createFormControl(props = {}) {
|
|
1896
1979
|
unset(_formState.errors, name);
|
1897
1980
|
_proxyFormState.isValid && _updateValid();
|
1898
1981
|
}
|
1899
|
-
_subjects.state.next(
|
1982
|
+
_subjects.state.next({ ..._formState });
|
1900
1983
|
}
|
1901
1984
|
};
|
1902
1985
|
const reset = (formValues, keepStateOptions = {}) => {
|
@@ -1909,28 +1992,37 @@ function createFormControl(props = {}) {
|
|
1909
1992
|
_defaultValues = updatedValues;
|
1910
1993
|
}
|
1911
1994
|
if (!keepStateOptions.keepValues) {
|
1912
|
-
if (
|
1913
|
-
for (const
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1995
|
+
if (keepStateOptions.keepDirtyValues) {
|
1996
|
+
for (const fieldName of _names.mount) {
|
1997
|
+
get(_formState.dirtyFields, fieldName)
|
1998
|
+
? set(values, fieldName, get(_formValues, fieldName))
|
1999
|
+
: setValue(fieldName, get(values, fieldName));
|
2000
|
+
}
|
2001
|
+
}
|
2002
|
+
else {
|
2003
|
+
if (isWeb && isUndefined(formValues)) {
|
2004
|
+
for (const name of _names.mount) {
|
2005
|
+
const field = get(_fields, name);
|
2006
|
+
if (field && field._f) {
|
2007
|
+
const fieldReference = Array.isArray(field._f.refs)
|
2008
|
+
? field._f.refs[0]
|
2009
|
+
: field._f.ref;
|
2010
|
+
try {
|
2011
|
+
isHTMLElement(fieldReference) &&
|
2012
|
+
fieldReference.closest('form').reset();
|
2013
|
+
break;
|
2014
|
+
}
|
2015
|
+
catch (_a) { }
|
1923
2016
|
}
|
1924
|
-
catch (_a) { }
|
1925
2017
|
}
|
1926
2018
|
}
|
2019
|
+
_fields = {};
|
1927
2020
|
}
|
1928
2021
|
_formValues = props.shouldUnregister
|
1929
2022
|
? keepStateOptions.keepDefaultValues
|
1930
2023
|
? cloneObject(_defaultValues)
|
1931
2024
|
: {}
|
1932
2025
|
: cloneUpdatedValues;
|
1933
|
-
_fields = {};
|
1934
2026
|
_subjects.array.next({
|
1935
2027
|
values,
|
1936
2028
|
});
|
@@ -1953,19 +2045,16 @@ function createFormControl(props = {}) {
|
|
1953
2045
|
submitCount: keepStateOptions.keepSubmitCount
|
1954
2046
|
? _formState.submitCount
|
1955
2047
|
: 0,
|
1956
|
-
isDirty: keepStateOptions.keepDirty
|
2048
|
+
isDirty: keepStateOptions.keepDirty || keepStateOptions.keepDirtyValues
|
1957
2049
|
? _formState.isDirty
|
1958
|
-
: keepStateOptions.keepDefaultValues
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
? _formState.isSubmitted
|
1963
|
-
: false,
|
1964
|
-
dirtyFields: keepStateOptions.keepDirty
|
2050
|
+
: !!(keepStateOptions.keepDefaultValues &&
|
2051
|
+
!deepEqual(formValues, _defaultValues)),
|
2052
|
+
isSubmitted: !!keepStateOptions.keepIsSubmitted,
|
2053
|
+
dirtyFields: keepStateOptions.keepDirty || keepStateOptions.keepDirtyValues
|
1965
2054
|
? _formState.dirtyFields
|
1966
|
-
:
|
1967
|
-
?
|
1968
|
-
: {}
|
2055
|
+
: keepStateOptions.keepDefaultValues && formValues
|
2056
|
+
? getDirtyFields(_defaultValues, formValues)
|
2057
|
+
: {},
|
1969
2058
|
touchedFields: keepStateOptions.keepTouched
|
1970
2059
|
? _formState.touchedFields
|
1971
2060
|
: {},
|
@@ -2026,7 +2115,10 @@ function createFormControl(props = {}) {
|
|
2026
2115
|
return _options;
|
2027
2116
|
},
|
2028
2117
|
set _options(value) {
|
2029
|
-
_options =
|
2118
|
+
_options = {
|
2119
|
+
..._options,
|
2120
|
+
...value,
|
2121
|
+
};
|
2030
2122
|
},
|
2031
2123
|
},
|
2032
2124
|
trigger,
|
@@ -2092,13 +2184,19 @@ function useForm(props = {}) {
|
|
2092
2184
|
_formControl.current.control._options = props;
|
2093
2185
|
}
|
2094
2186
|
else {
|
2095
|
-
_formControl.current =
|
2187
|
+
_formControl.current = {
|
2188
|
+
...createFormControl(props),
|
2189
|
+
formState,
|
2190
|
+
};
|
2096
2191
|
}
|
2097
2192
|
const control = _formControl.current.control;
|
2098
2193
|
const callback = React.useCallback((value) => {
|
2099
2194
|
if (shouldRenderFormState(value, control._proxyFormState, true)) {
|
2100
|
-
control._formState =
|
2101
|
-
|
2195
|
+
control._formState = {
|
2196
|
+
...control._formState,
|
2197
|
+
...value,
|
2198
|
+
};
|
2199
|
+
updateFormState({ ...control._formState });
|
2102
2200
|
}
|
2103
2201
|
}, [control]);
|
2104
2202
|
useSubscribe({
|