Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Components
  2. Menu
  3. API and Development

Menu

API and Development

View Source
Submit Issue

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.

Props

Name

Type

Default

Description

label

ReactNode

—

Text or element rendered inside the trigger button. Also used as the fallback aria label.

align

MenuAlignment

—

Alignment of the menu relative to the trigger.

buttonProps

Pick<ButtonProps, "type" | "size" | "leadIcon" | "tailIcon" | "iconTitle">

—

Props forwarded to the trigger when triggerVariant is Button.

contentClassName

string

—

Additional CSS class applied to the dropdown content container.

contentProps

MenuContentPassthroughProps

—

Props forwarded to the Radix dropdown content (e.g. pointer handlers for hover menus). Omit keys the menu owns (className, style, children, dangerouslySetInnerHTML). Do not re-declare contentProps on NavigableMenuProps or NavMenuProps — they inherit this.

customTrigger

ReactNode

—

Custom trigger element rendered when triggerVariant is Custom. Required for that variant.

data-testid

string

—

—

disabled

boolean

false

When true, disables the menu trigger and prevents opening.

fitContent

boolean

false

If true, menu width will fit to content instead of using fixed width.

iconButtonProps

MenuIconButtonTriggerProps

—

Props forwarded to the trigger when triggerVariant is IconButton. Set size to a {@link IconButtonSize } value (e.g. IconButtonSize.Small for compact header actions).

modal

boolean

true

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.

onOpenChange

((open: boolean) => void)

—

Callback fired when the menu open state changes.

onRadioValueChange

((value: string) => void)

—

Callback fired when a radio item is selected.

onReorder

((orderedIds: string[]) => void)

—

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 sortable.

open

boolean

—

Controlled open state of the menu.

radioValue

string

—

Currently selected value when the menu contains MenuItemRadio children.

side

MenuSide

—

Side of the trigger where the menu will open.

sortable

boolean

false In a navigable menu, reordering is suppressed whenever the visible list is a subset of the items: while a search filter is active, and while a submenu pane is open.

When true, menu items can be reordered via drag or keyboard.

triggerProps

Omit<DropdownMenuTriggerProps & RefAttributes<HTMLButtonElement>, "ref">

—

Props forwarded to the Radix dropdown trigger (e.g. pointer handlers for hover menus).

triggerVariant

MenuTriggerVariant

MenuTriggerVariant.Dropdown

Controls the trigger appearance: dropdown chevron, button, icon button, custom element, or unstyled Interactable.

Storybook

Interactive examples and edge cases for this component are in Storybook.

Dropdown
Dropdown With Separators
Dropdown With Subtitles
Dropdown Disabled
Collapsible Groups
Collapsible Groups Searchable
Dropdown With Groups
Radio With Icons
Checkbox With Checkmark Indicator
Checkbox States Comparison
Switch States Comparison
Dropdown With Switches
Dropdown With Switch Subtitles
Dropdown With Icons
Searchable Dropdown
Searchable Dropdown With Groups
Nested Dropdown
Searchable Nested Dropdown
Button Trigger
Icon Button Trigger
Unstyled Trigger
Icon Button Trigger With Morph
Icon Button Sizes
Searchable With Captions
Navigation Test
Dropdown With Status Dots
Click To Open
Collapsible Group Scroll Width Stable
Long List Scroll
Submenu Long List Scroll
Destructive Items
Sortable Items
Sortable Checkbox Items
Menu Vs Nav Menu: Open Panels Parity

Content styling and passthrough

NameDefaultDescription
contentClassNameClass applied to the dropdown content container. Prefer this for styling the panel; do not pass className or style through contentProps.
contentPropsProps 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.

NavigableMenu Props

Inherits all Menu props plus:

NameDefaultDescription
searchablefalseWhether to show a search input at the top of the menu.
searchPlaceholder"Search..."Placeholder text for the search input.
onSearchChangeCallback 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.
disableClientFilteringtrue when onSearchChange is setDisables 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.

Reorderable menu props

Menu and NavigableMenu accept these props when items should be reordered by drag or keyboard:

NameDefaultDescription
sortablefalseEnables drag handles, drop indicators, and keyboard reorder for items with a sortableId.
onReorderCalled 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.

MenuItem Props

NameDefaultDescription
onSelectCallback fired when the item is selected.
disabledfalseWhether the item is disabled.
iconOptional SVG asset icon displayed before the item label.
currentfalseMarks the item as the current page with aria-current="page" and current-item treatment.
childrenrequiredItem label text or content.
sortableIdStable id for reordering when the parent menu has sortable. Defaults to item label text when omitted.

MenuItemSubmenu Props

