@bombillazo/rhf-plus 7.65.0-plus.0 → 7.68.0-plus.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/dist/formStateSubscribe.d.ts +7 -0
- package/dist/formStateSubscribe.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 +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.mjs +92 -40
- package/dist/index.esm.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/logic/getDirtyFields.d.ts.map +1 -1
- package/dist/react-server.esm.mjs +23 -12
- 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/path/eager.d.ts +1 -1
- package/dist/types/path/eager.d.ts.map +1 -1
- package/dist/useController.d.ts.map +1 -1
- package/dist/useForm.d.ts.map +1 -1
- package/dist/useFormContext.d.ts +1 -1
- package/dist/utils/deepEqual.d.ts.map +1 -1
- package/dist/watch.d.ts +1 -1
- package/dist/watch.d.ts.map +1 -1
- package/package.json +16 -16
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,sBAAsB,CAAC;AACrC,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
|
package/dist/index.esm.mjs
CHANGED
|
@@ -179,7 +179,7 @@ HookFormContext.displayName = 'HookFormContext';
|
|
|
179
179
|
*/
|
|
180
180
|
const useFormContext = () => React.useContext(HookFormContext);
|
|
181
181
|
/**
|
|
182
|
-
* A provider component that propagates the `useForm` methods to all children components via [React Context](https://
|
|
182
|
+
* A provider component that propagates the `useForm` methods to all children components via [React Context](https://react.dev/reference/react/useContext) API. To be used with {@link useFormContext}.
|
|
183
183
|
*
|
|
184
184
|
* @remarks
|
|
185
185
|
* [API](https://react-hook-form.com/docs/useformcontext) • [Demo](https://codesandbox.io/s/react-hook-form-v7-form-context-ytudi)
|
|
@@ -318,7 +318,7 @@ var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
|
318
318
|
|
|
319
319
|
function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
|
|
320
320
|
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
321
|
-
return object1
|
|
321
|
+
return Object.is(object1, object2);
|
|
322
322
|
}
|
|
323
323
|
if (isDateObject(object1) && isDateObject(object2)) {
|
|
324
324
|
return object1.getTime() === object2.getTime();
|
|
@@ -344,7 +344,7 @@ function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
|
|
|
344
344
|
(isObject(val1) && isObject(val2)) ||
|
|
345
345
|
(Array.isArray(val1) && Array.isArray(val2))
|
|
346
346
|
? !deepEqual(val1, val2, _internal_visited)
|
|
347
|
-
: val1
|
|
347
|
+
: !Object.is(val1, val2)) {
|
|
348
348
|
return false;
|
|
349
349
|
}
|
|
350
350
|
}
|
|
@@ -374,33 +374,68 @@ function useWatch(props) {
|
|
|
374
374
|
const _defaultValue = React.useRef(defaultValue);
|
|
375
375
|
const _compute = React.useRef(compute);
|
|
376
376
|
const _computeFormValues = React.useRef(undefined);
|
|
377
|
+
const _prevControl = React.useRef(control);
|
|
378
|
+
const _prevName = React.useRef(name);
|
|
377
379
|
_compute.current = compute;
|
|
378
|
-
const
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
else {
|
|
397
|
-
updateValue(formValues);
|
|
380
|
+
const [value, updateValue] = React.useState(() => {
|
|
381
|
+
const defaultValue = control._getWatch(name, _defaultValue.current);
|
|
382
|
+
return _compute.current ? _compute.current(defaultValue) : defaultValue;
|
|
383
|
+
});
|
|
384
|
+
const getCurrentOutput = React.useCallback((values) => {
|
|
385
|
+
const formValues = generateWatchOutput(name, control._names, values || control._formValues, false, _defaultValue.current);
|
|
386
|
+
return _compute.current ? _compute.current(formValues) : formValues;
|
|
387
|
+
}, [control._formValues, control._names, name]);
|
|
388
|
+
const refreshValue = React.useCallback((values) => {
|
|
389
|
+
if (!disabled) {
|
|
390
|
+
const formValues = generateWatchOutput(name, control._names, values || control._formValues, false, _defaultValue.current);
|
|
391
|
+
if (_compute.current) {
|
|
392
|
+
const computedFormValues = _compute.current(formValues);
|
|
393
|
+
if (!deepEqual(computedFormValues, _computeFormValues.current)) {
|
|
394
|
+
updateValue(computedFormValues);
|
|
395
|
+
_computeFormValues.current = computedFormValues;
|
|
398
396
|
}
|
|
399
397
|
}
|
|
400
|
-
|
|
401
|
-
|
|
398
|
+
else {
|
|
399
|
+
updateValue(formValues);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}, [control._formValues, control._names, disabled, name]);
|
|
403
|
+
useIsomorphicLayoutEffect(() => {
|
|
404
|
+
if (_prevControl.current !== control ||
|
|
405
|
+
!deepEqual(_prevName.current, name)) {
|
|
406
|
+
_prevControl.current = control;
|
|
407
|
+
_prevName.current = name;
|
|
408
|
+
refreshValue();
|
|
409
|
+
}
|
|
410
|
+
return control._subscribe({
|
|
411
|
+
name,
|
|
412
|
+
formState: {
|
|
413
|
+
values: true,
|
|
414
|
+
},
|
|
415
|
+
exact,
|
|
416
|
+
callback: (formState) => {
|
|
417
|
+
refreshValue(formState.values);
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
}, [control, exact, name, refreshValue]);
|
|
402
421
|
React.useEffect(() => control._removeUnmounted());
|
|
403
|
-
|
|
422
|
+
// If name or control changed for this render, synchronously reflect the
|
|
423
|
+
// latest value so callers (like useController) see the correct value
|
|
424
|
+
// immediately on the same render.
|
|
425
|
+
// Optimize: Check control reference first before expensive deepEqual
|
|
426
|
+
const controlChanged = _prevControl.current !== control;
|
|
427
|
+
const prevName = _prevName.current;
|
|
428
|
+
// Cache the computed output to avoid duplicate calls within the same render
|
|
429
|
+
// We include shouldReturnImmediate in deps to ensure proper recomputation
|
|
430
|
+
const computedOutput = React.useMemo(() => {
|
|
431
|
+
if (disabled) {
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
const nameChanged = !controlChanged && !deepEqual(prevName, name);
|
|
435
|
+
const shouldReturnImmediate = controlChanged || nameChanged;
|
|
436
|
+
return shouldReturnImmediate ? getCurrentOutput() : null;
|
|
437
|
+
}, [disabled, controlChanged, name, prevName, getCurrentOutput]);
|
|
438
|
+
return computedOutput !== null ? computedOutput : value;
|
|
404
439
|
}
|
|
405
440
|
|
|
406
441
|
/**
|
|
@@ -429,7 +464,7 @@ function useWatch(props) {
|
|
|
429
464
|
*/
|
|
430
465
|
function useController(props) {
|
|
431
466
|
const methods = useFormContext();
|
|
432
|
-
const { name, disabled, control = methods === null || methods === void 0 ? void 0 : methods.control, shouldUnregister, defaultValue, } = props;
|
|
467
|
+
const { name, disabled, control = methods === null || methods === void 0 ? void 0 : methods.control, shouldUnregister, defaultValue, exact = true, } = props;
|
|
433
468
|
if (!control) {
|
|
434
469
|
throw new Error('useController: missing `control`. Pass `control` as a prop or provide it via FormProvider.');
|
|
435
470
|
}
|
|
@@ -439,12 +474,12 @@ function useController(props) {
|
|
|
439
474
|
control,
|
|
440
475
|
name,
|
|
441
476
|
defaultValue: defaultValueMemo,
|
|
442
|
-
exact
|
|
477
|
+
exact,
|
|
443
478
|
});
|
|
444
479
|
const formState = useFormState({
|
|
445
480
|
control,
|
|
446
481
|
name,
|
|
447
|
-
exact
|
|
482
|
+
exact,
|
|
448
483
|
});
|
|
449
484
|
const _props = React.useRef(props);
|
|
450
485
|
const _previousRules = React.useRef(props.rules);
|
|
@@ -797,6 +832,8 @@ function Form(props) {
|
|
|
797
832
|
}))) : (React.createElement("form", { noValidate: mounted, action: action, method: method, encType: encType, onSubmit: submit, ...rest }, children));
|
|
798
833
|
}
|
|
799
834
|
|
|
835
|
+
const FormStateSubscribe = ({ control, disabled, exact, name, render, }) => render(useFormState({ control, name, disabled, exact }));
|
|
836
|
+
|
|
800
837
|
var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
|
|
801
838
|
? {
|
|
802
839
|
...errors[name],
|
|
@@ -972,11 +1009,12 @@ function isTraversable(value) {
|
|
|
972
1009
|
}
|
|
973
1010
|
function markFieldsDirty(data, fields = {}) {
|
|
974
1011
|
for (const key in data) {
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1012
|
+
const value = data[key];
|
|
1013
|
+
if (isTraversable(value)) {
|
|
1014
|
+
fields[key] = Array.isArray(value) ? [] : {};
|
|
1015
|
+
markFieldsDirty(value, fields[key]);
|
|
978
1016
|
}
|
|
979
|
-
else if (!isUndefined(
|
|
1017
|
+
else if (!isUndefined(value)) {
|
|
980
1018
|
fields[key] = true;
|
|
981
1019
|
}
|
|
982
1020
|
}
|
|
@@ -987,16 +1025,18 @@ function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
|
|
|
987
1025
|
dirtyFieldsFromValues = markFieldsDirty(formValues);
|
|
988
1026
|
}
|
|
989
1027
|
for (const key in data) {
|
|
990
|
-
|
|
1028
|
+
const value = data[key];
|
|
1029
|
+
if (isTraversable(value)) {
|
|
991
1030
|
if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) {
|
|
992
|
-
dirtyFieldsFromValues[key] = markFieldsDirty(
|
|
1031
|
+
dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {});
|
|
993
1032
|
}
|
|
994
1033
|
else {
|
|
995
|
-
getDirtyFields(
|
|
1034
|
+
getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
|
|
996
1035
|
}
|
|
997
1036
|
}
|
|
998
1037
|
else {
|
|
999
|
-
|
|
1038
|
+
const formValue = formValues[key];
|
|
1039
|
+
dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
|
|
1000
1040
|
}
|
|
1001
1041
|
}
|
|
1002
1042
|
return dirtyFieldsFromValues;
|
|
@@ -1630,7 +1670,7 @@ function createFormControl(props = {}) {
|
|
|
1630
1670
|
shouldSkipSetValueAs
|
|
1631
1671
|
? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
|
|
1632
1672
|
: setFieldValue(name, defaultValue);
|
|
1633
|
-
_state.mount && _setValid();
|
|
1673
|
+
_state.mount && !_state.action && _setValid();
|
|
1634
1674
|
}
|
|
1635
1675
|
};
|
|
1636
1676
|
const updateTouchAndDirty = (name, fieldValue, isBlurEvent, isFocusEvent, shouldDirty, shouldRender) => {
|
|
@@ -2558,8 +2598,16 @@ function createFormControl(props = {}) {
|
|
|
2558
2598
|
_state.mount =
|
|
2559
2599
|
!_proxyFormState.isValid ||
|
|
2560
2600
|
!!keepStateOptions.keepIsValid ||
|
|
2561
|
-
!!keepStateOptions.keepDirtyValues
|
|
2601
|
+
!!keepStateOptions.keepDirtyValues ||
|
|
2602
|
+
(!_options.shouldUnregister && !isEmptyObject(values));
|
|
2562
2603
|
_state.watch = !!_options.shouldUnregister;
|
|
2604
|
+
_state.action = false;
|
|
2605
|
+
// Clear errors synchronously to prevent validation errors on subsequent submissions
|
|
2606
|
+
// This fixes the issue where form.reset() causes validation errors on subsequent
|
|
2607
|
+
// submissions in Next.js 16 with Server Actions
|
|
2608
|
+
if (!keepStateOptions.keepErrors) {
|
|
2609
|
+
_formState.errors = {};
|
|
2610
|
+
}
|
|
2563
2611
|
_subjects.state.next({
|
|
2564
2612
|
submitCount: keepStateOptions.keepSubmitCount
|
|
2565
2613
|
? _formState.submitCount
|
|
@@ -3217,11 +3265,15 @@ function useForm(props = {}) {
|
|
|
3217
3265
|
}
|
|
3218
3266
|
}, [control, formState.isDirty]);
|
|
3219
3267
|
React.useEffect(() => {
|
|
3268
|
+
var _a;
|
|
3220
3269
|
if (props.values && !deepEqual(props.values, _values.current)) {
|
|
3221
3270
|
control._reset(props.values, {
|
|
3222
3271
|
keepFieldsRef: true,
|
|
3223
3272
|
...control._options.resetOptions,
|
|
3224
3273
|
});
|
|
3274
|
+
if (!((_a = control._options.resetOptions) === null || _a === void 0 ? void 0 : _a.keepIsValid)) {
|
|
3275
|
+
control._setValid();
|
|
3276
|
+
}
|
|
3225
3277
|
_values.current = props.values;
|
|
3226
3278
|
updateFormState((state) => ({ ...state }));
|
|
3227
3279
|
}
|
|
@@ -3280,5 +3332,5 @@ function useForm(props = {}) {
|
|
|
3280
3332
|
*/
|
|
3281
3333
|
const Watch = ({ control, names, render, }) => render(useWatch({ control, name: names }));
|
|
3282
3334
|
|
|
3283
|
-
export { Controller, Form, FormProvider, Watch, appendErrors, createFormControl, get, set, submitForm as submit, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
|
|
3335
|
+
export { Controller, Form, FormProvider, FormStateSubscribe, Watch, appendErrors, createFormControl, get, set, submitForm as submit, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
|
|
3284
3336
|
//# sourceMappingURL=index.esm.mjs.map
|