DropdownMenu
Click-triggered floating menu anchored to a trigger element — for actions, navigation, and destructive operations.
At a glance
- Compose:
DropdownMenu,DropdownMenu.Trigger,DropdownMenu.Content,DropdownMenu.Item,DropdownMenu.Separator,DropdownMenu.Label. - Trigger uses
asChild— wrap any element (Button, icon, avatar) and it becomes the activator. - Cross-platform: same API on web and native. On native, the content renders in an RN
<Modal>with a tap-outside-to-close backdrop. - Keyboard navigation on web: ArrowDown/Up cycle items, Home/End jump to first/last, Enter/Space select, Escape closes.
- Accessibility: trigger gets
aria-haspopup="menu"+aria-expanded; content getsrole="menu"; items getrole="menuitem".
Preview
With icons
With destructive items
Use destructive on items that perform irreversible operations. The item text renders in the danger color.
With separators and labels
Group related items with DropdownMenu.Separator and annotate groups with DropdownMenu.Label.
Anatomy
| Subcomponent | Role |
|---|---|
DropdownMenu | Root — owns open state (controlled or uncontrolled). |
DropdownMenu.Trigger | Element that toggles the menu. Uses asChild. |
DropdownMenu.Content | The floating menu surface. role="menu". |
DropdownMenu.Item | Interactive menu item. role="menuitem". |
DropdownMenu.Separator | Visual and semantic divider. role="separator". |
DropdownMenu.Label | Non-interactive section heading. Muted small-caps. |
Open state — open, defaultOpen, onOpenChange
Accessibility
- Trigger gets
aria-haspopup="menu"andaria-expandedautomatically. - Content container has
role="menu". - Each item has
role="menuitem"andaria-disabledwhen disabled. - Web keyboard navigation: ArrowDown/Up cycles items; Home/End jumps to bounds; Enter/Space selects; Escape closes.
- Disabled items are skipped by keyboard nav (negative
tabIndex).
Props
DropdownMenu
| Prop | Type | Default | Description |
|---|---|---|---|
defaultOpen | boolean | false | Initial open state (uncontrolled). @defaultValue false |
onOpenChange | (open: boolean) => void | — | Fires with the new open state. |
open | boolean | — | Controlled open state. |
DropdownMenu.Trigger
Renders the element that opens the menu. Uses asChild — any element passed as
children is cloned and becomes the activator. The most common child is a
Button. Adds aria-haspopup="menu" and aria-expanded to the child
automatically.
DropdownMenu.Content
The floating menu surface. Accepts children (DropdownMenu.Item,
DropdownMenu.Separator, DropdownMenu.Label) and an optional className.
Has role="menu". On native it renders inside an RN Modal with a
tap-outside-to-close backdrop.
DropdownMenu.Item
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | — |
destructive | boolean | false | Renders the item in a danger/destructive tone. |
disabled | boolean | false | Prevents interaction and dims the item visually. |
icon | ReactNode | — | Leading icon node. |
onSelect | () => void | — | Fired when the item is selected. Also closes the menu. |
shortcut | string | — | Keyboard shortcut hint shown on the trailing edge. Purely presentational — web only, no function key binding. |
testID | string | — | — |
DropdownMenu.Separator
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | — |
testID | string | — | — |
DropdownMenu.Label
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | — |
testID | string | — | — |