import { RefObject, useEffect } from 'react'; import { useCallbackRef } from './use-callback-ref'; function getScrollParent(element: HTMLElement, includeHidden = false): HTMLElement { let style = getComputedStyle(element); const excludeStaticParent = style.position === 'absolute'; const overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/; if (style.position === 'fixed') return document.body; let parent: HTMLElement | null = element; while ((parent = parent.parentElement)) { style = getComputedStyle(parent); if (excludeStaticParent && style.position === 'static') continue; if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) return parent; } return document.body; } export function useParentScroll( ref: RefObject | null | undefined, cb: (e: Event) => void, ) { const cbRef = useCallbackRef(cb); useEffect(() => { const el = ref?.current; if (el) { const parent = getScrollParent(el); const lol = (e: Event) => cbRef.current(e); parent.addEventListener('scroll', lol, { passive: true }); return () => parent.removeEventListener('scroll', cb); } }, [ref, cbRef]); }