@bombillazo/rhf-plus 7.62.0-plus.2 → 7.62.0-plus.4
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 +6 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +92 -7
- 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/skipValidation.d.ts +5 -1
- package/dist/logic/skipValidation.d.ts.map +1 -1
- package/dist/react-server.esm.mjs +43 -7
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/types/controller.d.ts +1 -0
- package/dist/types/controller.d.ts.map +1 -1
- package/dist/types/form.d.ts +4 -0
- package/dist/types/form.d.ts.map +1 -1
- package/dist/useController.d.ts.map +1 -1
- package/dist/useForm.d.ts.map +1 -1
- package/dist/useFormState.d.ts.map +1 -1
- package/dist/utils/mergeMissingKeysAsUndefined.d.ts +2 -0
- package/dist/utils/mergeMissingKeysAsUndefined.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.esm.mjs
CHANGED
|
@@ -81,6 +81,21 @@ var get = (object, path, defaultValue) => {
|
|
|
81
81
|
|
|
82
82
|
var isBoolean = (value) => typeof value === 'boolean';
|
|
83
83
|
|
|
84
|
+
function mergeMissingKeysAsUndefined(oldObject, newObject) {
|
|
85
|
+
if (!newObject) {
|
|
86
|
+
return newObject;
|
|
87
|
+
}
|
|
88
|
+
const result = { ...newObject };
|
|
89
|
+
if (oldObject) {
|
|
90
|
+
for (const key in oldObject) {
|
|
91
|
+
if (!(key in result)) {
|
|
92
|
+
result[key] = undefined;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
|
|
84
99
|
var set = (object, path, value) => {
|
|
85
100
|
let index = -1;
|
|
86
101
|
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
|
@@ -109,6 +124,8 @@ var set = (object, path, value) => {
|
|
|
109
124
|
const EVENTS = {
|
|
110
125
|
BLUR: 'blur',
|
|
111
126
|
FOCUS_OUT: 'focusout',
|
|
127
|
+
FOCUS: 'focus',
|
|
128
|
+
FOCUS_IN: 'focusin',
|
|
112
129
|
CHANGE: 'change',
|
|
113
130
|
};
|
|
114
131
|
const VALIDATION_MODE = {
|
|
@@ -256,6 +273,7 @@ function useFormState(props) {
|
|
|
256
273
|
isLoading: false,
|
|
257
274
|
dirtyFields: false,
|
|
258
275
|
touchedFields: false,
|
|
276
|
+
focusedField: false,
|
|
259
277
|
validatingFields: false,
|
|
260
278
|
isValidating: false,
|
|
261
279
|
isValid: false,
|
|
@@ -427,11 +445,22 @@ function useController(props) {
|
|
|
427
445
|
exact: true,
|
|
428
446
|
});
|
|
429
447
|
const _props = React.useRef(props);
|
|
448
|
+
const _previousRules = React.useRef(props.rules);
|
|
430
449
|
const _registerProps = React.useRef(control.register(name, {
|
|
431
450
|
...props.rules,
|
|
432
451
|
value,
|
|
433
452
|
...(isBoolean(props.disabled) ? { disabled: props.disabled } : {}),
|
|
434
453
|
}));
|
|
454
|
+
const mergedRules = React.useMemo(() => mergeMissingKeysAsUndefined(_previousRules.current, props.rules), [props.rules]);
|
|
455
|
+
// Update register props when rules change
|
|
456
|
+
React.useEffect(() => {
|
|
457
|
+
_registerProps.current = control.register(name, {
|
|
458
|
+
...mergedRules,
|
|
459
|
+
value,
|
|
460
|
+
...(isBoolean(props.disabled) ? { disabled: props.disabled } : {}),
|
|
461
|
+
});
|
|
462
|
+
_previousRules.current = props.rules;
|
|
463
|
+
}, [mergedRules, props.rules, value, props.disabled, control, name]);
|
|
435
464
|
_props.current = props;
|
|
436
465
|
const fieldState = React.useMemo(() => Object.defineProperties({}, {
|
|
437
466
|
invalid: {
|
|
@@ -446,6 +475,10 @@ function useController(props) {
|
|
|
446
475
|
enumerable: true,
|
|
447
476
|
get: () => !!get(formState.touchedFields, name),
|
|
448
477
|
},
|
|
478
|
+
isFocused: {
|
|
479
|
+
enumerable: true,
|
|
480
|
+
get: () => formState.focusedField === name,
|
|
481
|
+
},
|
|
449
482
|
isValidating: {
|
|
450
483
|
enumerable: true,
|
|
451
484
|
get: () => !!get(formState.validatingFields, name),
|
|
@@ -469,6 +502,13 @@ function useController(props) {
|
|
|
469
502
|
},
|
|
470
503
|
type: EVENTS.BLUR,
|
|
471
504
|
}), [name, control._formValues]);
|
|
505
|
+
const onFocus = React.useCallback(() => _registerProps.current.onFocus({
|
|
506
|
+
target: {
|
|
507
|
+
value: get(control._formValues, name),
|
|
508
|
+
name: name,
|
|
509
|
+
},
|
|
510
|
+
type: EVENTS.FOCUS,
|
|
511
|
+
}), [name, control._formValues]);
|
|
472
512
|
const elementRef = React.useRef(null);
|
|
473
513
|
const ref = React.useCallback((elm) => {
|
|
474
514
|
elementRef.current = elm;
|
|
@@ -510,9 +550,19 @@ function useController(props) {
|
|
|
510
550
|
...(isBoolean(isFieldDisabled) ? { disabled: isFieldDisabled } : {}),
|
|
511
551
|
onChange,
|
|
512
552
|
onBlur,
|
|
553
|
+
onFocus,
|
|
513
554
|
ref,
|
|
514
555
|
};
|
|
515
|
-
}, [
|
|
556
|
+
}, [
|
|
557
|
+
name,
|
|
558
|
+
disabled,
|
|
559
|
+
control._options.disabled,
|
|
560
|
+
onChange,
|
|
561
|
+
onBlur,
|
|
562
|
+
onFocus,
|
|
563
|
+
ref,
|
|
564
|
+
value,
|
|
565
|
+
]);
|
|
516
566
|
React.useEffect(() => {
|
|
517
567
|
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
|
518
568
|
control.register(name, {
|
|
@@ -1120,7 +1170,15 @@ var shouldSubscribeByName = (name, signalName, exact) => !name ||
|
|
|
1120
1170
|
: currentName.startsWith(signalName) ||
|
|
1121
1171
|
signalName.startsWith(currentName)));
|
|
1122
1172
|
|
|
1123
|
-
var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode
|
|
1173
|
+
var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode,
|
|
1174
|
+
/**
|
|
1175
|
+
* Need to keep this order of parameters for backward compatibility
|
|
1176
|
+
*/
|
|
1177
|
+
isFocusEvent) => {
|
|
1178
|
+
// Focus events should always skip validation
|
|
1179
|
+
if (isFocusEvent) {
|
|
1180
|
+
return true;
|
|
1181
|
+
}
|
|
1124
1182
|
if (mode.isOnAll) {
|
|
1125
1183
|
return false;
|
|
1126
1184
|
}
|
|
@@ -1387,6 +1445,7 @@ function createFormControl(props = {}) {
|
|
|
1387
1445
|
isValid: false,
|
|
1388
1446
|
touchedFields: {},
|
|
1389
1447
|
dirtyFields: {},
|
|
1448
|
+
focusedField: undefined,
|
|
1390
1449
|
validatingFields: {},
|
|
1391
1450
|
errors: _options.errors || {},
|
|
1392
1451
|
disabled: Array.isArray(_options.disabled)
|
|
@@ -1420,6 +1479,7 @@ function createFormControl(props = {}) {
|
|
|
1420
1479
|
dirtyFields: false,
|
|
1421
1480
|
validatingFields: false,
|
|
1422
1481
|
touchedFields: false,
|
|
1482
|
+
focusedField: false,
|
|
1423
1483
|
isValidating: false,
|
|
1424
1484
|
isValid: false,
|
|
1425
1485
|
errors: false,
|
|
@@ -1531,7 +1591,7 @@ function createFormControl(props = {}) {
|
|
|
1531
1591
|
_state.mount && _setValid();
|
|
1532
1592
|
}
|
|
1533
1593
|
};
|
|
1534
|
-
const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
|
|
1594
|
+
const updateTouchAndDirty = (name, fieldValue, isBlurEvent, isFocusEvent, shouldDirty, shouldRender) => {
|
|
1535
1595
|
let shouldUpdateField = false;
|
|
1536
1596
|
let isPreviousDirty = false;
|
|
1537
1597
|
const output = {
|
|
@@ -1568,6 +1628,25 @@ function createFormControl(props = {}) {
|
|
|
1568
1628
|
isPreviousFieldTouched !== isBlurEvent);
|
|
1569
1629
|
}
|
|
1570
1630
|
}
|
|
1631
|
+
// Handle focus state
|
|
1632
|
+
if (isFocusEvent || isBlurEvent) {
|
|
1633
|
+
const wasPreviouslyFocused = _formState.focusedField === name;
|
|
1634
|
+
const shouldBeFocused = isFocusEvent && !isBlurEvent;
|
|
1635
|
+
if (wasPreviouslyFocused !== shouldBeFocused) {
|
|
1636
|
+
if (shouldBeFocused) {
|
|
1637
|
+
_formState.focusedField = name;
|
|
1638
|
+
}
|
|
1639
|
+
else {
|
|
1640
|
+
_formState.focusedField = undefined;
|
|
1641
|
+
}
|
|
1642
|
+
output.focusedField = _formState.focusedField;
|
|
1643
|
+
shouldUpdateField =
|
|
1644
|
+
shouldUpdateField ||
|
|
1645
|
+
((_proxyFormState.focusedField ||
|
|
1646
|
+
_proxySubscribeFormState.focusedField) &&
|
|
1647
|
+
wasPreviouslyFocused !== shouldBeFocused);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1571
1650
|
shouldUpdateField && shouldRender && _subjects.state.next(output);
|
|
1572
1651
|
}
|
|
1573
1652
|
return shouldUpdateField ? output : {};
|
|
@@ -1733,7 +1812,8 @@ function createFormControl(props = {}) {
|
|
|
1733
1812
|
}
|
|
1734
1813
|
}
|
|
1735
1814
|
(options.shouldDirty || options.shouldTouch) &&
|
|
1736
|
-
updateTouchAndDirty(name, fieldValue, options.shouldTouch,
|
|
1815
|
+
updateTouchAndDirty(name, fieldValue, options.shouldTouch, false, // isFocusEvent - not applicable for setValue
|
|
1816
|
+
options.shouldDirty, true);
|
|
1737
1817
|
options.shouldValidate && trigger(name);
|
|
1738
1818
|
};
|
|
1739
1819
|
const setValues = (name, value, options) => {
|
|
@@ -1822,12 +1902,13 @@ function createFormControl(props = {}) {
|
|
|
1822
1902
|
? getFieldValue(field._f)
|
|
1823
1903
|
: getEventValue(event);
|
|
1824
1904
|
const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
|
|
1905
|
+
const isFocusEvent = event.type === EVENTS.FOCUS || event.type === EVENTS.FOCUS_IN;
|
|
1825
1906
|
const shouldSkipValidation = (!hasValidation(field._f) &&
|
|
1826
1907
|
!_options.resolver &&
|
|
1827
1908
|
!get(_formState.errors, name) &&
|
|
1828
1909
|
!field._f.deps) ||
|
|
1829
|
-
skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
|
|
1830
|
-
const watched = isWatched(name, _names, isBlurEvent);
|
|
1910
|
+
skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit, isFocusEvent);
|
|
1911
|
+
const watched = isWatched(name, _names, isBlurEvent || isFocusEvent);
|
|
1831
1912
|
set(_formValues, name, fieldValue);
|
|
1832
1913
|
if (isBlurEvent) {
|
|
1833
1914
|
if (!target || !target.readOnly) {
|
|
@@ -1838,7 +1919,7 @@ function createFormControl(props = {}) {
|
|
|
1838
1919
|
else if (field._f.onChange) {
|
|
1839
1920
|
field._f.onChange(event);
|
|
1840
1921
|
}
|
|
1841
|
-
const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent);
|
|
1922
|
+
const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, isFocusEvent);
|
|
1842
1923
|
const shouldRender = !isEmptyObject(fieldState) || watched;
|
|
1843
1924
|
!isBlurEvent &&
|
|
1844
1925
|
_subjects.state.next({
|
|
@@ -1952,6 +2033,7 @@ function createFormControl(props = {}) {
|
|
|
1952
2033
|
error: get((formState || _formState).errors, name),
|
|
1953
2034
|
isValidating: !!get(_formState.validatingFields, name),
|
|
1954
2035
|
isTouched: !!get((formState || _formState).touchedFields, name),
|
|
2036
|
+
isFocused: (formState || _formState).focusedField === name,
|
|
1955
2037
|
});
|
|
1956
2038
|
const clearErrors = (name) => {
|
|
1957
2039
|
name &&
|
|
@@ -2091,6 +2173,7 @@ function createFormControl(props = {}) {
|
|
|
2091
2173
|
name,
|
|
2092
2174
|
onChange,
|
|
2093
2175
|
onBlur: onChange,
|
|
2176
|
+
onFocus: onChange,
|
|
2094
2177
|
ref: (ref) => {
|
|
2095
2178
|
if (ref) {
|
|
2096
2179
|
register(name, options);
|
|
@@ -2356,6 +2439,7 @@ function createFormControl(props = {}) {
|
|
|
2356
2439
|
touchedFields: keepStateOptions.keepTouched
|
|
2357
2440
|
? _formState.touchedFields
|
|
2358
2441
|
: {},
|
|
2442
|
+
focusedField: undefined, // Always reset focused field on form reset
|
|
2359
2443
|
errors: keepStateOptions.keepErrors ? _formState.errors : {},
|
|
2360
2444
|
isSubmitSuccessful: keepStateOptions.keepIsSubmitSuccessful
|
|
2361
2445
|
? _formState.isSubmitSuccessful
|
|
@@ -2872,6 +2956,7 @@ function useForm(props = {}) {
|
|
|
2872
2956
|
submitCount: 0,
|
|
2873
2957
|
dirtyFields: {},
|
|
2874
2958
|
touchedFields: {},
|
|
2959
|
+
focusedField: undefined,
|
|
2875
2960
|
validatingFields: {},
|
|
2876
2961
|
errors: props.errors || {},
|
|
2877
2962
|
// If it's an array, set formState.disabled to false because when using array mode,
|