모달 스크롤 버그를 Modal.tsx 한 곳만 고쳤더니 같은 잠금·복귀 코드가 그대로 복사돼 있던 GallerySection·EventSection 에는 버그가 그대로 남아 있었다(2026-09-21 실측). 복사한 코드는 복사한 곳마다 따로 고쳐야 하므로 훅 하나로 뺀다. - lib/ui/use-scroll-lock.ts: 스크롤 잠금·복귀 로직 신규 — scroll-behavior:auto 강제 포함 - lib/ui/Modal.tsx, sections/GallerySection.tsx, sections/items/EventSection.tsx: 중복 잠금 코드 제거, useScrollLock() 호출로 교체 - lib/ui/index.ts: useScrollLock export 추가 tsc 통과, vitest 100 passed(무관한 날씨 조건 테스트 2건은 이 변경 전부터 실패 중) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
40 lines
1.7 KiB
TypeScript
40 lines
1.7 KiB
TypeScript
/**
|
|
* 모달·오버레이가 열려 있는 동안 배경 스크롤을 잠근다 — **한 벌만 둔다.**
|
|
*
|
|
* ★ 왜 훅으로 뺐나 (2026-09-21, 사장님: "이거 목업 하나만 해결하면 끝이야? 훅으로 만들어놓던가")
|
|
* 같은 잠금·복귀 코드가 Modal · GallerySection · EventSection 세 곳에 따로 박혀 있었다.
|
|
* 모달 하나만 고치고 나니 나머지 둘은 그대로 남아 같은 스크롤 버그가 다시 났다 —
|
|
* 복사한 코드는 복사한 곳마다 따로 고쳐야 한다.
|
|
* ★ 복귀는 즉시 이동이어야 한다. `index.css` 의 전역 `html { scroll-behavior: smooth }` 때문에
|
|
* `window.scrollTo` 가 애니메이션으로 움직이며 "위로 튀었다 내려오는" 것처럼 보인다 —
|
|
* 이 한 번만 `scroll-behavior: auto` 로 강제한다.
|
|
*/
|
|
import {useEffect} from 'react';
|
|
|
|
export function useScrollLock(active: boolean) {
|
|
useEffect(() => {
|
|
if (!active) return;
|
|
const scrollY = window.scrollY;
|
|
const body = document.body;
|
|
const prevPosition = body.style.position;
|
|
const prevTop = body.style.top;
|
|
const prevWidth = body.style.width;
|
|
const prevOverflow = body.style.overflow;
|
|
body.style.position = 'fixed';
|
|
body.style.top = `-${scrollY}px`;
|
|
body.style.width = '100%';
|
|
body.style.overflow = 'hidden';
|
|
return () => {
|
|
body.style.position = prevPosition;
|
|
body.style.top = prevTop;
|
|
body.style.width = prevWidth;
|
|
body.style.overflow = prevOverflow;
|
|
const root = document.documentElement;
|
|
const prevScrollBehavior = root.style.scrollBehavior;
|
|
root.style.scrollBehavior = 'auto';
|
|
window.scrollTo(0, scrollY);
|
|
root.style.scrollBehavior = prevScrollBehavior;
|
|
};
|
|
}, [active]);
|
|
}
|