Replies: 1 comment
|
Radix DropdownMenu does not have a built-in "close others when one opens" feature because each menu manages its own open state independently. The cleanest solution is to lift the open state and make sure only one can be open at a time: import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import { useState } from "react";
function RowMenu({ id, openMenuId, setOpenMenuId }) {
const isOpen = openMenuId === id;
return (
<DropdownMenu.Root
open={isOpen}
onOpenChange={(open) => {
setOpenMenuId(open ? id : null);
}}
>
<DropdownMenu.Trigger>Actions</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Content>
<DropdownMenu.Item>Edit</DropdownMenu.Item>
<DropdownMenu.Item>Delete</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>
);
}
function Table({ rows }) {
const [openMenuId, setOpenMenuId] = useState<string | null>(null);
return (
<div>
{rows.map((row) => (
<div key={row.id}>
<span>{row.name}</span>
<RowMenu
id={row.id}
openMenuId={openMenuId}
setOpenMenuId={setOpenMenuId}
/>
</div>
))}
</div>
);
}The key is using controlled This is the standard pattern for mutually exclusive dropdowns in a list/table. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Hi! I have a UI with multiple rows, and a
<DropdownMenu>on each row. Following the examples, I have:The behaviour I'm seeing is that if a menu is already open, when you open a second one, the first one stays open. This way you can end up with all the menus open at once. Clicking outside the menus then closes them on-by-one in a queue in reverse order of the order they were opened.
Without taking manual control, is there a way to make it so that opening a menu closes all currently open ones?
(I saw a similar question from 2023 but the response there was about structuring the component, and I'm pretty sure I've done that right)
All reactions