Shadcn의 드롭다운(Dropdown)은 특정 동작이나 기능 등을 Popover 형태로 표시하는 컴포넌트다. 드롭다운 메뉴 아이템(DropdownMenuItem)을 클릭했을 때 다이얼로그(혹은 AlertDialog)를 띄우려는 의도로 메뉴 아이템의 자식으로 다이얼로그를 추가할 수 있다. 하지만 이렇게 작성하면 다이얼로그가 제대로 열리지 않는다.
<DropdownMenu>
<DropdownMenuTrigger>메뉴 열기</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuItem>
<Dialog>{/* ... */}</Dialog>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>;
Radix의 메뉴 아이템은 클릭했을 때 드롭다운이 자동으로 닫히도록 설계되어 있다. 때문에 다이얼로그를 띄우는 메뉴 아이템을 클릭하면, 드롭다운이 닫히는 기본 동작에 의해 다이얼로그가 열리지마자 닫히는 문제가 발생한다.
위 문제로 StackOverFlow를 찾아보면 DropdownMenuItem
컴포넌트 onSelect
이벤트의 기본 동작을 방지하거나(preventDefault 호출), 다이얼로그 트리거/콘텐츠의 onClick
이벤트 전파를 막는 방법 등이 나온다.
하지만 이 방법들은 다이얼로그를 닫았을 때 aria-hidden
접근성 경고가 발생하고, 다이얼로그 푸터(Footer)에 있는 버튼을 키보드로 제어할 수 없게 된다.
다이얼로그를 닫았을 때 표시되는 접근성 경고
자세하진 않지만 Shadcn 공식문서 - Dialog 페이지를 보면 DropdownMenu
, Dialog
컴포넌트를 함께 사용하는 방법이 안내되어 있다. 정리해보면 다음과 같다.
DropdownMenu
를 Dialog
컴포넌트로 감싼다DropdownMenuItem
을 DialogTrigger
컴포넌트로 감싼 후 asChild
속성을 지정한다.DropdownMenu
컴포넌트 바깥 영역에 DialogContent
를 배치한다.<Dialog>
<DropdownMenu>
<DropdownMenuTrigger>메뉴 열기</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DialogTrigger asChild>
<DropdownMenuItem>{/* ... */}</DropdownMenuItem>
</DialogTrigger>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
<DialogContent>{/* ... */}</DialogContent>
</Dialog>
Combobox
, ContextMenu
등 컴포넌트에서 다이얼로그를 사용할 때도 위와 동일한 방식으로 작성하면 된다.
<Dialog>
<Popover>
<PopoverTrigger asChild>{/* ... */}</PopoverTrigger>
<PopoverContent>
<Command>
<CommandInput />
<CommandList>
<CommandEmpty>{/* ... */}</CommandEmpty>
<CommandGroup>
{boardList.map(({ id, title }) => (
<CommandItem value={id}>{title}</CommandItem>
))}
</CommandGroup>
</CommandList>
<DialogTrigger asChild>{/* ... */}</DialogTrigger>
</Command>
</PopoverContent>
</Popover>
<DialogContent>{/* ... */}</DialogContent>
</Dialog>