UNPKG

@redocly/theme

Version:

Shared UI components lib

57 lines (45 loc) 1.78 kB
import { useEffect, useRef } from 'react'; export function useModalScrollLock(isOpen: boolean): void { const originalBodyStylesRef = useRef<{ overflow: string; paddingRight: string; scrollbarWidth: string | null; } | null>(null); useEffect(() => { if (typeof window === 'undefined' || typeof document === 'undefined') { return; } const { body, documentElement } = document; const restoreOriginalBodyStyles = () => { if (!originalBodyStylesRef.current) return; const { overflow, paddingRight, scrollbarWidth } = originalBodyStylesRef.current; body.style.overflow = overflow; body.style.paddingRight = paddingRight; if (scrollbarWidth) { documentElement.style.setProperty('--modal-scrollbar-width', scrollbarWidth); } else { documentElement.style.removeProperty('--modal-scrollbar-width'); } originalBodyStylesRef.current = null; }; if (isOpen && !originalBodyStylesRef.current) { originalBodyStylesRef.current = { overflow: body.style.overflow, paddingRight: body.style.paddingRight, scrollbarWidth: documentElement.style.getPropertyValue('--modal-scrollbar-width') || null, }; const scrollbarWidth = window.innerWidth - documentElement.clientWidth; body.style.overflow = 'hidden'; if (scrollbarWidth > 0) { body.style.paddingRight = `${scrollbarWidth}px`; documentElement.style.setProperty('--modal-scrollbar-width', `${scrollbarWidth}px`); } } else if (!isOpen && originalBodyStylesRef.current) { restoreOriginalBodyStyles(); } // Cleanup only if component unmounts while modal is open return () => { restoreOriginalBodyStyles(); }; }, [isOpen]); }