Menu

A list of actions in a dropdown, enhanced with keyboard navigation.

API reference

Import the component and assemble its parts:

Anatomy
import { Menu } from '@base-ui-components/react/menu';
<Menu.Root>  <Menu.Trigger />  <Menu.Portal>    <Menu.Backdrop />    <Menu.Positioner>      <Menu.Popup>        <Menu.Arrow />        <Menu.Item />        <Menu.Separator />        <Menu.Group>          <Menu.GroupLabel />        </Menu.Group>        <Menu.RadioGroup>          <Menu.RadioItem />        </Menu.RadioGroup>        <Menu.CheckboxItem />      </Menu.Popup>    </Menu.Positioner>  </Menu.Portal></Menu.Root>

Root

Groups all parts of the menu. Doesn’t render its own HTML element.

PropTypeDefault
defaultOpen

boolean

false

open

boolean

undefined

onOpenChange

(open, event) => void

undefined

closeParentOnEsc

boolean

true

modal

boolean

true

disabled

boolean

false

openOnHover

boolean

undefined

delay

number

100

loop

boolean

true

orientation

'horizontal' | 'vertical'

'vertical'

Trigger

A button that opens the menu. Renders a <button> element.

PropTypeDefault
disabled

boolean

false

className

string | (state) => string

undefined

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

Attribute
Description
data-popup-open
data-pressed

Portal

A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to <body>.

PropTypeDefault
container

React.Ref | HTMLElement | null

undefined

keepMounted

boolean

false

Positioner

Positions the menu popup against the trigger. Renders a <div> element.

PropTypeDefault
align

'start' | 'center' | 'end'

undefined

alignOffset

number

0

side

| 'bottom'
| 'inline-end'
| 'inline-start'
| 'left'
| 'right'
| 'top'

undefined

sideOffset

number

0

arrowPadding

number

5

anchor

| React.Ref
| Element
| VirtualElement
| (() => Element | VirtualElement | null)
| null

undefined

collisionBoundary

| 'clipping-ancestors'
| Element
| Element[]
| Rect

'clipping-ancestors'

collisionPadding

number | Rect

5

sticky

boolean

false

positionMethod

'absolute' | 'fixed'

'absolute'

className

string | (state) => string

undefined

keepMounted

boolean

false

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

Attribute
Description
data-open
data-closed
data-anchor-hidden
data-side
CSS Variable
Description
--anchor-height
--anchor-width
--available-height
--available-width
--transform-origin

A container for the menu items. Renders a <div> element.

PropTypeDefault
className

string | (state) => string

undefined

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

Attribute
Description
data-open
data-closed
data-side
data-starting-style
data-ending-style

Arrow

Displays an element positioned against the menu anchor. Renders a <div> element.

PropTypeDefault
className

string | (state) => string

undefined

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

Attribute
Description
data-open
data-closed
data-uncentered
data-anchor-hidden
data-side

Item

An individual interactive item in the menu. Renders a <div> element.

PropTypeDefault
label

string

undefined

onClick

(event) => void

undefined

closeOnClick

boolean

true

disabled

boolean

false

Group

Groups related menu items with the corresponding label. Renders a <div> element.

PropTypeDefault
children

React.ReactNode

undefined

className

string | (state) => string

undefined

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

GroupLabel

An accessible label that is automatically associated with its parent group. Renders a <div> element.

PropTypeDefault
className

string | (state) => string

undefined

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

RadioGroup

Groups related radio items. Renders a <div> element.

PropTypeDefault
defaultValue

any

undefined

value

any

undefined

onValueChange

(value, event) => void

() => {}

children

React.ReactNode

undefined

className

string | (state) => string

undefined

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

RadioItem

A menu item that works like a radio button in a given group. Renders a <div> element.

PropTypeDefault
label

string

undefined

value

any

undefined

onClick

(event) => void

undefined

closeOnClick

boolean

false

disabled

boolean

false

Attribute
Description
data-checked
data-unchecked

RadioItemIndicator

Indicates whether the radio item is selected. Renders a <div> element.

PropTypeDefault
className

string | (state) => string

undefined

keepMounted

boolean

false

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

Attribute
Description
data-checked
data-unchecked
data-disabled
data-starting-style
data-ending-style

