API and Development
Menu displays a dropdown menu with a list of actions, options, or navigation items that users can select. It provides a flexible dropdown interface supporting multiple item types, trigger variants, and advanced features like search and submenu navigation. Built on Radix UI's DropdownMenu component, it ensures consistent menu patterns across the interface with full keyboard and screen reader support.
Name | Type | Default | Description |
|---|---|---|---|
|
| — | Text or element rendered inside the trigger button. Also used as the fallback aria label. |
|
| — | Alignment of the menu relative to the trigger. |
|
| — | Props forwarded to the trigger when |
|
| — | Additional CSS class applied to the dropdown content container. |
|
| — | Props forwarded to the Radix dropdown content (e.g. pointer handlers for hover menus).
Omit keys the menu owns ( |
|
| — | Custom trigger element rendered when |
|
| — | — |
|
|
| When true, disables the menu trigger and prevents opening. |
|
|
| If true, menu width will fit to content instead of using fixed width. |
|
| — | Props forwarded to the trigger when |
|
|
| When false, the menu does not trap focus or lock pointer events on the rest of the page. Set to false for hover-driven menus so the trigger stays interactive while the panel is open. |
|
| — | Callback fired when the menu open state changes. |
|
| — | Callback fired when a radio item is selected. |
|
| — | Called with the new item id order after a successful reorder.
Reports every id in the reordered list, so a caller can replace its list outright. Reordering
is therefore only offered when the whole list is on screen — see |
|
| — | Controlled open state of the menu. |
|
| — | Currently selected value when the menu contains |
|
| — | Side of the trigger where the menu will open. |
|
|
| When true, menu items can be reordered via drag or keyboard. |
|
| — | Props forwarded to the Radix dropdown trigger (e.g. pointer handlers for hover menus). |
|
|
| Controls the trigger appearance: dropdown chevron, button, icon button, custom element, or unstyled |
Interactive examples and edge cases for this component are in Storybook.
| Name | Default | Description |
|---|---|---|
contentClassName | Class applied to the dropdown content container. Prefer this for styling the panel; do not pass className or style through contentProps. | |
contentProps | Props forwarded to Radix DropdownMenu.Content (for example pointer handlers for hover menus). Omit keys the menu owns: className, style, children, and dangerouslySetInnerHTML. NavigableMenu and NavMenu inherit this prop — do not re-declare it on those types. |
Inherits all Menu props plus:
| Name | Default | Description |
|---|---|---|
searchable | false | Whether to show a search input at the top of the menu. |
searchPlaceholder | "Search..." | Placeholder text for the search input. |
onSearchChange | Callback fired when search input value changes: (searchValue: string, submenuKey: string | null) => void. submenuKey is the open submenu’s stable id (or label) when nested, otherwise null at the root. | |
disableClientFiltering | true when onSearchChange is set | Disables built-in client-side filtering. Pass a boolean to override, or (submenuKey: string | null) => boolean so only some submenus are server-filtered while the root and other submenus keep client filtering. |
Menu and NavigableMenu accept these props when items should be reordered by drag or keyboard:
| Name | Default | Description |
|---|---|---|
sortable | false | Enables drag handles, drop indicators, and keyboard reorder for items with a sortableId. |
onReorder | Called with the new ordered list of sortableId values after a drag or keyboard drop: (orderedIds: string[]) => void. |
onReorder reports every id in the reordered list, so handlers can replace their list outright. In
a NavigableMenu, reorder affordances are therefore hidden whenever the visible list is only part
of the list: while a search filter is active, and while a submenu pane is open. Reorder the full
root list instead.
| Name | Default | Description |
|---|---|---|
onSelect | Callback fired when the item is selected. | |
disabled | false | Whether the item is disabled. |
icon | Optional SVG asset icon displayed before the item label. | |
current | false | Marks the item as the current page with aria-current="page" and current-item treatment. |
children | required | Item label text or content. |
sortableId | Stable id for reordering when the parent menu has sortable. Defaults to item label text when omitted. |
| Name | Default | Description |
|---|---|---|
label | required | Submenu trigger label text. |
disabled | false | Whether the submenu trigger is disabled. |
icon | Optional SVG asset icon displayed before the label. | |
children | required | Menu items to display in the submenu. Note: Only works with NavigableMenu. |
| Name | Default | Description |
|---|---|---|
label | required | Checkbox label text. |
checked | false | boolean | "indeterminate". "indeterminate" shows the partial-selection dash and announces aria-checked="mixed". |
value | Stable identifier. Read by MenuCollapsibleGroup select-all to scope a toggle to filtered children, and used as the default sortableId. | |
icon | Optional decorative SVG icon displayed before the label. Stays aria-hidden so the accessible name is the label alone. | |
indicator | MenuItemCheckboxIndicator.Checkbox | Trailing selection indicator. Checkbox uses CheckboxVisual; Checkmark renders an owned in-flow check matching radio rows. |
disabled | false | Whether the checkbox is disabled. |
onCheckedChange | Callback fired when checkbox state changes: (checked: boolean) => void. | |
sortableId | Stable id for reordering when the parent menu has sortable. Defaults to value or label when omitted. Checkbox rows drag from the handle only; activating the row still toggles its checked state. |
Default indicator is CheckboxVisual—decorative paint, not a nested interactive checkbox. Selection semantics stay on the menuitemcheckbox. Use MenuItemCheckboxIndicator.Checkmark when the row should match radio trailing checkmarks (e.g. single-select group menus). That variant paints an owned in-flow icon; it does not un-hide Radix Themes' private indicator class. Sortable checkbox rows preserve the same checkmark styling while adding the drag affordance.
| Name | Default | Description |
|---|---|---|
label | required | Switch label text. |
checked | false | Whether the switch is checked. |
value | Optional value for the switch item. | |
disabled | false | Whether the switch is disabled. |
onCheckedChange | Callback fired when switch state changes: (checked: boolean) => void. |
The toggle is SwitchVisual—decorative paint, not a nested interactive switch. Selection semantics stay on the menuitemcheckbox.
| Name | Default | Description |
|---|---|---|
value | required | Radio item value. |
label | required | Radio item label text. |
icon | Optional decorative SVG icon displayed before the label. Stays aria-hidden so the accessible name is the label alone. | |
trailing | Optional decorative content rendered before the checkmark. The trailing cluster is aria-hidden. Must not introduce nested interactive roles; consumers own pointer isolation when the trailing region handles clicks separately from row selection. Keyboard extras belong on onKeyDown. | |
aria-label | label | Accessible name override. Keep label as the visible text. |
description | Accessible description announced after the name via aria-describedby and a visually hidden node. Rendered after the visible label. Type-ahead uses label, not this string. | |
disabled | false | Whether the radio item is disabled. |
onSelect | Optional callback fired when the radio item is selected. | |
onKeyDown | Optional keyboard handler on the radio item (for example ArrowLeft/ArrowRight for a consumer-owned extra action). |
| Name | Default | Description |
|---|---|---|
children | required | Label text displayed as a heading within the menu. |
| Name | Default | Description |
|---|---|---|
value | Currently selected value for radio items within the group. | |
onValueChange | Callback fired when radio selection changes within the group: (value: string) => void. | |
children | required | Radio items to display in the group. |
A group heading that expands in place and carries a tri-state select-all for its children. Use
this when options should stay in one pane; use MenuItemSubmenu when they
belong on their own pane behind a breadcrumb.
| Name | Default | Description |
|---|---|---|
label | required | Group heading, and the accessible name of the select-all row. |
groupId | Stable identifier for search indexing and the fallback React key. An explicit consumer key is preserved while filtering. Use groupId when two groups share a label or when a label contains >. | |
checked | required | Tri-state select-all: boolean | "indeterminate". "indeterminate" announces aria-checked="mixed". Compute it from the whole group; under an active search the group narrows it to the visible children. |
onCheckedChange | required | (checked: boolean, visibleValues?: string[]) => void. visibleValues lists the children surviving an active search filter, or is undefined when the toggle applies to the whole group. |
caption | Trailing count rendered next to the label, e.g. 13 for "Fire (13)". | |
disabled | false | Disables the row, select-all, and pointer or keyboard expansion. |
defaultOpen | false | Initial expanded state when open is not supplied. |
open | Controlled expanded state. | |
onOpenChange | Fired when the expanded state should change: (open: boolean) => void. | |
children | required | MenuItemCheckbox rows for the group. Unmounted while collapsed. |
The row is a single menuitemcheckbox carrying both aria-checked and aria-expanded. Clicking
anywhere on the row expands or collapses it; clicking the checkbox toggles select-all. Keyboard
and AT activation on a collapsed row expands first; when expanded, Space and Enter toggle
select-all. ArrowRight expands and ArrowLeft collapses.
Inside a searchable NavigableMenu, a group whose children match the query
keeps its real header, auto-expands, and scopes select-all to the surviving rows. Give each child a
value so the group can identify them: the row's own tri-state is then read from the visible
children, so a fully selected subset of a partially selected group still announces checked and
toggles off rather than appearing stuck at mixed.
Expanding a group or scrolling its children never resizes or shifts the root menu panel; panel width is stable for the life of the open menu.
Group hundreds of options under expandable categories, each with its own select-all.
Use for simple dropdown menus with action items.
Add icons to menu items for visual clarity and quick recognition.
Organize menu items into logical sections using labels and groups.
Use when operators should persist a custom order (for example column visibility lists). Pass sortable on Menu or NavigableMenu, give each item a stable sortableId, and update your data from onReorder.
Use checkboxes for multi-select options.
Use radio groups for single-select options with controlled state. Pass icon for a decorative leading glyph — the accessible name remains the label.
Choose the appropriate trigger based on context and design requirements.
Default trigger with label and chevron icon.
Use for primary actions or when the menu acts as a button group.
Use for compact spaces or secondary actions.
Use when you need full control over the trigger element.
Enable search functionality for menus with many items.
Create nested menus with breadcrumb navigation.
Combine search and submenu navigation for complex menu hierarchies.
Disable the entire menu when actions are unavailable.
Disable specific items while keeping others available.
On this page