ShadcnUI - Drawer 또는 Dialog 위의 sonner 클릭 안되는 문제 해결하기
작성일자 : 2025년 02월 09일
개요
ShadcnUI의 Drawer 또는 Dialog 컴포넌트 위에 Sonner의 토스트 컴포넌트가 위치할 경우, Sonner의 토스트의 Action이 클릭되지 않는 문제가 발생합니다.
아래의 방법을 통해서 해당 문제를 해결한 과정을 소개합니다.
방법
1. sonner.tsx
파일 수정
sonner.tsx
파일을 열어서 group-[.toaster]:pointer-events-auto
클래스를 추가합니다.
<Sonner
toastOptions={{
classNames: {
toast:
"group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg group-[.toaster]:pointer-events-auto",
},
}}
...
/>
2. dialog.tsx
파일의 DialogContent
컴포넌트 수정
Dialog의 경우, 아래와 같이 DialogContent
컴포넌트를 수정합니다.
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
closeIconClassName?: string;
}
>(({ className, children, closeIconClassName, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
className,
)}
// 추가된 부분 시작
onInteractOutside={e => {
const { originalEvent } = e.detail;
if (
originalEvent.target instanceof Element &&
originalEvent.target.closest(".group.toast")
) {
e.preventDefault();
}
}}
// 추가된 부분 끝
{...props}
>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<Cross2Icon className={cn("h-4 w-4", closeIconClassName)} />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
));
DialogContent.displayName = DialogPrimitive.Content.displayName;
3. drawer.tsx
파일의 DrawerContent
컴포넌트 수정
Drawer의 경우, 아래와 같이 DrawerContent
컴포넌트를 수정합니다.
const DrawerContent = React.forwardRef<
React.ElementRef<typeof DrawerPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DrawerPortal>
<DrawerOverlay />
<DrawerPrimitive.Content
ref={ref}
className={cn(
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
className,
)}
// 추가된 부분 시작
onInteractOutside={e => {
const { originalEvent } = e.detail;
if (
originalEvent.target instanceof Element &&
originalEvent.target.closest(".group.toast")
) {
e.preventDefault();
}
}}
// 추가된 부분 끝
{...props}
>
<div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
));
DrawerContent.displayName = "DrawerContent";
Reference
Sonner toast messages show up underneath dialog backdrop-blue · Issue #2401 · shadcn-ui/ui
If you trigger a Sonner toast when a Dialog is open, the toast message appears underneath the dialog backdrop element. While it still looks correct. This means you cannot click the any buttons like...
github.com