UNPKG

@lani.ground/react-modal

Version:
68 lines (67 loc) 3.16 kB
import { hasBodyScroll } from './browser'; var isBrowser = typeof window !== 'undefined'; // 스크롤 가능한 요소인지 체크하는 유틸 함수 var isScrollable = function (element) { var style = window.getComputedStyle(element); var hasScroll = style.overflow === 'auto' || style.overflow === 'scroll' || style.overflowY === 'auto' || style.overflowY === 'scroll'; return hasScroll && element.scrollHeight > element.clientHeight; }; // 모달 내부 스크롤 전파 방지 핸들러 export var preventScrollPropagation = function (e) { var target = e.target; var modalContainer = target.closest('.react-modal__container'); // 모달 컨테이너가 아니면 이벤트 중단 if (!modalContainer) { e.preventDefault(); e.stopPropagation(); return; } // 현재 요소부터 부모로 올라가면서 스크롤 가능한 요소 찾기 var scrollableParent = target; while (scrollableParent && modalContainer.contains(scrollableParent)) { if (isScrollable(scrollableParent)) { // 스크롤 가능한 요소를 찾으면 스크롤 허용 if (e.type === 'wheel') { var wheelEvent = e; var isAtTop = scrollableParent.scrollTop === 0; var isAtBottom = scrollableParent.scrollTop + scrollableParent.clientHeight >= scrollableParent.scrollHeight; // 스크롤이 끝에 도달했을 때만 이벤트 중단 if ((isAtTop && wheelEvent.deltaY < 0) || (isAtBottom && wheelEvent.deltaY > 0)) { e.preventDefault(); } } e.stopPropagation(); return; } scrollableParent = scrollableParent.parentElement; } // 스크롤 가능한 요소를 찾지 못했으면 이벤트 중단 e.preventDefault(); e.stopPropagation(); }; export var lockScroll = function (isMobile, scrollbarWidth, originalStyles) { if (!isBrowser || !(document === null || document === void 0 ? void 0 : document.documentElement) || !(document === null || document === void 0 ? void 0 : document.body)) return 0; // 데스크톱에서만 스크롤바 패딩 조정 if (!isMobile && hasBodyScroll()) { var currentPadding = parseInt(window.getComputedStyle(document.body).paddingRight, 10) || 0; document.body.style.paddingRight = "".concat(currentPadding + scrollbarWidth, "px"); } // overflow hidden 적용 document.documentElement.style.overflow = 'hidden'; return window.scrollY; }; export var unlockScroll = function (scrollY, originalStyles) { if (!isBrowser || !(document === null || document === void 0 ? void 0 : document.documentElement) || !(document === null || document === void 0 ? void 0 : document.body)) return; // Styles 완전히 제거 (이전 상태로 복원하는 대신) document.documentElement.style.removeProperty('overflow'); document.body.style.removeProperty('padding-right'); // 스크롤 위치 복원 window.scrollTo(0, scrollY); };