Refactor AlertDialog and Dialog components to improve tab management and visibility handling. Updated effectiveOpen logic and adjusted display styles based on tab activity.

This commit is contained in:
kjs
2026-03-23 15:22:16 +09:00
parent aa48d40048
commit cab0342081
2 changed files with 14 additions and 4 deletions

View File

@@ -31,7 +31,7 @@ const AlertDialog: React.FC<React.ComponentProps<typeof AlertDialogPrimitive.Roo
const isTabActiveRef = React.useRef(isTabActive);
isTabActiveRef.current = isTabActive;
const effectiveOpen = open != null ? open && isTabActive : undefined;
const effectiveOpen = open != null ? open : undefined;
const guardedOnOpenChange = React.useCallback(
(newOpen: boolean) => {
@@ -94,6 +94,11 @@ const AlertDialogContent = React.forwardRef<
const container = explicitContainer !== undefined ? explicitContainer : autoContainer;
const scoped = React.useContext(ScopedAlertCtx);
// 탭 비활성 시 content를 언마운트하지 않고 CSS로 숨김 (자식 컴포넌트 상태 보존)
const tabId = useTabId();
const activeTabId = useTabStore((s) => s[s.mode].activeTabId);
const isTabActive = !tabId || tabId === activeTabId;
const adjustedStyle = scoped && style
? { ...style, maxHeight: undefined, maxWidth: undefined }
: style;
@@ -117,7 +122,7 @@ const AlertDialogContent = React.forwardRef<
<DialogPrimitive.Portal container={container ?? undefined}>
<div
className="absolute inset-0 z-1050 flex items-center justify-center overflow-hidden p-4"
style={hiddenProp ? { display: "none" } : undefined}
style={(hiddenProp || !isTabActive) ? { display: "none" } : undefined}
>
<div className="absolute inset-0 bg-black/80" />
<DialogPrimitive.Content

View File

@@ -28,7 +28,7 @@ const Dialog: React.FC<React.ComponentProps<typeof DialogPrimitive.Root>> = ({
isTabActiveRef.current = isTabActive;
const effectiveModal = modal !== undefined ? modal : !scoped ? undefined : false;
const effectiveOpen = open != null ? open && isTabActive : undefined;
const effectiveOpen = open != null ? open : undefined;
// 비활성 탭에서 발생하는 onOpenChange(false) 차단
// (탭 전환 시 content unmount → focus 이동 → Radix가 onOpenChange(false)를 호출하는 것을 방지)
@@ -83,6 +83,11 @@ const DialogContent = React.forwardRef<
const container = explicitContainer !== undefined ? explicitContainer : autoContainer;
const scoped = !!container;
// 탭 비활성 시 content를 언마운트하지 않고 CSS로 숨김 (자식 컴포넌트 상태 보존)
const tabId = useTabId();
const activeTabId = useTabStore((s) => s[s.mode].activeTabId);
const isTabActive = !tabId || tabId === activeTabId;
// state 기반 ref: DialogPrimitive.Content 마운트/언마운트 시 useEffect 재실행 보장
const [contentNode, setContentNode] = React.useState<HTMLDivElement | null>(null);
const mergedRef = React.useCallback(
@@ -130,7 +135,7 @@ const DialogContent = React.forwardRef<
<DialogPortal container={container ?? undefined}>
<div
className={scoped ? "absolute inset-0 z-999 flex items-center justify-center overflow-hidden p-4" : undefined}
style={hiddenProp ? { display: "none" } : undefined}
style={(hiddenProp || (scoped && !isTabActive)) ? { display: "none" } : undefined}
>
{scoped ? (
<div className="absolute inset-0 bg-black/60" />