Skip to main content
Use Menu for actions opened from a trigger. Its items supply keyboard navigation and the visual layout of ListItem.

Action menu

Action items close the menu when selected by default. disabled prevents selection. hotkeys displays shortcut hints; register shortcut handlers in your application.

Selection and submenus

Checkbox and radio items keep the popup open by default so users can adjust options. Use closeOnClick to change that behavior. Nest a SubmenuRoot, SubmenuTrigger, and Popup inside a parent popup for submenus.

Parts and interaction

Arrow keys move through the items, including disabled ones, which receive focus but cannot be selected; typeahead finds items by their text. Enter or Space selects an item. Escape closes the menu and returns focus to its trigger. Use clear text labels even when items have icons. Popup owns its portal and accepts placement props and a container override. Placement defaults depend on whether it is a top-level menu or a submenu: It uses the theme’s portal container by default. Control open state with Root.open and Root.onOpenChange.

Props

The reference is generated from the public component types. Native attributes, including accessible names and event handlers, are also accepted on parts that render elements.
RefObject<MenuRootActions | null>
A ref to imperative actions.
  • unmount: Manually unmounts the menu. Call this after any externally controlled closing animation finishes.
  • close: When specified, the menu can be closed imperatively.
ReactNode | PayloadChildRenderFunction<Payload>
The content of the menu. This can be a regular React node or a render function that receives the payload of the active trigger.
boolean
default:"false"
When in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu.
boolean
default:"false"
Whether the menu is initially open.To render a controlled menu, use the open prop instead.
string | null
ID of the trigger that the menu is associated with. This is useful in conjunction with the defaultOpen prop to create an initially open menu.
boolean
default:"false"
Whether the component should ignore user interaction.
MenuHandle<Payload>
A handle to associate the menu with a trigger. If specified, allows external triggers to control the menu’s open state.
boolean
default:"true"
Whether moving the pointer over items should highlight them. Disabling this prop allows CSS :hover to be differentiated from the :focus (data-highlighted) state.
boolean
default:"true"
Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys.
boolean
default:"true"
Determines if the menu enters a modal state when open.
  • true: user interaction is limited to the menu: document page scroll is locked and pointer interactions on outside elements are disabled.
  • false: user interaction with the rest of the document is allowed.
