@lani.ground/react-modal
Version:
Modal components used in reactjs
68 lines (67 loc) • 3.16 kB
JavaScript
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);
};