Menubar
A bar of menus that keeps the actions and options of a view in one place.
A menubar lines up several menus in one bar, as desktop applications do at the top of a window. Users open a menu with a press on its trigger, and while a menu is open, the pointer and the left and right arrow keys move on to the neighboring menus. A menu closes when users choose an item, press Escape or press outside of it. Checkbox and radio items keep the menu open, so users can change several options in a row. While a menu is open, the page doesn't scroll, and only the menubar and the open menu react to the pointer. A MenubarLabel needs a MenubarGroup or a MenubarRadioGroup around it and names that group for assistive technology.
Usage
Examples
With Label
Actions in a menu often apply to one specific record, such as a single order. A label gives their group a name, so users know what each action refers to before they choose it, and assistive technology announces that name with the group.
With Separator
Long menus are easier to scan when related actions stay together. Between two such sets, a separator marks where one ends and the next begins, so users find the actions that change a record apart from those that share it. The division also reaches assistive technology, which reports it as a separator.
With Icon
Users who return to a menu every day recognize its actions by their shape before they read them. An icon inside an item offers that cue to the eye, while the text keeps naming the action for everyone who meets it for the first time.
With Shortcut
Experienced users reach frequent actions faster with the keyboard than through a menu. Shown inside an item, the shortcut teaches the key combination whenever users open the menu. It informs only, so the application registers the keys and runs the action itself.
With Checkbox Items
Some options can be combined freely, such as the details a report includes. Checkbox items switch each option on or off on its own, and the menu stays open, so users adjust several options in one pass. With defaultChecked, an option is switched on from the start.
With Radio Group
Where a setting allows exactly one choice, such as the sort order of a list, a radio group lets users select one option and clears the previous one. The menu stays open after each selection, and defaultValue sets the option that applies from the start.
With Submenu
Rarely used options crowd a menu that users open many times a day. A submenu gathers them behind a single item and opens when the pointer rests on that item, on a press or from the keyboard. Escape then closes only the submenu, so users return to the menu without losing their place.
Destructive
Deleting a record from a menu often cannot be undone. With variant set to "destructive", the item signals that consequence, so users pause before they choose it.
Inset
When only some items carry an icon, their text no longer lines up. Through inset, an item or a label without an icon takes the same indent, so users read the menu as one even list.
Item as Link
Navigation menus lead users to another page instead of changing the current one. Given an anchor through render, an item becomes a real link, so users can open the page in a new tab or follow it with the keyboard, as with any link.
Controlled
An application sometimes needs to open a menu itself, for example from a keyboard shortcut elsewhere, or to close it once a longer action has finished. Through open and onOpenChange, it holds the open state of the menu, while users still open and close the menu as usual.
Controlled Submenu
Some submenus hold options that the application loads only when users open them. The application learns that moment once it holds the state through open and onOpenChange, and it can open or close the submenu on its own as well.
Controlled Checkbox Items
Menu options often shape a view elsewhere on the screen, such as the filters of a list. With checked and onCheckedChange, the application holds each option, so the view follows every change at once, and other controls, such as a reset button, can change the options as well.
Controlled Radio Group
A currency or a unit of measure chosen in a menu often matters beyond the current visit. Once the radio group receives value and onValueChange, the selection lives in the application, which can store it for the next visit or reflect a choice that users made elsewhere.
Disabled
While an import runs or a document is being saved, the actions on that data have to wait. The disabled prop of the menubar locks every trigger at once, so users can't open any menu until the process has finished.
Disabled Menu
Sometimes only one group of actions is unavailable, for example because users lack the permission for it. Applied to a single menu, disabled locks its trigger together with every item, and the other menus stay usable.
Disabled Trigger
Each trigger can also be locked on its own. Users then can't open the menu through a trigger that carries disabled, while the menu itself stays enabled for other triggers that share it.
Disabled Item
Until an order has been approved, the actions that depend on it cannot run. In that case, disabled keeps users from choosing the item, yet the arrow keys still move to it, so keyboard users also learn that the action exists.
Disabled Submenu Trigger
Whole sets of options can be unavailable at once, for example when a feature isn't part of the current plan. A submenu trigger marked as disabled no longer opens its submenu, while the other items of the menu remain available.
Disabled Radio Group
Settings reserved for a manager remain visible to everyone else, but only as information. With disabled on the radio group, users can't select another option, and the current selection still shows which setting applies.
API Reference
Menubar
| Prop | modal |
|---|---|
| Type | boolean |
| Default | true |
| Description | Locks the page while a menu is open: the page doesn't scroll, and elements outside of the menubar and the open menu don't react to the pointer. Set it to false to keep the rest of the page usable. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from opening the menus of the menubar. It disables every trigger. |
| Prop | orientation |
|---|---|
| Type | "horizontal" | "vertical" |
| Default | "horizontal" |
| Description | Sets the arrow keys that move between the triggers: left and right for "horizontal", up and down for "vertical". It changes neither the layout of the menubar nor the side that the menus open on. |
| Prop | loopFocus |
|---|---|
| Type | boolean |
| Default | true |
| Description | Returns focus to the first trigger when users move past the last one with the arrow keys. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the menubar with another component. |
MenubarMenu
| Prop | open |
|---|---|
| Type | boolean |
| Default | – |
| Description | Sets whether the menu is open and makes it controlled. Update it in onOpenChange. |
| Prop | defaultOpen |
|---|---|
| Type | boolean |
| Default | false |
| Description | Opens the menu at first render. The menu then tracks its open state itself. |
| Prop | onOpenChange |
|---|---|
| Type | (open: boolean, eventDetails: MenuRootChangeEventDetails) => void |
| Default | – |
| Description | Runs when users open or close the menu. It receives the open state that follows. |
| Prop | onOpenChangeComplete |
|---|---|
| Type | (open: boolean) => void |
| Default | – |
| Description | Runs after the menu has opened or closed and its animations have finished. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from opening the menu. It disables the trigger and every item of the menu. |
| Prop | modal |
|---|---|
| Type | boolean |
| Default | – |
| Description | Has no effect in a menubar, so set modal on Menubar. In development, the menu logs a warning when this prop is set. |
| Prop | loopFocus |
|---|---|
| Type | boolean |
| Default | true |
| Description | Returns focus to the first item of the menu when users move past the last one with the arrow keys. |
| Prop | highlightItemOnHover |
|---|---|
| Type | boolean |
| Default | true |
| Description | Moves the highlight to the item under the pointer. With false, only the keyboard moves the highlight. |
| Prop | orientation |
|---|---|
| Type | "horizontal" | "vertical" |
| Default | "vertical" |
| Description | Sets the arrow keys that move through the items of the menu: up and down for "vertical", left and right for "horizontal". It doesn't change the layout of the items. |
| Prop | closeParentOnEsc |
|---|---|
| Type | boolean |
| Default | false |
| Description | Has an effect only in a submenu, so set it on MenubarSub. |
| Prop | triggerId |
|---|---|
| Type | string | null |
| Default | – |
| Description | Sets the ID of the trigger that a controlled menu is associated with. A menu without open doesn't need it. |
| Prop | defaultTriggerId |
|---|---|
| Type | string | null |
| Default | – |
| Description | Sets the ID of the trigger that the menu is associated with when defaultOpen opens it at first render. |
| Prop | handle |
|---|---|
| Type | MenuHandle<unknown> |
| Default | – |
| Description | Connects the menu with triggers that are rendered outside of it. Create the handle with Menu.createHandle() from @base-ui/react/menu. |
| Prop | actionsRef |
|---|---|
| Type | RefObject<MenuRootActions | null> |
| Default | – |
| Description | Receives the functions close and unmount. close closes the menu from code, and unmount removes it from the DOM after a closing animation that the code controls itself. |
| Prop | children |
|---|---|
| Type | ReactNode | ((arg: { payload: unknown }) => ReactNode) |
| Default | – |
| Description | Holds the parts of the menu. A function receives the payload of the trigger that opened the menu. |
MenubarTrigger
| Prop | openOnHover |
|---|---|
| Type | boolean |
| Default | – |
| Description | Opens the menu when the pointer moves onto the trigger. In a menubar, the pointer opens a menu only while another menu of the menubar is open, and the menubar turns this on by itself. Set it to false to turn it off for this trigger. |
| Prop | delay |
|---|---|
| Type | number |
| Default | 100 |
| Description | Has no effect in a menubar. While another menu is open, the menu opens as soon as the pointer reaches the trigger. |
| Prop | closeDelay |
|---|---|
| Type | number |
| Default | 0 |
| Description | Has no effect in a menubar. A menu that the pointer opened stays open when the pointer leaves the trigger and the menu. |
| Prop | handle |
|---|---|
| Type | MenuHandle<unknown> |
| Default | – |
| Description | Connects the trigger with a MenubarMenu that it is rendered outside of. Pass the same handle to that MenubarMenu. |
| Prop | payload |
|---|---|
| Type | unknown |
| Default | – |
| Description | Passes a value to the menu when this trigger opens it. A function as children of MenubarMenu receives it. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the trigger with another component. |
| Prop | nativeButton |
|---|---|
| Type | boolean |
| Default | true |
| Description | Declares whether the rendered element is a native button. Set it to false when render returns a different element. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from opening the menu with this trigger. |
MenubarPortal
| Prop | keepMounted |
|---|---|
| Type | boolean |
| Default | false |
| Description | Keeps the portal in the DOM while the menu is closed. MenubarContent renders a portal of its own, so the content still leaves the DOM. |
| Prop | container |
|---|---|
| Type | HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null> | null |
| Default | – |
| Description | Sets the element that the portal is rendered into. Without it, the portal is appended to the body. A MenubarContent inside the portal is rendered there as well. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the portal with another component. |
MenubarContent
| Prop | side |
|---|---|
| Type | "top" | "bottom" | "left" | "right" | "inline-end" | "inline-start" |
| Default | "bottom" |
| Description | Sets the side of the trigger that the content opens on. "inline-start" and "inline-end" follow the reading direction. The content moves to the opposite side when the chosen one has too little space. |
| Prop | sideOffset |
|---|---|
| Type | number | OffsetFunction |
| Default | 8 |
| Description | Sets the distance between the trigger and the content in pixels. A function receives the side, the alignment and the dimensions of the trigger and the content, and returns the distance. |
| Prop | align |
|---|---|
| Type | "start" | "center" | "end" |
| Default | "start" |
| Description | Sets where the content lines up with the trigger along the chosen side: at its start, its center or its end. |
| Prop | alignOffset |
|---|---|
| Type | number | OffsetFunction |
| Default | -4 |
| Description | Moves the content along the alignment axis by a number of pixels. A function receives the same data as the one for sideOffset and returns the offset. |
| Prop | finalFocus |
|---|---|
| Type | boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void) |
| Default | – |
| Description | Determines the element that receives focus when the menu closes. Without it, focus returns to the trigger or to the element that had focus before. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the content with another component. |
MenubarGroup
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the group with another component. |
MenubarLabel
| Prop | inset |
|---|---|
| Type | boolean |
| Default | – |
| Description | Indents the label so that it lines up with the text of items that start with an icon or a check mark. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the label with another component. |
MenubarItem
| Prop | variant |
|---|---|
| Type | "default" | "destructive" |
| Default | "default" |
| Description | Sets the color of the item. "destructive" colors the text and the icon of an action that deletes something or cannot be undone. |
| Prop | inset |
|---|---|
| Type | boolean |
| Default | – |
| Description | Indents the item so that its text lines up with the text of items that start with an icon or a check mark. |
| Prop | onClick |
|---|---|
| Type | (event: BaseUIEvent<MouseEvent<HTMLDivElement>>) => void |
| Default | – |
| Description | Runs when users choose the item with the pointer or the keyboard. |
| Prop | closeOnClick |
|---|---|
| Type | boolean |
| Default | true |
| Description | Closes the menu when users choose the item. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from choosing the item. The arrow keys still move to it. |
| Prop | label |
|---|---|
| Type | string |
| Default | – |
| Description | Sets the text that the item is matched against when users type to jump to an item. Without it, the item is matched against its text content. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the item with another component. |
| Prop | nativeButton |
|---|---|
| Type | boolean |
| Default | false |
| Description | Declares whether the rendered element is a native button. Set it to true when render returns a button. |
MenubarCheckboxItem
| Prop | checked |
|---|---|
| Type | boolean |
| Default | – |
| Description | Sets whether the item is checked and makes it controlled. Update it in onCheckedChange. |
| Prop | defaultChecked |
|---|---|
| Type | boolean |
| Default | false |
| Description | Checks the item at first render. The item then tracks its state itself. |
| Prop | onCheckedChange |
|---|---|
| Type | (checked: boolean, eventDetails: MenuCheckboxItemChangeEventDetails) => void |
| Default | – |
| Description | Runs when users check or uncheck the item. It receives the state that follows. |
| Prop | inset |
|---|---|
| Type | boolean |
| Default | – |
| Description | Sets the data-inset attribute on the item. The indent stays the same, because the item always keeps the space for its check mark in front of its text. |
| Prop | onClick |
|---|---|
| Type | (event: BaseUIEvent<MouseEvent<HTMLDivElement>>) => void |
| Default | – |
| Description | Runs when users choose the item with the pointer or the keyboard. |
| Prop | closeOnClick |
|---|---|
| Type | boolean |
| Default | false |
| Description | Closes the menu when users check or uncheck the item. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from checking or unchecking the item. The arrow keys still move to it. |
| Prop | label |
|---|---|
| Type | string |
| Default | – |
| Description | Sets the text that the item is matched against when users type to jump to an item. Without it, the item is matched against its text content. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the item with another component. |
| Prop | nativeButton |
|---|---|
| Type | boolean |
| Default | false |
| Description | Declares whether the rendered element is a native button. Set it to true when render returns a button. |
MenubarRadioGroup
| Prop | value |
|---|---|
| Type | any |
| Default | – |
| Description | Sets the value of the selected item and makes the radio group controlled. Update it in onValueChange. |
| Prop | defaultValue |
|---|---|
| Type | any |
| Default | – |
| Description | Sets the value of the item that is selected at first render. The radio group then tracks the selection itself. |
| Prop | onValueChange |
|---|---|
| Type | (value: any, eventDetails: MenuRadioGroupChangeEventDetails) => void |
| Default | – |
| Description | Runs when users select an item. It receives the value of that item. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from selecting any item of the radio group. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the radio group with another component. |
MenubarRadioItem
| Prop | value |
|---|---|
| Type | any |
| Default | – |
| Description | Identifies the item in value and defaultValue of the radio group. Every radio item needs one. |
| Prop | inset |
|---|---|
| Type | boolean |
| Default | – |
| Description | Sets the data-inset attribute on the item. The indent stays the same, because the item always keeps the space for its check mark in front of its text. |
| Prop | onClick |
|---|---|
| Type | (event: BaseUIEvent<MouseEvent<HTMLDivElement>>) => void |
| Default | – |
| Description | Runs when users choose the item with the pointer or the keyboard. |
| Prop | closeOnClick |
|---|---|
| Type | boolean |
| Default | false |
| Description | Closes the menu when users select the item. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from selecting the item. The arrow keys still move to it. |
| Prop | label |
|---|---|
| Type | string |
| Default | – |
| Description | Sets the text that the item is matched against when users type to jump to an item. Without it, the item is matched against its text content. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the item with another component. |
| Prop | nativeButton |
|---|---|
| Type | boolean |
| Default | false |
| Description | Declares whether the rendered element is a native button. Set it to true when render returns a button. |
MenubarSub
| Prop | open |
|---|---|
| Type | boolean |
| Default | – |
| Description | Sets whether the submenu is open and makes it controlled. Update it in onOpenChange. |
| Prop | defaultOpen |
|---|---|
| Type | boolean |
| Default | false |
| Description | Opens the submenu at first render. The submenu then tracks its open state itself. |
| Prop | onOpenChange |
|---|---|
| Type | (open: boolean, eventDetails: MenuSubmenuRootChangeEventDetails) => void |
| Default | – |
| Description | Runs when users open or close the submenu. It receives the open state that follows. |
| Prop | onOpenChangeComplete |
|---|---|
| Type | (open: boolean) => void |
| Default | – |
| Description | Runs after the submenu has opened or closed and its animations have finished. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from opening the submenu. |
| Prop | loopFocus |
|---|---|
| Type | boolean |
| Default | true |
| Description | Returns focus to the first item of the submenu when users move past the last one with the arrow keys. |
| Prop | highlightItemOnHover |
|---|---|
| Type | boolean |
| Default | true |
| Description | Moves the highlight to the item under the pointer. With false, only the keyboard moves the highlight. |
| Prop | orientation |
|---|---|
| Type | "horizontal" | "vertical" |
| Default | "vertical" |
| Description | Sets the arrow keys that move through the items of the submenu: up and down for "vertical", left and right for "horizontal". It doesn't change the layout of the items. |
| Prop | closeParentOnEsc |
|---|---|
| Type | boolean |
| Default | false |
| Description | Closes the whole menu when users press Escape in the submenu. Without it, Escape closes only the submenu. |
| Prop | actionsRef |
|---|---|
| Type | RefObject<MenuRootActions | null> |
| Default | – |
| Description | Receives the functions close and unmount. close closes the submenu from code, and unmount removes it from the DOM after a closing animation that the code controls itself. |
MenubarSubTrigger
| Prop | inset |
|---|---|
| Type | boolean |
| Default | – |
| Description | Indents the trigger so that its text lines up with the text of items that start with an icon or a check mark. |
| Prop | openOnHover |
|---|---|
| Type | boolean |
| Default | true |
| Description | Opens the submenu when the pointer rests on the trigger. With false, users open it with a press or the keyboard. |
| Prop | delay |
|---|---|
| Type | number |
| Default | 100 |
| Description | Sets how many milliseconds the pointer must rest on the trigger before the submenu opens. It has an effect only with openOnHover. |
| Prop | closeDelay |
|---|---|
| Type | number |
| Default | 0 |
| Description | Sets how many milliseconds the submenu stays open after the pointer has left it. It has an effect only with openOnHover. |
| Prop | onClick |
|---|---|
| Type | (event: BaseUIEvent<MouseEvent<HTMLDivElement>>) => void |
| Default | – |
| Description | Runs when users press the trigger with the pointer or the keyboard. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from opening the submenu with this trigger. |
| Prop | label |
|---|---|
| Type | string |
| Default | – |
| Description | Sets the text that the trigger is matched against when users type to jump to an item. Without it, the trigger is matched against its text content. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the trigger with another component. |
| Prop | nativeButton |
|---|---|
| Type | boolean |
| Default | false |
| Description | Declares whether the rendered element is a native button. Set it to true when render returns a button. |
MenubarSubContent
| Prop | side |
|---|---|
| Type | "top" | "bottom" | "left" | "right" | "inline-end" | "inline-start" |
| Default | "right" |
| Description | Sets the side of the submenu trigger that the content opens on. "inline-start" and "inline-end" follow the reading direction. The content moves to another side when the chosen one has too little space. |
| Prop | sideOffset |
|---|---|
| Type | number | OffsetFunction |
| Default | 0 |
| Description | Sets the distance between the submenu trigger and the content in pixels. A function receives the side, the alignment and the dimensions of the trigger and the content, and returns the distance. |
| Prop | align |
|---|---|
| Type | "start" | "center" | "end" |
| Default | "start" |
| Description | Sets where the content lines up with the submenu trigger along the chosen side: at its start, its center or its end. |
| Prop | alignOffset |
|---|---|
| Type | number | OffsetFunction |
| Default | -3 |
| Description | Moves the content along the alignment axis by a number of pixels. A function receives the same data as the one for sideOffset and returns the offset. |
| Prop | finalFocus |
|---|---|
| Type | boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void) |
| Default | – |
| Description | Determines the element that receives focus when the submenu closes. Without it, focus returns to the submenu trigger or to the element that had focus before. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the content with another component. |
MenubarSeparator
| Prop | orientation |
|---|---|
| Type | "horizontal" | "vertical" |
| Default | "horizontal" |
| Description | Sets the orientation that the separator reports to assistive technology. The line itself stays horizontal. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the separator with another component. |
MenubarShortcut
MenubarShortcut shows the keyboard shortcut of an item at the end of its row and doesn't handle the key press itself. It renders a span and has no props of its own.