On touch devices, a true modal blocks outside taps but leaves the page scrollable unless the popup spans nearly the full viewport width, matching native iOS behavior.Nested menus ignore this prop, and menus opened by hover are never modal.
((open: boolean, eventDetails: MenuRootChangeEventDetails) => void)
Event handler called when the menu is opened or closed.
((open: boolean) => void)
Event handler called after any animations complete when the menu is opened or closed.
boolean
Whether the menu is currently open.
"horizontal" | "vertical"
default:"vertical"
The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys.
string | null
ID of the trigger that the menu is associated with. This is useful in conjunction with the open prop to create a controlled menu. There’s no need to specify this prop when the menu is uncontrolled (that is, when the open prop is not set).
string | ((state: MenuTriggerState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
number
default:"0"
How long to wait before closing the menu that was opened on hover. Specified in milliseconds.Requires the openOnHover prop.
number
default:"100"
How long to wait before the menu may be opened on hover. Specified in milliseconds.Requires the openOnHover prop.
boolean
default:"false"
Whether the component should ignore user interaction.
MenuHandle<Payload>
A handle to associate the trigger with a menu.
boolean
default:"true"
Whether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).
boolean
Whether the menu should also open when the trigger is hovered.
Payload
A payload to pass to the menu when it is opened.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuTriggerState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
CSSProperties | ((state: MenuTriggerState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
"center" | "start" | "end"
Alignment of the popup along the anchor. Defaults to start.
number
Offset in pixels along the alignment axis. Defaults to 0 for a menu and -4 for a submenu.
Element | VirtualElement | RefObject<Element | null> | (() => Element | VirtualElement | null) | null
Element or position the popup is anchored to. Defaults to the trigger.
string | ((state: MenuPopupState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null> | null
Element the popup is portaled into. Defaults to the theme’s portal container.
boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | void | HTMLElement | null)
Determines the element to focus when the menu is closed.
  • false: Do not move focus.
  • true: Move focus based on the default behavior (trigger or previously focused element).
  • RefObject: Move focus to the ref element.
  • function: Called with the interaction type (mouse, touch, pen, or keyboard). Return an element to focus, true to use the default behavior, or false/undefined to do nothing.
boolean
Keeps the popup mounted in the DOM while the menu is closed.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuPopupState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
"top" | "bottom" | "left" | "right" | "inline-end" | "inline-start"
Side of the anchor the popup is placed on. Defaults to bottom for a menu and inline-end for a submenu.
number
Distance in pixels between the anchor and the popup. Defaults to 8 for a menu and 0 for a submenu.
CSSProperties | ((state: MenuPopupState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
string | ((state: MenuItemState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
boolean
default:"true"
Whether to close the menu when the item is clicked.
"neutral" | "danger"
Color of the text and icons. danger marks a destructive action.
ReactNode
Supporting text, placed according to descriptionPlacement.
"inline" | "end"
Where the description renders: inline after the content or at the end of the row.
boolean
default:"false"
Whether the component should ignore user interaction.
ReactNode
Icon rendered after the content.
string[]
Keyboard shortcut keys displayed at the end of the row. Registering the shortcut is up to the application.
string
Overrides the text label to use when the item is matched during keyboard text navigation.
boolean
default:"false"
Whether the component renders a native <button> element when replacing it via the render prop. Set to true if the rendered element is a native button.
((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void)
The click handler for the menu item.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuItemState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
ReactNode
Icon rendered before the content.
CSSProperties | ((state: MenuItemState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
boolean
Whether the checkbox item is currently ticked.To render an uncontrolled checkbox item, use the defaultChecked prop instead.
string | ((state: MenuCheckboxItemState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
boolean
default:"false"
Whether to close the menu when the item is clicked.
"neutral" | "danger"
Color of the text and icons. danger marks a destructive action.
boolean
default:"false"
Whether the checkbox item is initially ticked.To render a controlled checkbox item, use the checked prop instead.
ReactNode
Supporting text, placed according to descriptionPlacement.
"inline" | "end"
Where the description renders: inline after the content or at the end of the row.
boolean
default:"false"
Whether the component should ignore user interaction.
ReactNode
Icon rendered after the content.
string[]
Keyboard shortcut keys displayed at the end of the row. Registering the shortcut is up to the application.
string
Overrides the text label to use when the item is matched during keyboard text navigation.
boolean
default:"false"
Whether the component renders a native <button> element when replacing it via the render prop. Set to true if the rendered element is a native button.
((checked: boolean, eventDetails: MenuRootChangeEventDetails) => void)
Event handler called when the checkbox item is ticked or unticked.
((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void)
The click handler for the menu item.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuCheckboxItemState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
ReactNode
Icon rendered before the content.
CSSProperties | ((state: MenuCheckboxItemState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
ReactNode
The content of the component.
string | ((state: MenuRadioGroupState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
any
The uncontrolled value of the radio item that should be initially selected.To render a controlled radio group, use the value prop instead.
boolean
default:"false"
Whether the component should ignore user interaction.
((value: any, eventDetails: MenuRootChangeEventDetails) => void)
Function called when the selected value changes.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuRadioGroupState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
CSSProperties | ((state: MenuRadioGroupState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
any
The controlled value of the radio item that should be currently selected.To render an uncontrolled radio group, use the defaultValue prop instead.
string | ((state: MenuRadioItemState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
boolean
default:"false"
Whether to close the menu when the item is clicked.
"neutral" | "danger"
Color of the text and icons. danger marks a destructive action.
ReactNode
Supporting text, placed according to descriptionPlacement.
"inline" | "end"
Where the description renders: inline after the content or at the end of the row.
boolean
default:"false"
Whether the component should ignore user interaction.
ReactNode
Icon rendered after the content.
string[]
Keyboard shortcut keys displayed at the end of the row. Registering the shortcut is up to the application.
string
Overrides the text label to use when the item is matched during keyboard text navigation.
boolean
default:"false"
Whether the component renders a native <button> element when replacing it via the render prop. Set to true if the rendered element is a native button.
((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void)
The click handler for the menu item.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuRadioItemState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
ReactNode
Icon rendered before the content.
CSSProperties | ((state: MenuRadioItemState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
any
required
Value of the radio item. This is the value that will be set in the MenuRadioGroup when the item is selected.
ReactNode
The content of the component.
string | ((state: MenuGroupState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuGroupState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
CSSProperties | ((state: MenuGroupState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
string | ((state: MenuGroupLabelState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuGroupLabelState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
CSSProperties | ((state: MenuGroupLabelState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
string | ((state: SeparatorState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
"horizontal" | "vertical"
default:"horizontal"
The orientation of the separator.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SeparatorState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
CSSProperties | ((state: SeparatorState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.
RefObject<MenuRootActions | null>
A ref to imperative actions.
  • unmount: Manually unmounts the menu. Call this after any externally controlled closing animation finishes.
  • close: When specified, the menu can be closed imperatively.
ReactNode
The content of the submenu.
boolean
default:"false"
When in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu.
boolean
default:"false"
Whether the menu is initially open.To render a controlled menu, use the open prop instead.
boolean
default:"false"
Whether the component should ignore user interaction.
boolean
default:"true"
Whether moving the pointer over items should highlight them. Disabling this prop allows CSS :hover to be differentiated from the :focus (data-highlighted) state.
boolean
default:"true"
Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys.
((open: boolean, eventDetails: MenuRootChangeEventDetails) => void)
Event handler called when the menu is opened or closed.
((open: boolean) => void)
Event handler called after any animations complete when the menu is opened or closed.
boolean
Whether the menu is currently open.
"horizontal" | "vertical"
default:"vertical"
The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys.
string | ((state: MenuSubmenuTriggerState) => string | undefined)
CSS class applied to the element, or a function that returns a class based on the component’s state.
number
default:"0"
How long to wait before closing the menu that was opened on hover. Specified in milliseconds.Requires the openOnHover prop.
"neutral" | "danger"
Color of the text and icons. danger marks a destructive action.
number
default:"100"
How long to wait before the menu may be opened on hover. Specified in milliseconds.Requires the openOnHover prop.
ReactNode
Supporting text, placed according to descriptionPlacement.
"inline" | "end"
Where the description renders: inline after the content or at the end of the row.
boolean
default:"false"
Whether the component should ignore user interaction.
ReactNode
Icon rendered after the content.
string[]
Keyboard shortcut keys displayed at the end of the row. Registering the shortcut is up to the application.
string
Overrides the text label to use when the item is matched during keyboard text navigation.
boolean
default:"false"
Whether the component renders a native <button> element when replacing it via the render prop. Set to true if the rendered element is a native button.
((event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void)
boolean
default:"true"
Whether the menu should also open when the trigger is hovered.
ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, MenuSubmenuTriggerState>
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.
ReactNode
Icon rendered before the content.
CSSProperties | ((state: MenuSubmenuTriggerState) => CSSProperties | undefined)
Style applied to the element, or a function that returns a style object based on the component’s state.