CheckboxItem

A menu item that toggles a setting on or off. Renders a <div> element.

PropTypeDefault
label

string

undefined

defaultChecked

boolean

false

checked

boolean

undefined

onCheckedChange

(checked, event) => void

undefined

onClick

(event) => void

undefined

closeOnClick

boolean

false

disabled

boolean

false

Attribute
Description
data-checked
data-unchecked

CheckboxItemIndicator

Indicates whether the checkbox item is ticked. Renders a <div> element.

PropTypeDefault
className

string | (state) => string

undefined

keepMounted

boolean

false

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

Attribute
Description
data-checked
data-unchecked
data-disabled
data-starting-style
data-ending-style

A menu item that opens a submenu. Renders a <div> element.

PropTypeDefault
label

string

undefined

disabled

boolean

false

className

string | (state) => string

undefined

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

Attribute
Description
data-popup-open

Separator

A separator element accessible to screen readers. Renders a <div> element.

PropTypeDefault
className

string | (state) => string

undefined

render

| React.ReactElement
| (props, state) => React.ReactElement

undefined

Examples

Open on hover

To create a menu that opens on hover, add the openOnHover prop to the Root part. You can additionally configure how quickly the menu opens on hover using the delay prop.

Checkbox items

Use the <Menu.CheckboxItem> part to create a menu item that can toggle a setting on or off.

Radio items

Use the <Menu.RadioGroup> and <Menu.RadioItem> parts to create menu items that work like radio buttons.

Close on click

Use the closeOnClick prop to change whether the menu closes when an item is clicked.

Control whether the menu closes on click
// Close the menu when a checkbox item is clicked<Menu.CheckboxItem closeOnClick />
// Keep the menu open when an item is clicked<Menu.Item closeOnClick={false} />

Group labels

Use the <Menu.GroupLabel> part to add a label to a <Menu.Group>

Nested menu

To create a submenu, nest another menu inside the parent menu. Use the <Menu.SubmenuTrigger> part for the menu item that opens the nested menu.

Adding a submenu
<Menu.Root>  <Menu.Trigger />  <Menu.Portal>    <Menu.Backdrop />    <Menu.Positioner>      <Menu.Popup>        <Menu.Arrow />        <Menu.Item />
        {/* Submenu */}        <Menu.Root>          <Menu.SubmenuTrigger />          <Menu.Portal>            <Menu.Positioner>              <Menu.Popup>              </Menu.Popup>            </Menu.Positioner>          </Menu.Portal>        </Menu.Root>      </Menu.Popup>    </Menu.Positioner>  </Menu.Portal></Menu.Root>

Use the render prop to compose a menu item with an anchor element.

A menu item that opens a link
<Menu.Item render={<a href="/projects">Go to Projects</a>} />

Open a dialog

In order to open a dialog using a menu, control the dialog state and open it imperatively using the onClick handler on the menu item.

Make sure to also use the dialog’s finalFocus prop to return focus back to the menu trigger.

Connecting a dialog to a menu
import * as React from 'react';import { Dialog } from '@base-ui/components/dialog';import { Menu } from '@base-ui/components/menu';
function ExampleMenu() {  const menuTriggerRef = React.useRef<HTMLButtonElement>(null);  const [dialogOpen, setDialogOpen] = React.useState(false);
  return (    <React.Fragment>      <Menu.Root>        {/* Set the trigger ref */}        <Menu.Trigger ref={menuTriggerRef}>Open menu</Menu.Trigger>        <Menu.Portal>          <Menu.Positioner>            <Menu.Popup>              {/* Open the dialog when the menu item is clicked */}              <Menu.Item onClick={() => setDialogOpen(true)}>Open dialog</Menu.Item>            </Menu.Popup>          </Menu.Positioner>        </Menu.Portal>      </Menu.Root>
      {/* Control the dialog state */}      <Dialog.Root open={dialogOpen} onOpenChange={setDialogOpen}>        <Dialog.Portal>          <Dialog.Backdrop />          {/* Return focus to the menu trigger when the dialog is closed */}          <Dialog.Popup finalFocus={menuTriggerRef}>          </Dialog.Popup>        </Dialog.Portal>      </Dialog.Root>    </React.Fragment>  );}