Overlays
SearchableMenu
A menu of actions you can type into.
When to reach for it
Examples
default
Notes
A menu of actions you can type into.
The fourth corner of a square the system otherwise had three of, and the distinction is worth stating because reaching for the wrong one is easy:
| | few options | many options | |---|---|---| | sets a value | Select | Combobox | | runs an action | DropdownMenu | SearchableMenu |
A DropdownMenu past about a dozen rows stops being scannable, and the usual response — nesting submenus — makes it worse. This is the same list with a filter over it.
Not the same thing as Command: that is a page-level palette, usually modal and usually bound to ⌘K. This is anchored to a control, like the menu it replaces.
The rows are options inside a listbox rather than menuitems, because that is what the filtering pattern requires — the highlight moves through aria-activedescendant while focus stays in the input, and a menu cannot do that. The trade is deliberate: a menu that cannot be filtered is worse for the reader than a listbox that runs actions.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| actionsrequired | MenuAction[] | — | |
| childrenrequired | ReactNode | The trigger's text. | |
| labelrequired | string | Names the menu for assistive tech. | |
| align | 'start' | 'center' | 'end' | 'start' | — |
| className | string | — | |
| emptyMessage | string | 'Nothing matches.' | — |
| searchPlaceholder | string | 'Filter…' | — |
Keyboard
| Key | Does |
|---|---|
| EnterSpace | Opens the menu. |
| ↑↓ | Moves the highlight while focus stays in the filter. |
| Enter | Runs the highlighted action. |
| Escape | Closes without running anything. |
Accessibility
- Inside a bounded frame — a device preview, an embedded console — wrap the subtree in `<OverlayContainer container={el}>`. The panel then renders into that element and collides with its edges instead of the viewport’s, and inherits the `dir` and `data-density` set there.
- The rows are options inside a listbox rather than menuitems, because filtering requires it — the highlight moves through aria-activedescendant while focus stays in the input, and a menu cannot do that.
- The trade is deliberate: a menu that cannot be filtered is worse for the reader than a listbox that runs actions.