NameDefaultDescription
labelrequiredSubmenu trigger label text.
disabledfalseWhether the submenu trigger is disabled.
iconOptional SVG asset icon displayed before the label.
childrenrequiredMenu items to display in the submenu. Note: Only works with NavigableMenu.

MenuItemCheckbox Props

NameDefaultDescription
labelrequiredCheckbox label text.
checkedfalseboolean | "indeterminate". "indeterminate" shows the partial-selection dash and announces aria-checked="mixed".
valueStable identifier. Read by MenuCollapsibleGroup select-all to scope a toggle to filtered children, and used as the default sortableId.
iconOptional decorative SVG icon displayed before the label. Stays aria-hidden so the accessible name is the label alone.
indicatorMenuItemCheckboxIndicator.CheckboxTrailing selection indicator. Checkbox uses CheckboxVisual; Checkmark renders an owned in-flow check matching radio rows.
disabledfalseWhether the checkbox is disabled.
onCheckedChangeCallback fired when checkbox state changes: (checked: boolean) => void.
sortableIdStable 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.

MenuItemSwitch Props

NameDefaultDescription
labelrequiredSwitch label text.
checkedfalseWhether the switch is checked.
valueOptional value for the switch item.
disabledfalseWhether the switch is disabled.
onCheckedChangeCallback 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.

MenuItemRadio Props

NameDefaultDescription
valuerequiredRadio item value.
labelrequiredRadio item label text.
iconOptional decorative SVG icon displayed before the label. Stays aria-hidden so the accessible name is the label alone.
trailingOptional 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-labellabelAccessible name override. Keep label as the visible text.
descriptionAccessible 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.
disabledfalseWhether the radio item is disabled.
onSelectOptional callback fired when the radio item is selected.
onKeyDownOptional keyboard handler on the radio item (for example ArrowLeft/ArrowRight for a consumer-owned extra action).

MenuLabel Props

NameDefaultDescription
childrenrequiredLabel text displayed as a heading within the menu.

MenuGroup Props

NameDefaultDescription
valueCurrently selected value for radio items within the group.
onValueChangeCallback fired when radio selection changes within the group: (value: string) => void.
childrenrequiredRadio items to display in the group.

MenuCollapsibleGroup Props

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.

NameDefaultDescription
labelrequiredGroup heading, and the accessible name of the select-all row.
groupIdStable 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 >.
checkedrequiredTri-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.
onCheckedChangerequired(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.
captionTrailing count rendered next to the label, e.g. 13 for "Fire (13)".
disabledfalseDisables the row, select-all, and pointer or keyboard expansion.
defaultOpenfalseInitial expanded state when open is not supplied.
openControlled expanded state.
onOpenChangeFired when the expanded state should change: (open: boolean) => void.
childrenrequiredMenuItemCheckbox 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.

Menu with Collapsible Groups

Group hundreds of options under expandable categories, each with its own select-all.

Basic Menu

Use for simple dropdown menus with action items.

Menu with Icons

Add icons to menu items for visual clarity and quick recognition.

Menu with Groups and Labels

Organize menu items into logical sections using labels and groups.

Reorderable menu

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.

Menu with Checkboxes

Use checkboxes for multi-select options.

Menu with Radio Groups

Use radio groups for single-select options with controlled state. Pass icon for a decorative leading glyph — the accessible name remains the label.

Trigger Variants

Choose the appropriate trigger based on context and design requirements.

Dropdown Trigger

Default trigger with label and chevron icon.

Button Trigger

Use for primary actions or when the menu acts as a button group.

Icon Button Trigger

Use for compact spaces or secondary actions.

Custom Trigger

Use when you need full control over the trigger element.

NavigableMenu with Search

Enable search functionality for menus with many items.

NavigableMenu with Submenus

Create nested menus with breadcrumb navigation.

Searchable Menu with Submenus

Combine search and submenu navigation for complex menu hierarchies.

Disabled Menu

Disable the entire menu when actions are unavailable.

Disabled Menu Items

Disable specific items while keeping others available.

Previous

Menu / Usage

Next

Accessibility / General

On this page

Props
Storybook
Content styling and passthrough
NavigableMenu Props
Reorderable menu props
MenuItem Props
MenuItemSubmenu Props
MenuItemCheckbox Props
MenuItemSwitch Props
MenuItemRadio Props
MenuLabel Props
MenuGroup Props
MenuCollapsibleGroup Props
Menu with Collapsible Groups
Basic Menu
Menu with Icons
Menu with Groups and Labels
Reorderable menu
Menu with Checkboxes
Menu with Radio Groups
Trigger Variants
Dropdown Trigger
Button Trigger
Icon Button Trigger
Custom Trigger
NavigableMenu with Search
NavigableMenu with Submenus
Searchable Menu with Submenus
Disabled Menu
Disabled Menu Items