shadcn.io is not affiliated with official shadcn/ui
Components
Free
Menubar for React
File and Edit menus that stay on screen in a desktop window, instead of hanging off one button. For React with Base UI, when the commands belong to the window the whole time.
Framework
UI library
File, Edit, and View stay on screen while the document underneath changes.
Use it when those commands belong to the window, not to one action. Links that move around a marketing site belong in a Navigation Menu. In React, Base UI keeps unavailable commands in the menu, disabled, so the row doesn't grow and shrink.
Installation
Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
View holds two checkbox items, bookmarks and full URLs, beside ordinary commands such as Reload. Format is only checkboxes: strikethrough, code, and superscript. Several can be on, and each keeps its checked state after the menu closes if you store it. Give plain items inset so their labels line up, and reserve checkboxes for settings rather than one-shot actions.
Radio
Profiles is a radio group, Andy, Benoit, or Luis, with Edit and Add Profile as plain items underneath. Theme is a second group: light, dark, or system, and only one item in a group stays selected. Keep commands that are not part of the choice outside the group, with inset so they line up, and use two menus so unrelated choices do not share a selection.
Submenu
File opens Share beside the item: email, messages, and notes, then Print under a separator. Edit nests Find the same way, between undo and the clipboard commands. A submenu is for a cluster that does not deserve its own top-level menu, and one extra level is usually enough. Do not put another menubar inside an item.
Icons
File leads New, Open, and Save with icons, and the shortcuts stay at the end of the row. More uses icons for Settings and Help, then a destructive Delete. The icon is decorative when the label is there, so hide it from assistive tech. Icons pay off on a menu people scan often, and the destructive variant still marks the dangerous row.
Rtl
The full bar, File through Profiles, is in Arabic. The wrapper and each menu set dir to rtl, so triggers run from the right and submenus open toward the start of the line. Checkboxes, radios, and shortcuts follow. Set the direction on the nested menus too, since a direction on the page alone can miss content that has been portaled out of the bar.
FAQ
How do I control a checkbox in a Menubar in React?
A checkbox row toggles a setting and stays in the menu, unlike a command that runs once, and each choice is its own MenubarCheckboxItem. Keep that choice in state if it should survive closing the menu.
Pass checked and onCheckedChange, whose handler receives a boolean.
How do I keep one Menubar radio item selected?
Put the choices in one MenubarRadioGroup so only one of them is selected, and leave unrelated commands, such as Edit, as MenubarItem elements beside the group. The group is the control, and the items only name the options.
Pass value, and read the next string from onValueChange.
How do I add a submenu to a Menubar?
Inside MenubarContent, wrap the nested entries in MenubarSub, MenubarSubTrigger, and MenubarSubContent. The trigger opens that menu beside the item, which is the structure in the Submenu demo. Do not put another Menubar inside the item. A separator can sit between the submenu and the commands under it.
Can I operate a Menubar from the keyboard?
Yes. Arrow keys move between triggers and items, Home and End jump to the ends, and Enter or Space activates the focused control. MenubarShortcut only displays the hint you put inside it. It does not register a key listener, so those glyphs are not a shortcut system.
Should I use a Menubar or a Dropdown Menu?
Use a Menubar for a persistent row of commands, such as File and Edit. Use a Dropdown Menu for one button that opens a single menu, and a Navigation Menu for links that move around the site. A menubar item is a command unless you render it as a link yourself.
Why is my Menubar menu clipped or hidden?
Menu content is portaled, so overflow hidden on a parent does not clip it. If a dialog or another layer still covers the menu, raise the content in the menubar file under components/ui. The content is already stacked above ordinary page content. Inset lines up an item that has no icon with items that do.
How do I style a Menubar with Base UI?
Edit the menubar file under components/ui. Triggers and items are flex rows, and MenubarItem accepts variant destructive for a dangerous command. inset on an item, label, or submenu trigger sets data-inset so the label lines up with checked rows. Shortcuts are pushed to the end of the row with a logical margin.
How do I install Menubar in React?
Run the command in the Installation section on this page, which adds the bar, each menu, and the item parts, including checkbox, radio, and submenu, to your ui folder. Import the parts you render.
The command uses the shadcn CLI.
A ref to imperative actions.
- unmount: Ends the closing phase of the menu after an externally controlled closing animation finishes.
Call preventUnmountOnClose() in onOpenChange first, otherwise the menu completes closing on its own.
Whether it leaves the DOM is decided by keepMounted on the portal.
- close: Closes the menu imperatively when called.
When in a submenu, determines whether pressing the Escape key
closes the entire menu, or only the current child menu.
Default
false
defaultTriggerId?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.
Type
string | null
disabled?boolean
Whether the component should ignore user interaction.
Default
false
handle?MenuHandle<Payload>
A handle to associate the menu with a trigger.
If specified, allows external triggers to control the menu's open state.
Type
MenuHandle<Payload>
highlightItemOnHover?boolean
Whether moving the pointer over items should highlight them.
Disabling this prop allows CSS :hover to be differentiated from the :focus (data-highlighted) state.
Default
true
loopFocus?boolean
Whether to loop keyboard focus back to the first item
when the end of the list is reached while using the arrow keys.
Default
true
modal?boolean
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.
Callback fired when an item is highlighted or unhighlighted.
Receives the highlighted item element (or undefined if no item is highlighted) and details
containing the reason for the change, the event, and the item's text label.
The reason can be:
- keyboard: the highlight changed due to keyboard navigation.
- pointer: the highlight changed due to pointer hovering. The event may be a MouseEvent
rather than a PointerEvent.
- none: the highlight changed for another reason, such as automatic highlighting while
filtering, the item list changing, or the popup opening or closing.
Event handler called after any animations complete when the menu is opened or closed.
Parameters
open – boolean
Returns
void
orientation?MenuRoot.Orientation
The visual orientation of the menu.
Controls whether roving focus uses up/down or left/right arrow keys.
Default
"vertical"
triggerId?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).
How long to wait before closing the menu that was opened on hover.
Specified in milliseconds.
Requires the openOnHover prop.
Default
0
delay?number
How long to wait before the menu may be opened on hover. Specified in milliseconds.
Requires the openOnHover prop.
Default
100
disabled?boolean
Whether the component should ignore user interaction.
Default
false
handle?MenuHandle<Payload>
A handle to associate the trigger with a menu.
Type
MenuHandle<Payload>
nativeButton?boolean
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>).
Default
true
openOnHover?boolean
Whether the menu should also open when the trigger is hovered.
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.
A ref to imperative actions.
- unmount: Ends the closing phase of the menu after an externally controlled closing animation finishes.
Call preventUnmountOnClose() in onOpenChange first, otherwise the menu completes closing on its own.
Whether it leaves the DOM is decided by keepMounted on the portal.
- close: Closes the menu imperatively when called.
Type
React.RefObject<MenuRoot.Actions | null>
children?React.ReactNode
The content of the submenu.
closeParentOnEsc?boolean
When in a submenu, determines whether pressing the Escape key
closes the entire menu, or only the current child menu.
Default
false
disabled?boolean
Whether the component should ignore user interaction.
Default
false
highlightItemOnHover?boolean
Whether moving the pointer over items should highlight them.
Disabling this prop allows CSS :hover to be differentiated from the :focus (data-highlighted) state.
Default
true
loopFocus?boolean
Whether to loop keyboard focus back to the first item
when the end of the list is reached while using the arrow keys.
Callback fired when an item is highlighted or unhighlighted.
Receives the highlighted item element (or undefined if no item is highlighted) and details
containing the reason for the change, the event, and the item's text label.
The reason can be:
- keyboard: the highlight changed due to keyboard navigation.
- pointer: the highlight changed due to pointer hovering. The event may be a MouseEvent
rather than a PointerEvent.
- none: the highlight changed for another reason, such as automatic highlighting while
filtering, the item list changing, or the popup opening or closing.
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.