Focusing with smooth scrolling #9034
-
I'm using the Controller component and pass the ref to my custom component, which allows react-hook-form to focus (and scroll to) the first component having an error. However, I don't see a param to fill to have the "smooth scroll" behavior. Is there a way to achieve it ? Thanks |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 2 replies
-
You can override focus() method of the DOM element when passing it via "ref" of "register" and perform any custom behaviour for focusing, something like scrollIntoView with smooth option then trigger focus() of the element. Example of overriding focus() method: https://codesandbox.io/s/setfocus-forked-qqr3zr?file=/src/App.tsx |
Beta Was this translation helpful? Give feedback.
-
After trying both of the above code snippets, I realized in my form, I could easily just set the CSS |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
It would be nice, if i am able to pass scrollbehaviour parameter to setFocus. |
Beta Was this translation helpful? Give feedback.
-
@davidalvarezr I was also looking for the answer and after reading through this issue thread, I created the following component. By integrating it with react-hook-form, it effectively handles both server and client validation errors. However, when dealing with custom "fields" like radio button groups, where multiple inputs share the same name, react-hook-form might not determine the correct ref and import { useEffect } from 'react';
import { useFormContext, FieldError } from 'react-hook-form';
export const ScrollToFieldError = () => {
const {
formState: { errors, isSubmitting },
} = useFormContext();
useEffect(() => {
const error = Object.values(errors)[0] as FieldError;
if (!(error?.ref instanceof HTMLElement) || isSubmitting) return;
// To achieve the desired smooth scrolling behavior,
// make sure to configure the useForm with shouldFocusError set to false.
error.ref.scrollIntoView({
behavior: 'smooth',
block: 'center',
});
error.ref.focus({ preventScroll: true });
}, [errors, isSubmitting]);
return null;
};
// ------------------------
<FormProvider {...}>
<ScrollToFieldError />
<form {...}>{...}</form>
</FormProvider> |
Beta Was this translation helpful? Give feedback.
@davidalvarezr
You can override focus() method of the DOM element when passing it via "ref" of "register" and perform any custom behaviour for focusing, something like scrollIntoView with smooth option then trigger focus() of the element.
Example of overriding focus() method: https://codesandbox.io/s/setfocus-forked-qqr3zr?file=/src/App.tsx