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.

60 lines (59 loc) 2.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useWindowScrollLock = useWindowScrollLock; const react_1 = require("react"); /** * A hook that locks/unlocks window scrolling by setting overflow on document.body. * Preserves the original overflow value and restores it when unlocked or unmounted. * * @param locked Whether scrolling should be locked * * @example * // In a modal component * useWindowScrollLock(isOpen); */ function useWindowScrollLock(locked) { // Store the original overflow value const originalOverflow = (0, react_1.useRef)(); (0, react_1.useEffect)(() => { if (typeof document === 'undefined') return; const { body } = document; if (!body) return; if (locked) { // Store current overflow only when locking originalOverflow.current = body.style.overflow; // Get current scroll position const scrollY = window.scrollY; // Lock scroll body.style.overflow = 'hidden'; // Prevent content jump by setting top margin body.style.marginTop = `-${scrollY}px`; body.style.width = '100%'; body.style.position = 'fixed'; } else if (originalOverflow.current !== undefined) { // Get the margin top value (scroll position) const scrollY = parseInt(body.style.marginTop || '0', 10); // Restore original styles body.style.overflow = originalOverflow.current; body.style.marginTop = ''; body.style.width = ''; body.style.position = ''; // Restore scroll position window.scrollTo(0, Math.abs(scrollY)); } return () => { // Cleanup on unmount - restore original overflow if (originalOverflow.current !== undefined) { const scrollY = parseInt(body.style.marginTop || '0', 10); body.style.overflow = originalOverflow.current; body.style.marginTop = ''; body.style.width = ''; body.style.position = ''; window.scrollTo(0, Math.abs(scrollY)); } }; }, [locked]); }