fix(pop-modal): 중첩 모달 닫기 시 모든 모달이 한꺼번에 닫히는 버그 수정

- handleCloseModal(index) -> handleCloseTopModal()로 변경 (최상위 1개만 닫기)
- onOpenChange에 isTopModal 가드 추가 (하위 모달 연쇄 반응 방지)
- onInteractOutside/onEscapeKeyDown에 isTopModal 가드 추가

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
SeongHyun Kim 2026-02-23 14:03:55 +09:00
parent df8cbb3e80
commit fc0e913b8a
1 changed files with 8 additions and 8 deletions

View File

@ -91,9 +91,9 @@ export default function PopViewerWithModals({
};
}, [subscribe, layout.modals]);
// 특정 인덱스의 모달 닫기
const handleCloseModal = useCallback((index: number) => {
setModalStack(prev => prev.slice(0, index));
// 최상위 모달만 닫기 (X 버튼, overlay 클릭, ESC)
const handleCloseTopModal = useCallback(() => {
setModalStack(prev => prev.slice(0, -1));
}, []);
return (
@ -112,10 +112,10 @@ export default function PopViewerWithModals({
{/* 모달 스택 렌더링 */}
{modalStack.map((modal, index) => {
const { definition } = modal;
const isTopModal = index === modalStack.length - 1;
const closeOnOverlay = definition.frameConfig?.closeOnOverlay !== false;
const closeOnEsc = definition.frameConfig?.closeOnEsc !== false;
// 모달의 layout 구성 (모달 자체를 하나의 레이아웃으로)
const modalLayout: PopLayoutDataV5 = {
...layout,
gridConfig: definition.gridConfig,
@ -123,7 +123,6 @@ export default function PopViewerWithModals({
overrides: definition.overrides,
};
// sizeConfig 기반 모달 너비 계산
const detectedMode = currentMode || detectGridMode(viewportWidth);
const modalWidth = resolveModalWidth(definition.sizeConfig, detectedMode, viewportWidth);
const isFull = modalWidth >= viewportWidth;
@ -134,7 +133,7 @@ export default function PopViewerWithModals({
key={`${definition.id}-${index}`}
open={true}
onOpenChange={(open) => {
if (!open) handleCloseModal(index);
if (!open && isTopModal) handleCloseTopModal();
}}
>
<DialogContent
@ -147,10 +146,11 @@ export default function PopViewerWithModals({
width: `${modalWidth}px`,
}}
onInteractOutside={(e) => {
if (!closeOnOverlay) e.preventDefault();
// 최상위 모달이 아니면 overlay 클릭 무시 (하위 모달이 먼저 닫히는 것 방지)
if (!isTopModal || !closeOnOverlay) e.preventDefault();
}}
onEscapeKeyDown={(e) => {
if (!closeOnEsc) e.preventDefault();
if (!isTopModal || !closeOnEsc) e.preventDefault();
}}
>
<DialogHeader className={isFull ? "px-4 pt-3 pb-2" : "px-4 pt-4 pb-2"}>