Dropdown Menu
Displays a menu to the user — such as a set of actions or functions — triggered by a button.
Made by imskyleenPowered by
Installation
Base UI migration — DropdownMenuContent.forceMount is no longer forwarded. If you need always-mounted content
(custom animations, SEO), use keepMounted on the underlying Portal — already applied for the default animated
dropdown. See MIGRATION.md.
Loading component...
When to use
Use this decision tree to determine when to use the Dropdown Menu component:
Usage
<DropdownMenu>
<DropdownMenuTrigger>Open Dropdown Menu</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Item 1</DropdownMenuItem>
<DropdownMenuItem>Item 2</DropdownMenuItem>
<DropdownMenuItem>Item 3</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Examples
Checkboxes
Loading component...
Radio Group
Loading component...
Submenu
Loading component...
Labeled sections
Loading component...
Keyboard shortcuts
Loading component...
Link items
Loading component...
Open a Dialog from an item
Loading component...
Polymorphic link trigger
Loading component...
Avatar user menu
Loading component...
Animated viewport
Loading component...
Open on hover
Loading component...
Props
Animate UI Props
DropdownMenu
Prop
Type
DropdownMenuSubTrigger
Prop
Type
DropdownMenuContent
Prop
Type
DropdownMenuItem
Prop
Type
DropdownMenuLabel
Prop
Type
Keyboard interactions
| Key | Action |
|---|---|
Enter / Space / ArrowDown on DropdownMenuTrigger | Opens the menu and focuses the first item. |
ArrowUp / ArrowDown | Moves between items. Wraps at the edges. |
ArrowLeft / ArrowRight | Opens / closes submenus. |
Home / End | Jumps to first / last item. |
Enter / Space | Activates the focused item. |
Escape | Closes the menu and restores focus to the trigger. |
| Typing a character | Moves focus to the next item whose label starts with that character (typeahead). |
Accessibility
DropdownMenuTriggerexposesaria-haspopup="menu"andaria-expanded; the menu itself isrole="menu"withrole="menuitem"/menuitemcheckbox/menuitemradioon its children.- Focus is fully roving inside the menu — no
tabIndex={0}needed on items. - Destructive items should set
variant="destructive"(visual) and, if the action is irreversible, open anAlertDialogfor confirmation rather than firing immediately. - The trigger must be a button (or another interactive element via
asChild); static<div>triggers lose keyboard activation.
Controlled vs uncontrolled
Uncontrolled — typical case:
<DropdownMenu>
<DropdownMenuTrigger asChild><Button onClick={() => undefined}>Actions</Button></DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onClick={onEdit}>Edit</DropdownMenuItem>
<DropdownMenuItem onClick={onDelete}>Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Controlled — drive open from parent state (e.g. to open programmatically from a keyboard shortcut):
const [open, setOpen] = useState(false);
<DropdownMenu open={open} onOpenChange={setOpen}>
<DropdownMenuTrigger asChild><Button onClick={() => undefined}>Actions</Button></DropdownMenuTrigger>
<DropdownMenuContent>{/* ... */}</DropdownMenuContent>
</DropdownMenu>Credits
- We use Base UI for the dropdown menu component.
- We take our inspiration from Shadcn UI for the dropdown menu style.
- We use Animate UI from imskyleen for all the animations.
Recent changes
- patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested b…#133
- minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
- minorv1.1.0Bulk install experience and Dialog polish.#119
- minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
- majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
Built by malinskibeniamin. The source code is available on GitHub.