A visually persistent menu common in desktop applications that provides quick access to a consistent set of commands.
import React from 'react';import * as Menubar from '@radix-ui/react-menubar';import { CheckIcon, ChevronRightIcon, DotFilledIcon } from '@radix-ui/react-icons';import './styles.css';const RADIO_ITEMS = ['Andy', 'Benoît', 'Luis'];const CHECK_ITEMS = ['Always Show Bookmarks Bar', 'Always Show Full URLs'];const MenubarDemo = () => {const [checkedSelection, setCheckedSelection] = React.useState([CHECK_ITEMS[1]]);const [radioSelection, setRadioSelection] = React.useState(RADIO_ITEMS[2]);return (<Menubar.Root className="MenubarRoot"><Menubar.Menu><Menubar.Trigger className="MenubarTrigger">File</Menubar.Trigger><Menubar.Portal><Menubar.Content className="MenubarContent" align="start" sideOffset={5} alignOffset={-3}><Menubar.Item className="MenubarItem">New Tab <div className="RightSlot">⌘ T</div></Menubar.Item><Menubar.Item className="MenubarItem">New Window <div className="RightSlot">⌘ N</div></Menubar.Item><Menubar.Item className="MenubarItem" disabled>New Incognito Window</Menubar.Item><Menubar.Separator className="MenubarSeparator" /><Menubar.Sub><Menubar.SubTrigger className="MenubarSubTrigger">Share<div className="RightSlot"><ChevronRightIcon /></div></Menubar.SubTrigger><Menubar.Portal><Menubar.SubContent className="MenubarSubContent" alignOffset={-5}><Menubar.Item className="MenubarItem">Email Link</Menubar.Item><Menubar.Item className="MenubarItem">Messages</Menubar.Item><Menubar.Item className="MenubarItem">Notes</Menubar.Item></Menubar.SubContent></Menubar.Portal></Menubar.Sub><Menubar.Separator className="MenubarSeparator" /><Menubar.Item className="MenubarItem">Print… <div className="RightSlot">⌘ P</div></Menubar.Item></Menubar.Content></Menubar.Portal></Menubar.Menu><Menubar.Menu><Menubar.Trigger className="MenubarTrigger">Edit</Menubar.Trigger><Menubar.Portal><Menubar.Content className="MenubarContent" align="start" sideOffset={5} alignOffset={-3}><Menubar.Item className="MenubarItem">Undo <div className="RightSlot">⌘ Z</div></Menubar.Item><Menubar.Item className="MenubarItem">Redo <div className="RightSlot">⇧ ⌘ Z</div></Menubar.Item><Menubar.Separator className="MenubarSeparator" /><Menubar.Sub><Menubar.SubTrigger className="MenubarSubTrigger">Find<div className="RightSlot"><ChevronRightIcon /></div></Menubar.SubTrigger><Menubar.Portal><Menubar.SubContent className="MenubarSubContent" alignOffset={-5}><Menubar.Item className="MenubarItem">Search the web…</Menubar.Item><Menubar.Separator className="MenubarSeparator" /><Menubar.Item className="MenubarItem">Find…</Menubar.Item><Menubar.Item className="MenubarItem">Find Next</Menubar.Item><Menubar.Item className="MenubarItem">Find Previous</Menubar.Item></Menubar.SubContent></Menubar.Portal></Menubar.Sub><Menubar.Separator className="MenubarSeparator" /><Menubar.Item className="MenubarItem">Cut</Menubar.Item><Menubar.Item className="MenubarItem">Copy</Menubar.Item><Menubar.Item className="MenubarItem">Paste</Menubar.Item></Menubar.Content></Menubar.Portal></Menubar.Menu><Menubar.Menu><Menubar.Trigger className="MenubarTrigger">View</Menubar.Trigger><Menubar.Portal><Menubar.Content className="MenubarContent" align="start" sideOffset={5} alignOffset={-14} >{CHECK_ITEMS.map((item) => (<Menubar.CheckboxItem className="MenubarCheckboxItem inset" key={item} checked={checkedSelection.includes(item)} onCheckedChange={() => setCheckedSelection((current) => current.includes(item) ? current.filter((el) => el !== item) : current.concat(item) ) } ><Menubar.ItemIndicator className="MenubarItemIndicator"><CheckIcon /></Menubar.ItemIndicator>{item}</Menubar.CheckboxItem>))}<Menubar.Separator className="MenubarSeparator" /><Menubar.Item className="MenubarItem inset">Reload <div className="RightSlot">⌘ R</div></Menubar.Item><Menubar.Item className="MenubarItem inset" disabled>Force Reload <div className="RightSlot">⇧ ⌘ R</div></Menubar.Item><Menubar.Separator className="MenubarSeparator" /><Menubar.Item className="MenubarItem inset">Toggle Fullscreen</Menubar.Item><Menubar.Separator className="MenubarSeparator" /><Menubar.Item className="MenubarItem inset">Hide Sidebar</Menubar.Item></Menubar.Content></Menubar.Portal></Menubar.Menu><Menubar.Menu><Menubar.Trigger className="MenubarTrigger">Profiles</Menubar.Trigger><Menubar.Portal><Menubar.Content className="MenubarContent" align="start" sideOffset={5} alignOffset={-14} ><Menubar.RadioGroup value={radioSelection} onValueChange={setRadioSelection}>{RADIO_ITEMS.map((item) => (<Menubar.RadioItem className="MenubarRadioItem inset" key={item} value={item}><Menubar.ItemIndicator className="MenubarItemIndicator"><DotFilledIcon /></Menubar.ItemIndicator>{item}</Menubar.RadioItem>))}<Menubar.Separator className="MenubarSeparator" /><Menubar.Item className="MenubarItem inset">Edit…</Menubar.Item><Menubar.Separator className="MenubarSeparator" /><Menubar.Item className="MenubarItem inset">Add Profile…</Menubar.Item></Menubar.RadioGroup></Menubar.Content></Menubar.Portal></Menubar.Menu></Menubar.Root>);};export default MenubarDemo;
Can be controlled or uncontrolled.
Supports submenus with configurable reading direction.
Supports items, labels, groups of items.
Supports checkable items (single or multiple).
Customize side, alignment, offsets, collision handling.
Optionally render a pointing arrow.
Focus is fully managed.
Full keyboard navigation.
Typeahead support.
Install the component from your command line.
Import all parts and piece them together.
Contains all the parts of a menubar.
A top level menu item, contains a trigger with content combination.
The button that toggles the content. By default, the Menubar.Content
will position itself against the trigger.
When used, portals the content part into the body
.
The component that pops out when a menu is open.
An optional arrow element to render alongside a menubar menu. This can be used to help visually link the trigger with the Menubar.Content
. Must be rendered inside Menubar.Content
.
The component that contains the menubar items.
Used to group multiple Menubar.Item
s.
Used to render a label. It won't be focusable using arrow keys.
An item that can be controlled and rendered like a checkbox.
Used to group multiple Menubar.RadioItem
s.
An item that can be controlled and rendered like a radio.
Renders when the parent Menubar.CheckboxItem
or Menubar.RadioItem
is checked. You can style this element directly, or you can use it as a wrapper to put an icon into, or both.
Used to visually separate items in a menubar menu.
Contains all the parts of a submenu.
An item that opens a submenu. Must be rendered inside Menubar.Sub
.
The component that pops out when a submenu is open. Must be rendered inside Menubar.Sub
.
You can create submenus by using Menubar.Sub
in combination with its parts.
You can add special styles to disabled items via the data-disabled
attribute.
Use the Separator
part to add a separator between items.
Use the Label
part to help label a section.
Use the CheckboxItem
part to add an item that can be checked.
Use the RadioGroup
and RadioItem
parts to add an item that can be checked amongst others.
You can add extra decorative elements in the Item
parts, such as images.
You may want to constrain the width of the content (or sub-content) so that it matches the trigger (or sub-trigger) width. You may also want to constrain its height to not exceed the viewport.
We expose several CSS custom properties such as --radix-menubar-trigger-width
and --radix-menubar-content-available-height
to support this. Use them to constrain the content dimensions.
We expose a CSS custom property --radix-menubar-content-transform-origin
. Use it to animate the content from its computed origin based on side
, sideOffset
, align
, alignOffset
and any collisions.
We expose data-side
and data-align
attributes. Their values will change at runtime to reflect collisions. Use them to create collision and direction-aware animations.
Adheres to the Menu Button WAI-ARIA design pattern and uses roving tabindex to manage focus movement among menu items.