A list of actions in a dropdown, enhanced with keyboard navigation.
import * as React from 'react';
import { Menu } from '@base-ui-components/react/menu';
import styles from './index.module.css';
export default function ExampleMenu() {
return (
<Menu.Root>
<Menu.Trigger className={styles.Button}>
Song <ChevronDownIcon className={styles.ButtonIcon} />
</Menu.Trigger>
<Menu.Portal>
<Menu.Positioner className={styles.Positioner} sideOffset={8}>
<Menu.Popup className={styles.Popup}>
<Menu.Arrow className={styles.Arrow}>
<ArrowSvg />
</Menu.Arrow>
<Menu.Item className={styles.Item}>Add to Library</Menu.Item>
<Menu.Item className={styles.Item}>Add to Playlist</Menu.Item>
<Menu.Separator className={styles.Separator} />
<Menu.Item className={styles.Item}>Play Next</Menu.Item>
<Menu.Item className={styles.Item}>Play Last</Menu.Item>
<Menu.Separator className={styles.Separator} />
<Menu.Item className={styles.Item}>Favorite</Menu.Item>
<Menu.Item className={styles.Item}>Share</Menu.Item>
</Menu.Popup>
</Menu.Positioner>
</Menu.Portal>
</Menu.Root>
);
}
function ArrowSvg(props: React.ComponentProps<'svg'>) {
return (
<svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}>
<path
d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z"
className={styles.ArrowFill}
/>
<path
d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z"
className={styles.ArrowOuterStroke}
/>
<path
d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z"
className={styles.ArrowInnerStroke}
/>
</svg>
);
}
function ChevronDownIcon(props: React.ComponentProps<'svg'>) {
return (
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" {...props}>
<path d="M1 3.5L5 7.5L9 3.5" stroke="currentcolor" strokeWidth="1.5" />
</svg>
);
}
API reference
Import the component and place its parts the following way:
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 />
{/* 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>
Root
Groups all parts of the menu.
Doesn’t render its own HTML element.
Prop | Type | Default | |
---|
closeParentOnEsc | boolean | true | |
---|
defaultOpen | boolean | false | |
---|
delay | number | 100 | |
---|
disabled | boolean | false | |
---|
loop | boolean | true | |
---|
onOpenChange | (open, event) => void | undefined | |
---|
open | boolean | undefined | |
---|
openOnHover | boolean | undefined | |
---|
orientation | 'horizontal' | 'vertical' | 'vertical' | |
---|
Trigger
A button that opens the menu.
Renders a <button>
element.
Prop | Type | Default | |
---|
className | string | (state) => string | undefined | |
---|
disabled | boolean | false | |
---|
label | string | undefined | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|
Attribute | Type | |
---|
data-popup-open | Empty attribute | |
---|
data-pressed | Empty attribute | |
---|
Portal
A portal element that moves the popup to a different part of the DOM.
By default, the portal element is appended to the <body>
.
Prop | Type | Default | |
---|
container | React.Ref | HTMLElement | null | undefined | |
---|
keepMounted | boolean | false | |
---|
Positioner
Positions the menu popup against the trigger.
Renders a <div>
element.
Prop | Type | Default | |
---|
align | 'start' | 'center' | 'end' | 'center' | |
---|
alignOffset | number | 0 | |
---|
anchor | | React.Ref | Element | VirtualElement | (() => Element | VirtualElement | null) | null | undefined | |
---|
arrowPadding | number | 5 | |
---|
className | string | (state) => string | undefined | |
---|
collisionBoundary | | 'clippingAncestors' | Element | Element[] | Rect | 'clipping-ancestors' | |
---|
collisionPadding | number | Rect | 5 | |
---|
keepMounted | boolean | false | |
---|
positionMethod | 'absolute' | 'fixed' | 'absolute' | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|
side | | 'bottom' | 'inline-end' | 'inline-start' | 'left' | 'right' | 'top' | 'bottom' | |
---|
sideOffset | number | 0 | |
---|
sticky | boolean | false | |
---|
Attribute | Type | |
---|
data-anchor-hidden | Empty attribute | |
---|
data-open | Empty attribute | |
---|
data-unchecked | Empty attribute | |
---|
CSS Variable | Type | |
---|
--anchor-height | number | |
---|
--anchor-width | number | |
---|
--available-height | number | |
---|
--available-width | number | |
---|
--transform-origin | string | |
---|
A container for the menu items.
Renders a <div>
element.
Prop | Type | Default | |
---|
className | string | (state) => string | undefined | |
---|
id | string | undefined | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|
Attribute | Type | |
---|
data-closed | Empty attribute | |
---|
data-ending-style | Empty attribute | |
---|
data-open | Empty attribute | |
---|
data-starting-style | Empty attribute | |
---|
Arrow
Displays an element positioned against the menu anchor.
Renders a <div>
element.
Prop | Type | Default | |
---|
className | string | (state) => string | undefined | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|
Item
An individual interactive item in the menu.
Renders a <div>
element.
Prop | Type | Default | |
---|
closeOnClick | boolean | true | |
---|
disabled | boolean | false | |
---|
id | string | undefined | |
---|
label | string | undefined | |
---|
onClick | (event) => void | undefined | |
---|
Group
Groups related menu items with the corresponding label.
Renders a <div>
element.
Prop | Type | Default | |
---|
children | React.ReactNode | undefined | |
---|
className | string | (state) => string | undefined | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|
Group Label
An accessible label that is automatically associated with its parent group.
Renders a <div>
element.
Prop | Type | Default | |
---|
className | string | (state) => string | undefined | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|
Radio Group
Groups related radio items.
Renders a <div>
element.
Prop | Type | Default | |
---|
children | React.ReactNode | undefined | |
---|
className | string | (state) => string | undefined | |
---|
defaultValue | any | undefined | |
---|
onValueChange | (value, event) => void | () => {} | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|
value | any | undefined | |
---|
Radio Item
A menu item that works like a radio button in a given group.
Renders a <div>
element.
Prop | Type | Default | |
---|
value | any | undefined | |
---|
closeOnClick | boolean | true | |
---|
disabled | boolean | false | |
---|
id | string | undefined | |
---|
label | string | undefined | |
---|
onClick | (event) => void | undefined | |
---|
Attribute | Type | |
---|
data-checked | Empty attribute | |
---|
data-unchecked | Empty attribute | |
---|
Radio Item Indicator
Indicates whether the radio item is selected.
Renders a <div>
element.
Prop | Type | Default | |
---|
className | string | (state) => string | undefined | |
---|
keepMounted | boolean | true | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|
Checkbox Item
A menu item that toggles a setting on or off.
Renders a <div>
element.
Prop | Type | Default | |
---|
checked | boolean | undefined | |
---|
closeOnClick | boolean | true | |
---|
defaultChecked | boolean | false | |
---|
disabled | boolean | false | |
---|
id | string | undefined | |
---|
label | string | undefined | |
---|
onCheckedChange | function | undefined | |
---|
onClick | (event) => void | undefined | |
---|
Checkbox Item Indicator
Indicates whether the checkbox item is ticked.
Renders a <div>
element.
Prop | Type | Default | |
---|
className | string | (state) => string | undefined | |
---|
keepMounted | boolean | true | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|
Attribute | Type | |
---|
data-checked | Empty attribute | |
---|
data-unchecked | Empty attribute | |
---|
A menu item that opens a submenu.
Renders a <div>
element.
Prop | Type | Default | |
---|
className | string | (state) => string | undefined | |
---|
disabled | boolean | false | |
---|
label | string | undefined | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|
Attribute | Type | |
---|
data-popup-open | Empty attribute | |
---|
Separator
A separator element accessible to screen readers.
Renders a <div>
element.
Prop | Type | Default | |
---|
className | string | (state) => string | undefined | |
---|
render | | React.ReactElement | (props, state) => React.ReactElement | undefined | |
---|