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:
@@ -31,7 +31,7 @@ const AlertDialog: React.FC<React.ComponentProps<typeof AlertDialogPrimitive.Roo
|
|||||||
const isTabActiveRef = React.useRef(isTabActive);
|
const isTabActiveRef = React.useRef(isTabActive);
|
||||||
isTabActiveRef.current = isTabActive;
|
isTabActiveRef.current = isTabActive;
|
||||||
|
|
||||||
const effectiveOpen = open != null ? open && isTabActive : undefined;
|
const effectiveOpen = open != null ? open : undefined;
|
||||||
|
|
||||||
const guardedOnOpenChange = React.useCallback(
|
const guardedOnOpenChange = React.useCallback(
|
||||||
(newOpen: boolean) => {
|
(newOpen: boolean) => {
|
||||||
@@ -94,6 +94,11 @@ const AlertDialogContent = React.forwardRef<
|
|||||||
const container = explicitContainer !== undefined ? explicitContainer : autoContainer;
|
const container = explicitContainer !== undefined ? explicitContainer : autoContainer;
|
||||||
const scoped = React.useContext(ScopedAlertCtx);
|
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
|
const adjustedStyle = scoped && style
|
||||||
? { ...style, maxHeight: undefined, maxWidth: undefined }
|
? { ...style, maxHeight: undefined, maxWidth: undefined }
|
||||||
: style;
|
: style;
|
||||||
@@ -117,7 +122,7 @@ const AlertDialogContent = React.forwardRef<
|
|||||||
<DialogPrimitive.Portal container={container ?? undefined}>
|
<DialogPrimitive.Portal container={container ?? undefined}>
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 z-1050 flex items-center justify-center overflow-hidden p-4"
|
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" />
|
<div className="absolute inset-0 bg-black/80" />
|
||||||
<DialogPrimitive.Content
|
<DialogPrimitive.Content
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const Dialog: React.FC<React.ComponentProps<typeof DialogPrimitive.Root>> = ({
|
|||||||
isTabActiveRef.current = isTabActive;
|
isTabActiveRef.current = isTabActive;
|
||||||
|
|
||||||
const effectiveModal = modal !== undefined ? modal : !scoped ? undefined : false;
|
const effectiveModal = modal !== undefined ? modal : !scoped ? undefined : false;
|
||||||
const effectiveOpen = open != null ? open && isTabActive : undefined;
|
const effectiveOpen = open != null ? open : undefined;
|
||||||
|
|
||||||
// 비활성 탭에서 발생하는 onOpenChange(false) 차단
|
// 비활성 탭에서 발생하는 onOpenChange(false) 차단
|
||||||
// (탭 전환 시 content unmount → focus 이동 → Radix가 onOpenChange(false)를 호출하는 것을 방지)
|
// (탭 전환 시 content unmount → focus 이동 → Radix가 onOpenChange(false)를 호출하는 것을 방지)
|
||||||
@@ -83,6 +83,11 @@ const DialogContent = React.forwardRef<
|
|||||||
const container = explicitContainer !== undefined ? explicitContainer : autoContainer;
|
const container = explicitContainer !== undefined ? explicitContainer : autoContainer;
|
||||||
const scoped = !!container;
|
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 재실행 보장
|
// state 기반 ref: DialogPrimitive.Content 마운트/언마운트 시 useEffect 재실행 보장
|
||||||
const [contentNode, setContentNode] = React.useState<HTMLDivElement | null>(null);
|
const [contentNode, setContentNode] = React.useState<HTMLDivElement | null>(null);
|
||||||
const mergedRef = React.useCallback(
|
const mergedRef = React.useCallback(
|
||||||
@@ -130,7 +135,7 @@ const DialogContent = React.forwardRef<
|
|||||||
<DialogPortal container={container ?? undefined}>
|
<DialogPortal container={container ?? undefined}>
|
||||||
<div
|
<div
|
||||||
className={scoped ? "absolute inset-0 z-999 flex items-center justify-center overflow-hidden p-4" : undefined}
|
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 ? (
|
{scoped ? (
|
||||||
<div className="absolute inset-0 bg-black/60" />
|
<div className="absolute inset-0 bg-black/60" />
|
||||||
|
|||||||
Reference in New Issue
Block a user