UNPKG

@mirawision/reactive-hooks

Version:

A comprehensive collection of 50+ React hooks for state management, UI interactions, device APIs, async operations, drag & drop, audio/speech, and more. Full TypeScript support with SSR safety.

84 lines (83 loc) 2.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useScroll = useScroll; const react_1 = require("react"); function getScrollPosition(target) { if (typeof window === 'undefined') { return { x: 0, y: 0 }; } // Handle ref case if (target && 'current' in target) { const element = target.current; if (!element) return { x: 0, y: 0 }; return { x: element.scrollLeft, y: element.scrollTop, }; } // Handle window case if (!target || target === window) { return { x: window.pageXOffset || document.documentElement.scrollLeft, y: window.pageYOffset || document.documentElement.scrollTop, }; } // Handle element case const element = target; return { x: element.scrollLeft, y: element.scrollTop, }; } /** * A hook that tracks scroll position of a target element or window. * @param target Optional target element (defaults to window) * @param throttleMs Optional throttle delay in milliseconds * @returns Object containing current scroll position (x, y) */ function useScroll(target, throttleMs) { const [position, setPosition] = (0, react_1.useState)(() => getScrollPosition(target)); (0, react_1.useEffect)(() => { if (typeof window === 'undefined') return; let timeoutId = null; let rafId = null; const updatePosition = () => { setPosition(getScrollPosition(target)); }; const handleScroll = () => { if (throttleMs) { // Cancel any pending updates if (timeoutId) clearTimeout(timeoutId); if (rafId) cancelAnimationFrame(rafId); timeoutId = setTimeout(() => { rafId = requestAnimationFrame(updatePosition); }, throttleMs); } else { updatePosition(); } }; // Initial position updatePosition(); // Add event listener to appropriate target const scrollTarget = target && 'current' in target ? target.current : target || window; if (scrollTarget) { scrollTarget.addEventListener('scroll', handleScroll, { passive: true }); } // Cleanup return () => { if (scrollTarget) { scrollTarget.removeEventListener('scroll', handleScroll); } if (timeoutId) clearTimeout(timeoutId); if (rafId) cancelAnimationFrame(rafId); }; }, [target, throttleMs]); return position; }