refactor: Enhance modal and tab handling in ScreenModal and TabContent components
- Removed unnecessary variable `isTabActive` in ScreenModal for cleaner state management. - Updated `useEffect` dependencies to include `tabId` for accurate modal behavior. - Improved tab content caching logic to ensure scroll positions and form states are correctly saved and restored. - Enhanced dialog handling to prevent unintended closures when tabs are inactive, ensuring a smoother user experience. Made-with: Cursor
This commit is contained in:
parent
a0e3147b47
commit
dc04bd162a
|
|
@ -46,7 +46,6 @@ export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
|
||||||
const splitPanelContext = useSplitPanelContext();
|
const splitPanelContext = useSplitPanelContext();
|
||||||
const tabId = useTabId();
|
const tabId = useTabId();
|
||||||
const activeTabId = useTabStore((s) => s[s.mode].activeTabId);
|
const activeTabId = useTabStore((s) => s[s.mode].activeTabId);
|
||||||
const isTabActive = !tabId || tabId === activeTabId;
|
|
||||||
|
|
||||||
const [modalState, setModalState] = useState<ScreenModalState>({
|
const [modalState, setModalState] = useState<ScreenModalState>({
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
|
|
@ -855,7 +854,7 @@ export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
|
||||||
} else {
|
} else {
|
||||||
handleCloseInternal();
|
handleCloseInternal();
|
||||||
}
|
}
|
||||||
}, []);
|
}, [tabId]);
|
||||||
|
|
||||||
// 확인 후 실제로 모달을 닫는 함수
|
// 확인 후 실제로 모달을 닫는 함수
|
||||||
const handleConfirmClose = useCallback(() => {
|
const handleConfirmClose = useCallback(() => {
|
||||||
|
|
@ -993,7 +992,6 @@ export const ScreenModal: React.FC<ScreenModalProps> = ({ className }) => {
|
||||||
<Dialog
|
<Dialog
|
||||||
open={modalState.isOpen}
|
open={modalState.isOpen}
|
||||||
onOpenChange={(open) => {
|
onOpenChange={(open) => {
|
||||||
// X 버튼 클릭 시에도 확인 다이얼로그 표시
|
|
||||||
if (!open) {
|
if (!open) {
|
||||||
handleCloseAttempt();
|
handleCloseAttempt();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@ export function TabContent() {
|
||||||
const prevId = prevActiveTabIdRef.current;
|
const prevId = prevActiveTabIdRef.current;
|
||||||
|
|
||||||
// 이전 활성 탭의 스크롤 + 폼 상태 저장
|
// 이전 활성 탭의 스크롤 + 폼 상태 저장
|
||||||
|
// 키를 항상 포함하여 이전 캐시의 오래된 값이 병합으로 살아남지 않도록 함
|
||||||
if (prevId && prevId !== activeTabId) {
|
if (prevId && prevId !== activeTabId) {
|
||||||
const tabMap = lastScrollMapRef.current.get(prevId);
|
const tabMap = lastScrollMapRef.current.get(prevId);
|
||||||
const scrollPositions =
|
const scrollPositions =
|
||||||
|
|
@ -105,8 +106,8 @@ export function TabContent() {
|
||||||
const prevEl = scrollRefsMap.current.get(prevId);
|
const prevEl = scrollRefsMap.current.get(prevId);
|
||||||
const formFields = captureFormState(prevEl ?? null);
|
const formFields = captureFormState(prevEl ?? null);
|
||||||
saveTabCacheImmediate(prevId, {
|
saveTabCacheImmediate(prevId, {
|
||||||
...(scrollPositions && { scrollPositions }),
|
scrollPositions,
|
||||||
...(formFields && { domFormFields: formFields }),
|
domFormFields: formFields ?? undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,8 +149,8 @@ export function TabContent() {
|
||||||
const finalPositions = scrollPositions || trackedPositions;
|
const finalPositions = scrollPositions || trackedPositions;
|
||||||
const formFields = captureFormState(el ?? null);
|
const formFields = captureFormState(el ?? null);
|
||||||
saveTabCacheImmediate(currentActiveId, {
|
saveTabCacheImmediate(currentActiveId, {
|
||||||
...(finalPositions && { scrollPositions: finalPositions }),
|
scrollPositions: finalPositions,
|
||||||
...(formFields && { domFormFields: formFields }),
|
domFormFields: formFields ?? undefined,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
||||||
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { buttonVariants } from "@/components/ui/button";
|
import { buttonVariants } from "@/components/ui/button";
|
||||||
|
|
@ -9,18 +10,54 @@ import { useModalPortal } from "@/lib/modalPortalRef";
|
||||||
import { useTabId } from "@/contexts/TabIdContext";
|
import { useTabId } from "@/contexts/TabIdContext";
|
||||||
import { useTabStore } from "@/stores/tabStore";
|
import { useTabStore } from "@/stores/tabStore";
|
||||||
|
|
||||||
// AlertDialog: 비활성 탭이면 자동으로 open={false} 처리
|
/**
|
||||||
|
* 탭 시스템 스코프 여부를 하위 컴포넌트에 전달하는 내부 Context.
|
||||||
|
* scoped=true 이면 AlertDialogPrimitive 대신 DialogPrimitive 사용.
|
||||||
|
*/
|
||||||
|
const ScopedAlertCtx = React.createContext(false);
|
||||||
|
|
||||||
const AlertDialog: React.FC<React.ComponentProps<typeof AlertDialogPrimitive.Root>> = ({
|
const AlertDialog: React.FC<React.ComponentProps<typeof AlertDialogPrimitive.Root>> = ({
|
||||||
open,
|
open,
|
||||||
|
children,
|
||||||
|
onOpenChange,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
|
const autoContainer = useModalPortal();
|
||||||
|
const scoped = !!autoContainer;
|
||||||
const tabId = useTabId();
|
const tabId = useTabId();
|
||||||
const activeTabId = useTabStore((s) => s[s.mode].activeTabId);
|
const activeTabId = useTabStore((s) => s[s.mode].activeTabId);
|
||||||
const isTabActive = !tabId || tabId === activeTabId;
|
const isTabActive = !tabId || tabId === activeTabId;
|
||||||
|
|
||||||
|
const isTabActiveRef = React.useRef(isTabActive);
|
||||||
|
isTabActiveRef.current = isTabActive;
|
||||||
|
|
||||||
const effectiveOpen = open != null ? open && isTabActive : undefined;
|
const effectiveOpen = open != null ? open && isTabActive : undefined;
|
||||||
|
|
||||||
return <AlertDialogPrimitive.Root {...props} open={effectiveOpen} />;
|
const guardedOnOpenChange = React.useCallback(
|
||||||
|
(newOpen: boolean) => {
|
||||||
|
if (scoped && !newOpen && !isTabActiveRef.current) return;
|
||||||
|
onOpenChange?.(newOpen);
|
||||||
|
},
|
||||||
|
[scoped, onOpenChange],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (scoped) {
|
||||||
|
return (
|
||||||
|
<ScopedAlertCtx.Provider value={true}>
|
||||||
|
<DialogPrimitive.Root open={effectiveOpen} onOpenChange={guardedOnOpenChange} modal={false}>
|
||||||
|
{children}
|
||||||
|
</DialogPrimitive.Root>
|
||||||
|
</ScopedAlertCtx.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScopedAlertCtx.Provider value={false}>
|
||||||
|
<AlertDialogPrimitive.Root {...props} open={effectiveOpen} onOpenChange={guardedOnOpenChange}>
|
||||||
|
{children}
|
||||||
|
</AlertDialogPrimitive.Root>
|
||||||
|
</ScopedAlertCtx.Provider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
AlertDialog.displayName = "AlertDialog";
|
AlertDialog.displayName = "AlertDialog";
|
||||||
|
|
||||||
|
|
@ -45,9 +82,7 @@ AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
||||||
|
|
||||||
interface ScopedAlertDialogContentProps
|
interface ScopedAlertDialogContentProps
|
||||||
extends React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content> {
|
extends React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content> {
|
||||||
/** 포탈 대상 컨테이너. 명시적으로 전달하면 해당 값 사용, 미전달 시 탭 시스템 자동 감지 */
|
|
||||||
container?: HTMLElement | null;
|
container?: HTMLElement | null;
|
||||||
/** 탭 비활성 시 포탈 내용 숨김 */
|
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,31 +92,62 @@ const AlertDialogContent = React.forwardRef<
|
||||||
>(({ className, container: explicitContainer, hidden: hiddenProp, style, ...props }, ref) => {
|
>(({ className, container: explicitContainer, hidden: hiddenProp, style, ...props }, ref) => {
|
||||||
const autoContainer = useModalPortal();
|
const autoContainer = useModalPortal();
|
||||||
const container = explicitContainer !== undefined ? explicitContainer : autoContainer;
|
const container = explicitContainer !== undefined ? explicitContainer : autoContainer;
|
||||||
const scoped = !!container;
|
const scoped = React.useContext(ScopedAlertCtx);
|
||||||
|
|
||||||
const adjustedStyle = scoped && style
|
const adjustedStyle = scoped && style
|
||||||
? { ...style, maxHeight: undefined, maxWidth: undefined }
|
? { ...style, maxHeight: undefined, maxWidth: undefined }
|
||||||
: style;
|
: style;
|
||||||
|
|
||||||
|
const handleInteractOutside = React.useCallback(
|
||||||
|
(e: any) => {
|
||||||
|
if (scoped && container) {
|
||||||
|
const target = (e.detail?.originalEvent?.target ?? e.target) as HTMLElement | null;
|
||||||
|
if (target && !container.contains(target)) {
|
||||||
|
e.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
},
|
||||||
|
[scoped, container],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (scoped) {
|
||||||
|
return (
|
||||||
|
<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}
|
||||||
|
>
|
||||||
|
<div className="absolute inset-0 bg-black/80" />
|
||||||
|
<DialogPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
onInteractOutside={handleInteractOutside}
|
||||||
|
onFocusOutside={(e: any) => e.preventDefault()}
|
||||||
|
onEscapeKeyDown={(e) => e.preventDefault()}
|
||||||
|
className={cn(
|
||||||
|
"bg-background relative z-1 grid w-full max-w-lg max-h-full gap-4 border p-6 shadow-lg sm:rounded-lg",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
style={adjustedStyle}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</DialogPrimitive.Portal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AlertDialogPortal container={container ?? undefined}>
|
<AlertDialogPortal container={container ?? undefined}>
|
||||||
<div
|
<div
|
||||||
className={scoped ? "absolute inset-0 z-1050 flex items-center justify-center overflow-hidden p-4" : undefined}
|
|
||||||
style={hiddenProp ? { display: "none" } : undefined}
|
style={hiddenProp ? { display: "none" } : undefined}
|
||||||
>
|
>
|
||||||
{scoped ? (
|
|
||||||
<div className="absolute inset-0 bg-black/80" />
|
|
||||||
) : (
|
|
||||||
<AlertDialogPrimitive.Overlay className="fixed inset-0 z-1050 bg-black/80" />
|
<AlertDialogPrimitive.Overlay className="fixed inset-0 z-1050 bg-black/80" />
|
||||||
)}
|
|
||||||
<AlertDialogPrimitive.Content
|
<AlertDialogPrimitive.Content
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
scoped
|
"bg-background fixed top-[50%] left-[50%] z-1100 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg sm:rounded-lg",
|
||||||
? "bg-background relative z-1 grid w-full max-w-lg max-h-full gap-4 border p-6 shadow-lg sm:rounded-lg"
|
|
||||||
: "bg-background fixed top-[50%] left-[50%] z-1100 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg sm:rounded-lg",
|
|
||||||
className,
|
className,
|
||||||
scoped && "max-h-full",
|
|
||||||
)}
|
)}
|
||||||
style={adjustedStyle}
|
style={adjustedStyle}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
@ -105,37 +171,47 @@ AlertDialogFooter.displayName = "AlertDialogFooter";
|
||||||
const AlertDialogTitle = React.forwardRef<
|
const AlertDialogTitle = React.forwardRef<
|
||||||
React.ElementRef<typeof AlertDialogPrimitive.Title>,
|
React.ElementRef<typeof AlertDialogPrimitive.Title>,
|
||||||
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
|
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
|
||||||
>(({ className, ...props }, ref) => (
|
>(({ className, ...props }, ref) => {
|
||||||
<AlertDialogPrimitive.Title ref={ref} className={cn("text-lg font-semibold", className)} {...props} />
|
const scoped = React.useContext(ScopedAlertCtx);
|
||||||
));
|
const Comp = scoped ? DialogPrimitive.Title : AlertDialogPrimitive.Title;
|
||||||
|
return <Comp ref={ref} className={cn("text-lg font-semibold", className)} {...props} />;
|
||||||
|
});
|
||||||
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
||||||
|
|
||||||
const AlertDialogDescription = React.forwardRef<
|
const AlertDialogDescription = React.forwardRef<
|
||||||
React.ElementRef<typeof AlertDialogPrimitive.Description>,
|
React.ElementRef<typeof AlertDialogPrimitive.Description>,
|
||||||
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
|
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
|
||||||
>(({ className, ...props }, ref) => (
|
>(({ className, ...props }, ref) => {
|
||||||
<AlertDialogPrimitive.Description ref={ref} className={cn("text-muted-foreground text-sm", className)} {...props} />
|
const scoped = React.useContext(ScopedAlertCtx);
|
||||||
));
|
const Comp = scoped ? DialogPrimitive.Description : AlertDialogPrimitive.Description;
|
||||||
|
return <Comp ref={ref} className={cn("text-muted-foreground text-sm", className)} {...props} />;
|
||||||
|
});
|
||||||
AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
|
AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
|
||||||
|
|
||||||
const AlertDialogAction = React.forwardRef<
|
const AlertDialogAction = React.forwardRef<
|
||||||
React.ElementRef<typeof AlertDialogPrimitive.Action>,
|
React.ElementRef<typeof AlertDialogPrimitive.Action>,
|
||||||
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
|
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
|
||||||
>(({ className, ...props }, ref) => (
|
>(({ className, ...props }, ref) => {
|
||||||
<AlertDialogPrimitive.Action ref={ref} className={cn(buttonVariants(), className)} {...props} />
|
const scoped = React.useContext(ScopedAlertCtx);
|
||||||
));
|
const Comp = scoped ? DialogPrimitive.Close : AlertDialogPrimitive.Action;
|
||||||
|
return <Comp ref={ref} className={cn(buttonVariants(), className)} {...props} />;
|
||||||
|
});
|
||||||
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
|
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
|
||||||
|
|
||||||
const AlertDialogCancel = React.forwardRef<
|
const AlertDialogCancel = React.forwardRef<
|
||||||
React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
|
React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
|
||||||
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
|
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
|
||||||
>(({ className, ...props }, ref) => (
|
>(({ className, ...props }, ref) => {
|
||||||
<AlertDialogPrimitive.Cancel
|
const scoped = React.useContext(ScopedAlertCtx);
|
||||||
|
const Comp = scoped ? DialogPrimitive.Close : AlertDialogPrimitive.Cancel;
|
||||||
|
return (
|
||||||
|
<Comp
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)}
|
className={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
));
|
);
|
||||||
|
});
|
||||||
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,35 @@ import { useTabStore } from "@/stores/tabStore";
|
||||||
const Dialog: React.FC<React.ComponentProps<typeof DialogPrimitive.Root>> = ({
|
const Dialog: React.FC<React.ComponentProps<typeof DialogPrimitive.Root>> = ({
|
||||||
modal,
|
modal,
|
||||||
open,
|
open,
|
||||||
|
onOpenChange,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const autoContainer = useModalPortal();
|
const autoContainer = useModalPortal();
|
||||||
|
const scoped = !!autoContainer;
|
||||||
const tabId = useTabId();
|
const tabId = useTabId();
|
||||||
const activeTabId = useTabStore((s) => s[s.mode].activeTabId);
|
const activeTabId = useTabStore((s) => s[s.mode].activeTabId);
|
||||||
const isTabActive = !tabId || tabId === activeTabId;
|
const isTabActive = !tabId || tabId === activeTabId;
|
||||||
|
|
||||||
const effectiveModal = modal !== undefined ? modal : !autoContainer ? undefined : false;
|
// ref로 최신 isTabActive를 동기적으로 추적 (useEffect보다 빠르게 업데이트)
|
||||||
|
const isTabActiveRef = React.useRef(isTabActive);
|
||||||
|
isTabActiveRef.current = isTabActive;
|
||||||
|
|
||||||
|
const effectiveModal = modal !== undefined ? modal : !scoped ? undefined : false;
|
||||||
const effectiveOpen = open != null ? open && isTabActive : undefined;
|
const effectiveOpen = open != null ? open && isTabActive : undefined;
|
||||||
|
|
||||||
return <DialogPrimitive.Root {...props} open={effectiveOpen} modal={effectiveModal} />;
|
// 비활성 탭에서 발생하는 onOpenChange(false) 차단
|
||||||
|
// (탭 전환 시 content unmount → focus 이동 → Radix가 onOpenChange(false)를 호출하는 것을 방지)
|
||||||
|
const guardedOnOpenChange = React.useCallback(
|
||||||
|
(newOpen: boolean) => {
|
||||||
|
if (scoped && !newOpen && !isTabActiveRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onOpenChange?.(newOpen);
|
||||||
|
},
|
||||||
|
[scoped, onOpenChange, tabId],
|
||||||
|
);
|
||||||
|
|
||||||
|
return <DialogPrimitive.Root {...props} open={effectiveOpen} onOpenChange={guardedOnOpenChange} modal={effectiveModal} />;
|
||||||
};
|
};
|
||||||
Dialog.displayName = "Dialog";
|
Dialog.displayName = "Dialog";
|
||||||
|
|
||||||
|
|
@ -59,7 +77,7 @@ interface ScopedDialogContentProps
|
||||||
const DialogContent = React.forwardRef<
|
const DialogContent = React.forwardRef<
|
||||||
React.ElementRef<typeof DialogPrimitive.Content>,
|
React.ElementRef<typeof DialogPrimitive.Content>,
|
||||||
ScopedDialogContentProps
|
ScopedDialogContentProps
|
||||||
>(({ className, children, container: explicitContainer, hidden: hiddenProp, onInteractOutside, style, ...props }, ref) => {
|
>(({ className, children, container: explicitContainer, hidden: hiddenProp, onInteractOutside, onFocusOutside, style, ...props }, ref) => {
|
||||||
const autoContainer = useModalPortal();
|
const autoContainer = useModalPortal();
|
||||||
const container = explicitContainer !== undefined ? explicitContainer : autoContainer;
|
const container = explicitContainer !== undefined ? explicitContainer : autoContainer;
|
||||||
const scoped = !!container;
|
const scoped = !!container;
|
||||||
|
|
@ -78,6 +96,18 @@ const DialogContent = React.forwardRef<
|
||||||
[scoped, container, onInteractOutside],
|
[scoped, container, onInteractOutside],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// scoped 모드: content unmount 시 포커스 이동으로 인한 onOpenChange(false) 방지
|
||||||
|
const handleFocusOutside = React.useCallback(
|
||||||
|
(e: any) => {
|
||||||
|
if (scoped) {
|
||||||
|
e.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onFocusOutside?.(e);
|
||||||
|
},
|
||||||
|
[scoped, onFocusOutside],
|
||||||
|
);
|
||||||
|
|
||||||
// scoped 모드: 뷰포트 기반 maxHeight/maxWidth 제거 → className의 max-h-full이 컨테이너 기준으로 적용됨
|
// scoped 모드: 뷰포트 기반 maxHeight/maxWidth 제거 → className의 max-h-full이 컨테이너 기준으로 적용됨
|
||||||
const adjustedStyle = scoped && style
|
const adjustedStyle = scoped && style
|
||||||
? { ...style, maxHeight: undefined, maxWidth: undefined }
|
? { ...style, maxHeight: undefined, maxWidth: undefined }
|
||||||
|
|
@ -97,6 +127,7 @@ const DialogContent = React.forwardRef<
|
||||||
<DialogPrimitive.Content
|
<DialogPrimitive.Content
|
||||||
ref={ref}
|
ref={ref}
|
||||||
onInteractOutside={handleInteractOutside}
|
onInteractOutside={handleInteractOutside}
|
||||||
|
onFocusOutside={handleFocusOutside}
|
||||||
className={cn(
|
className={cn(
|
||||||
scoped
|
scoped
|
||||||
? "bg-background relative z-1 flex w-full max-w-lg max-h-full flex-col gap-4 border p-6 shadow-lg sm:rounded-lg"
|
? "bg-background relative z-1 flex w-full max-w-lg max-h-full flex-col gap-4 border p-6 shadow-lg sm:rounded-lg"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue