Skip to content

Instantly share code, notes, and snippets.

@l-portet
Created October 23, 2024 13:56
Show Gist options
  • Save l-portet/f8070e6625f8971d5d235b25cd8da6f4 to your computer and use it in GitHub Desktop.
Save l-portet/f8070e6625f8971d5d235b25cd8da6f4 to your computer and use it in GitHub Desktop.
import { RefObject, useEffect, useRef } from 'react';
function getScrollParent(node: HTMLElement | null): HTMLElement | null {
const isElement = node instanceof HTMLElement;
const overflowY = isElement && window.getComputedStyle(node).overflowY;
const isScrollable = overflowY !== 'visible' && overflowY !== 'hidden';
if (!node) {
return null;
} else if (isScrollable && node.scrollHeight >= node.clientHeight) {
return node;
}
return (
getScrollParent(node.parentNode as HTMLElement) || (document.scrollingElement as HTMLElement) || document.body
);
}
export const useScrollParent = (ref: RefObject<HTMLElement>) => {
const parent = useRef<HTMLElement | null>(null);
useEffect(() => {
parent.current = getScrollParent(ref.current);
}, [ref.current]);
return {
element: parent.current,
scrollTo: (options: ScrollToOptions = {}) => {
const defaultOptions: ScrollToOptions = { top: 0, behavior: 'smooth' };
parent.current?.scrollTo({ ...defaultOptions, ...options });
},
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment