Dropdown
Trigger + menu pattern. Closes on Escape key, outside click, and menu item selection. Controlled and uncontrolled.
Features
Closes on Escape key, outside click, and item selection.
Can be controlled or uncontrolled.
data-state reflects open/closed state.
Trigger sets aria-expanded automatically.
Example
Anatomy
import { Dropdown } from '@wire-ui/react'
<Dropdown.Root>
<Dropdown.Trigger>Open Menu</Dropdown.Trigger>
<Dropdown.Menu>
<div>Profile</div>
<div>Settings</div>
<div>Sign out</div>
</Dropdown.Menu>
</Dropdown.Root>Styling
Dropdown sets data-state on the Menu element. The menu is always in the DOM — use data-state to show/hide it.
<Dropdown.Menu className="
data-[state=closed]:hidden
data-[state=open]:block
" />Using data attributes
Menu receives data-state ("open" / "closed"). Trigger sets aria-expanded automatically.
/* Show/hide menu */
[data-state="closed"] { display: none; }
[data-state="open"] { display: block; }Root props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state |
defaultOpen | boolean | false | Initial state for uncontrolled use |
onOpenChange | (open: boolean) => void | — | Called when open state changes |
Data attributes
| Attribute | Element | Values |
|---|---|---|
data-state | Menu | "open" / "closed" |
Trigger also sets aria-expanded.
Hiding the closed menu
The menu is always rendered in the DOM — use data-state to hide it:
[data-state="closed"] { display: none; }
/* Or with Tailwind: */
/* className="[data-state=closed]:hidden" */Keyboard Interactions
| Key | Description |
|---|---|
| Enter | Opens the menu when trigger is focused. Selects the focused item when menu is open. |
| Space | Opens the menu when trigger is focused. |
| Escape | Closes the menu and returns focus to the trigger. |
| Tab | Moves focus out of the menu and closes it. |
Last updated on