UNPKG

@supunlakmal/hooks

Version:

A collection of reusable React hooks

59 lines 2.26 kB
import { useState, useEffect, useRef } from 'react'; import { useEventListener } from '../event-handling/useEventListener'; const isBrowser = typeof window !== 'undefined'; function getScrollPosition(element) { if (!isBrowser) { return { x: 0, y: 0 }; } const target = element ? 'current' in element ? element.current : element : window; if (!target) { return { x: 0, y: 0 }; } if (target === window) { return { x: window.scrollX, y: window.scrollY }; } else if (target instanceof Element) { return { x: target.scrollLeft, y: target.scrollTop }; } else { // Should not happen with current types, but fallback return { x: 0, y: 0 }; } } /** * Custom hook to track the scroll position of the window or a specific element. * * @param {RefObject<Element> | Window | null} [element] - The target element or window to track scroll position for. Defaults to window. * @param {number} [throttleMs=100] - Throttle time in milliseconds to limit scroll event handling. Set to 0 to disable throttling. * @returns {ScrollPosition} An object containing the current x and y scroll position. */ export const useScrollPosition = (element, throttleMs = 100) => { const [position, setPosition] = useState(() => getScrollPosition(element)); const throttleTimeout = useRef(null); const handleScroll = () => { setPosition(getScrollPosition(element)); throttleTimeout.current = null; // Clear timeout ref after execution }; const throttledHandleScroll = () => { if (throttleMs <= 0) { handleScroll(); return; } if (throttleTimeout.current === null) { throttleTimeout.current = setTimeout(handleScroll, throttleMs); } }; // Determine the event target const target = element !== null && element !== void 0 ? element : window; useEventListener('scroll', throttledHandleScroll, target); // Re-calculate on element change useEffect(() => { setPosition(getScrollPosition(element)); }, [element]); // Depend on the element/ref object itself return position; }; //# sourceMappingURL=useScrollPosition.js.map