A visually persistent menu common in desktop applications that provides quick access to a consistent set of commands.
<Menubar.root
id="menubar-primitive"
class="DemoMenubarRoot"
>
<Menubar.menu value="file">
<Menubar.trigger
id="file-trigger"
content_id="file-content"
class="DemoMenubarTrigger"
>
File
</Menubar.trigger>
<Menubar.content
id="file-content"
class="DemoMenubarContent"
align="start"
side_offset={5}
>
<Menubar.item class="DemoMenubarItem">
New Tab
<div class="DemoRightSlot">⌘ T</div>
</Menubar.item>
<Menubar.item class="DemoMenubarItem">
New Window
<div class="DemoRightSlot">⌘ N</div>
</Menubar.item>
<Menubar.item
class="DemoMenubarItem"
disabled
>
New Incognito Window
</Menubar.item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.sub>
<Menubar.sub_trigger class="DemoMenubarSubTrigger">
Share
<div class="DemoRightSlot">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.61514 7.15788C10.7954 7.3502 10.7954 7.64949 10.61514 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z"
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"
>
</path>
</svg>
</div>
</Menubar.sub_trigger>
<Menubar.sub_content class="DemoMenubarSubContent">
<Menubar.item class="DemoMenubarItem">Email Link</Menubar.item>
<Menubar.item class="DemoMenubarItem">Messages</Menubar.item>
<Menubar.item class="DemoMenubarItem">Notes</Menubar.item>
</Menubar.sub_content>
</Menubar.sub>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem">
Print…
<div class="DemoRightSlot">⌘ P</div>
</Menubar.item>
</Menubar.content>
</Menubar.menu>
<Menubar.menu value="edit">
<Menubar.trigger
id="edit-trigger"
content_id="edit-content"
class="DemoMenubarTrigger"
>
Edit
</Menubar.trigger>
<Menubar.content
id="edit-content"
class="DemoMenubarContent"
align="start"
side_offset={5}
>
<Menubar.item class="DemoMenubarItem">
Undo
<div class="DemoRightSlot">⌘ Z</div>
</Menubar.item>
<Menubar.item class="DemoMenubarItem">
Redo
<div class="DemoRightSlot">⇧ ⌘ Z</div>
</Menubar.item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.sub>
<Menubar.sub_trigger class="DemoMenubarSubTrigger">
Find
<div class="DemoRightSlot">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.61514 7.15788C10.7954 7.3502 10.7954 7.64949 10.61514 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z"
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"
>
</path>
</svg>
</div>
</Menubar.sub_trigger>
<Menubar.sub_content class="DemoMenubarSubContent">
<Menubar.item class="DemoMenubarItem">Search the web…</Menubar.item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem">Find…</Menubar.item>
<Menubar.item class="DemoMenubarItem">Find Next</Menubar.item>
<Menubar.item class="DemoMenubarItem">Find Previous</Menubar.item>
</Menubar.sub_content>
</Menubar.sub>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem">Cut</Menubar.item>
<Menubar.item class="DemoMenubarItem">Copy</Menubar.item>
<Menubar.item class="DemoMenubarItem">Paste</Menubar.item>
</Menubar.content>
</Menubar.menu>
<Menubar.menu value="view">
<Menubar.trigger
id="view-trigger"
content_id="view-content"
class="DemoMenubarTrigger"
>
View
</Menubar.trigger>
<Menubar.content
id="view-content"
class="DemoMenubarContent"
align="start"
side_offset={5}
>
<Menubar.checkbox_item
class="DemoMenubarCheckboxItem inset"
text_value="Always Show Bookmarks Bar"
>
<Menubar.item_indicator class="DemoMenubarItemIndicator">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"
>
</path>
</svg>
</Menubar.item_indicator>
Always Show Bookmarks Bar
</Menubar.checkbox_item>
<Menubar.checkbox_item
class="DemoMenubarCheckboxItem inset"
checked
text_value="Always Show Full URLs"
>
<Menubar.item_indicator
class="DemoMenubarItemIndicator"
force_mount
>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"
>
</path>
</svg>
</Menubar.item_indicator>
Always Show Full URLs
</Menubar.checkbox_item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem inset">
Reload
<div class="DemoRightSlot">⌘ R</div>
</Menubar.item>
<Menubar.item
class="DemoMenubarItem inset"
disabled
>
Force Reload
<div class="DemoRightSlot">⇧ ⌘ R</div>
</Menubar.item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem inset">Toggle Fullscreen</Menubar.item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem inset">Hide Sidebar</Menubar.item>
</Menubar.content>
</Menubar.menu>
<Menubar.menu value="profiles">
<Menubar.trigger
id="profiles-trigger"
content_id="profiles-content"
class="DemoMenubarTrigger"
>
Profiles
</Menubar.trigger>
<Menubar.content
id="profiles-content"
class="DemoMenubarContent"
align="start"
side_offset={5}
>
<Menubar.radio_group value="Luis">
<Menubar.radio_item
class="DemoMenubarRadioItem inset"
value="Andy"
>
<Menubar.item_indicator class="DemoMenubarItemIndicator">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z"
fill="currentColor"
>
</path>
</svg>
</Menubar.item_indicator>
Andy
</Menubar.radio_item>
<Menubar.radio_item
class="DemoMenubarRadioItem inset"
value="Benoît"
>
<Menubar.item_indicator class="DemoMenubarItemIndicator">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z"
fill="currentColor"
>
</path>
</svg>
</Menubar.item_indicator>
Benoît
</Menubar.radio_item>
<Menubar.radio_item
class="DemoMenubarRadioItem inset"
value="Luis"
checked
>
<Menubar.item_indicator
class="DemoMenubarItemIndicator"
force_mount
>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z"
fill="currentColor"
>
</path>
</svg>
</Menubar.item_indicator>
Luis
</Menubar.radio_item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem inset">Edit…</Menubar.item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem inset">Add Profile…</Menubar.item>
</Menubar.radio_group>
</Menubar.content>
</Menubar.menu>
</Menubar.root>
/* reset */
button {
all: unset;
}
.DemoMenubarRoot {
display: flex;
background-color: white;
padding: 3px;
border-radius: 6px;
box-shadow: 0 2px 10px var(--black-a7);
}
.DemoMenubarTrigger {
padding: 8px 12px;
outline: none;
user-select: none;
font-weight: 500;
line-height: 1;
border-radius: 4px;
color: var(--violet-11);
font-size: 13px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 2px;
}
.DemoMenubarTrigger[data-highlighted],
.DemoMenubarTrigger[data-state="open"] {
background-color: var(--violet-4);
}
.DemoMenubarContent,
.DemoMenubarSubContent {
min-width: 220px;
background-color: white;
border-radius: 6px;
padding: 5px;
box-shadow:
0px 10px 38px -10px rgba(22, 23, 24, 0.35),
0px 10px 20px -15px rgba(22, 23, 24, 0.2);
animation-duration: 400ms;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
will-change: transform, opacity;
}
.DemoMenubarItem,
.DemoMenubarSubTrigger,
.DemoMenubarCheckboxItem,
.DemoMenubarRadioItem {
all: unset;
font-size: 13px;
line-height: 1;
color: var(--violet-11);
border-radius: 4px;
display: flex;
align-items: center;
height: 25px;
padding: 0 10px;
position: relative;
user-select: none;
}
.DemoMenubarItem.inset,
.DemoMenubarSubTrigger.inset,
.DemoMenubarCheckboxItem.inset,
.DemoMenubarRadioItem.inset {
padding-left: 20px;
}
.DemoMenubarItem[data-state="open"],
.DemoMenubarSubTrigger[data-state="open"] {
background-color: var(--violet-4);
color: var(--violet-11);
}
.DemoMenubarItem[data-highlighted],
.DemoMenubarSubTrigger[data-highlighted],
.DemoMenubarCheckboxItem[data-highlighted],
.DemoMenubarRadioItem[data-highlighted] {
background-image: linear-gradient(
135deg,
var(--violet-9) 0%,
var(--violet-10) 100%
);
color: var(--violet-1);
}
.DemoMenubarItem[data-disabled],
.DemoMenubarSubTrigger[data-disabled],
.DemoMenubarCheckboxItem[data-disabled],
.DemoMenubarRadioItem[data-disabled] {
color: var(--mauve-8);
pointer-events: none;
}
.DemoMenubarItemIndicator {
position: absolute;
left: 0;
width: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.DemoMenubarSeparator {
height: 1px;
background-color: var(--violet-6);
margin: 5px;
}
.DemoRightSlot {
margin-left: auto;
padding-left: 20px;
color: var(--mauve-9);
}
[data-highlighted] > .DemoRightSlot {
color: white;
}
[data-disabled] > .DemoRightSlot {
color: var(--mauve-8);
}
.DemoMenubarLabel {
padding-left: 25px;
font-size: 12px;
line-height: 25px;
color: var(--mauve-11);
}
Anatomy
Import all parts and piece them together.
<Menubar.root id="…">
<Menubar.menu value="…">
<Menubar.trigger content_id="…" />
<Menubar.portal>
<Menubar.content id="…">
<Menubar.label />
<Menubar.item />
<Menubar.group>
<Menubar.item />
</Menubar.group>
<Menubar.checkbox_item>
<Menubar.item_indicator />
</Menubar.checkbox_item>
<Menubar.radio_group>
<Menubar.radio_item>
<Menubar.item_indicator />
</Menubar.radio_item>
</Menubar.radio_group>
<Menubar.sub>
<Menubar.sub_trigger />
<Menubar.sub_content />
</Menubar.sub>
<Menubar.separator />
</Menubar.content>
</Menubar.portal>
</Menubar.menu>
</Menubar.root>
Anatomy
-
Root - Contains all the parts of a menubar.
-
Menu - A top-level menu item containing a trigger and content.
-
Trigger - The button that toggles the menu content.
-
Portal - Portals the content into the document (default `body`).
-
Content - The component that pops out when a menu is open.
-
Item - An actionable menu item.
-
Checkbox Item - An item that can be checked or unchecked.
-
Radio Group - Groups mutually exclusive `radio_item` parts.
-
Radio Item - An item that can be selected among a radio group.
-
Item Indicator - Renders when a checkbox or radio item is checked.
-
Label - A non-focusable section label.
-
Separator - Visually separates groups of items.
-
Group - Groups multiple items.
-
Sub - Contains all the parts of a submenu.
-
Sub Trigger - An item that opens a submenu.
-
Sub Content - The submenu panel.
API Reference
Root
Contains all the parts of a menubar.
| Prop | Type | Default | Description |
|---|---|---|---|
dir
|
string
|
"ltr"
|
|
id
|
string
|
—
|
|
loop
|
boolean
|
true
|
|
orientation
|
string
|
"horizontal"
|
dir
string
Default
"ltr"
id
string
Default
—
loop
boolean
Default
true
orientation
string
Default
"horizontal"
Menu
A top level menu item, contains a trigger with content combination.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
|
value
|
string
|
nil
|
id
string
Default
nil
value
string
Default
nil
Trigger
The button that toggles the content. By default, Menubar.content positions itself against the trigger.
| Prop | Type | Default | Description |
|---|---|---|---|
content_id
|
string
|
nil
|
|
disabled
|
boolean
|
false
|
|
id
|
string
|
nil
|
content_id
string
Default
nil
disabled
boolean
Default
false
id
string
Default
nil
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
open | closed
|
Reflects whether the menu is open. |
[data-highlighted]
|
Present when highlighted
|
Present when the trigger is highlighted. |
[data-disabled]
|
Present when disabled
|
Present when the trigger is disabled. |
Portal
When used, portals the content part into the target (default body).
| Prop | Type | Default | Description |
|---|---|---|---|
class
|
any
|
nil
|
|
container
|
string
|
"div"
|
|
id
|
string
|
—
|
|
target
|
string
|
"body"
|
class
any
Default
nil
container
string
Default
"div"
id
string
Default
—
target
string
Default
"body"
Content
The component that pops out when a menu is open.
| Prop | Type | Default | Description |
|---|---|---|---|
align
|
string
|
"start"
|
|
id
|
string
|
nil
|
|
loop
|
boolean
|
true
|
|
side
|
string
|
"bottom"
|
|
side_offset
|
integer
|
4
|
align
string
Default
"start"
id
string
Default
nil
loop
boolean
Default
true
side
string
Default
"bottom"
side_offset
integer
Default
4
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
open | closed
|
Reflects whether the menu is open. |
[data-side]
|
left | right | bottom | top
|
The side the content rendered against. |
[data-align]
|
start | end | center
|
The alignment against the trigger. |
| CSS variable | Description |
| --- | --- |
| --radix-menubar-content-transform-origin | The transform-origin computed from content and arrow positions/offsets |
| --radix-menubar-content-available-width | Remaining width between the trigger and the boundary edge |
| --radix-menubar-content-available-height | Remaining height between the trigger and the boundary edge |
| --radix-menubar-trigger-width | The width of the trigger |
| --radix-menubar-trigger-height | The height of the trigger |
Item
The component that contains the menubar items.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled
|
boolean
|
false
|
|
id
|
string
|
nil
|
|
text_value
|
string
|
nil
|
disabled
boolean
Default
false
id
string
Default
nil
text_value
string
Default
nil
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-highlighted]
|
Present when highlighted
|
Present when the item is highlighted. |
[data-disabled]
|
Present when disabled
|
Present when the item is disabled. |
Checkbox Item
An item that can be controlled and rendered like a checkbox.
| Prop | Type | Default | Description |
|---|---|---|---|
checked
|
boolean
|
false
|
|
disabled
|
boolean
|
false
|
|
id
|
string
|
nil
|
|
text_value
|
string
|
nil
|
checked
boolean
Default
false
disabled
boolean
Default
false
id
string
Default
nil
text_value
string
Default
nil
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
checked | unchecked
|
Reflects the checked state. |
[data-highlighted]
|
Present when highlighted
|
Present when the item is highlighted. |
[data-disabled]
|
Present when disabled
|
Present when the item is disabled. |
Radio Group
Used to group multiple Menubar.radio_item parts.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
|
value
|
string
|
nil
|
id
string
Default
nil
value
string
Default
nil
Radio Item
An item that can be controlled and rendered like a radio.
| Prop | Type | Default | Description |
|---|---|---|---|
checked
|
boolean
|
false
|
|
disabled
|
boolean
|
false
|
|
id
|
string
|
nil
|
|
text_value
|
string
|
nil
|
|
value
|
string
|
—
|
checked
boolean
Default
false
disabled
boolean
Default
false
id
string
Default
nil
text_value
string
Default
nil
value
string
Default
—
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
checked | unchecked
|
Reflects the selected state. |
[data-highlighted]
|
Present when highlighted
|
Present when the item is highlighted. |
[data-disabled]
|
Present when disabled
|
Present when the item is disabled. |
Item Indicator
Renders when the parent checkbox_item or radio_item is checked.
| Prop | Type | Default | Description |
|---|---|---|---|
force_mount
|
boolean
|
false
|
|
id
|
string
|
nil
|
force_mount
boolean
Default
false
id
string
Default
nil
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
checked | unchecked
|
Reflects the checked state of the parent item. |
Label
Used to render a label. It won't be focusable using arrow keys.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
id
string
Default
nil
Separator
Used to visually separate items in a menubar menu.
| Prop | Type | Default | Description |
|---|---|---|---|
decorative
|
boolean
|
true
|
|
id
|
string
|
nil
|
decorative
boolean
Default
true
id
string
Default
nil
Group
Used to group multiple Menubar.item parts.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
id
string
Default
nil
Sub
Contains all the parts of a submenu.
| Prop | Type | Default | Description |
|---|---|---|---|
id
|
string
|
nil
|
|
open
|
boolean
|
false
|
id
string
Default
nil
open
boolean
Default
false
Sub Trigger
An item that opens a submenu. Must be rendered inside Menubar.sub.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled
|
boolean
|
false
|
|
id
|
string
|
nil
|
|
text_value
|
string
|
nil
|
disabled
boolean
Default
false
id
string
Default
nil
text_value
string
Default
nil
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
open | closed
|
Reflects whether the submenu is open. |
[data-highlighted]
|
Present when highlighted
|
Present when the item is highlighted. |
[data-disabled]
|
Present when disabled
|
Present when the item is disabled. |
Sub Content
The component that pops out when a submenu is open. Must be rendered inside Menubar.sub.
| Prop | Type | Default | Description |
|---|---|---|---|
align
|
string
|
"start"
|
|
id
|
string
|
nil
|
|
side
|
string
|
"right"
|
|
side_offset
|
integer
|
0
|
align
string
Default
"start"
id
string
Default
nil
side
string
Default
"right"
side_offset
integer
Default
0
Data attributes
| Attribute | Values | Description |
|---|---|---|
[data-state]
|
open | closed
|
Reflects whether the submenu is open. |
[data-side]
|
left | right | bottom | top
|
The side the submenu rendered against. |
[data-align]
|
start | end | center
|
The alignment of the submenu. |
[data-orientation]
|
vertical | horizontal
|
The orientation of the submenu. |
Examples
With submenus
You can create submenus by using Menubar.sub in combination with its parts.
<Menubar.root id="menubar-sub">
<Menubar.menu value="file">
<Menubar.trigger id="menubar-sub-trigger" content_id="menubar-sub-content">…</Menubar.trigger>
<Menubar.content id="menubar-sub-content">
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.sub>
<Menubar.sub_trigger class="DemoMenubarSubTrigger">Sub menu →</Menubar.sub_trigger>
<Menubar.sub_content class="DemoMenubarSubContent">
<Menubar.item class="DemoMenubarItem">Sub menu item</Menubar.item>
<Menubar.item class="DemoMenubarItem">Sub menu item</Menubar.item>
</Menubar.sub_content>
</Menubar.sub>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
</Menubar.content>
</Menubar.menu>
</Menubar.root>
With disabled items
You can add special styles to disabled items via the data-disabled attribute.
<Menubar.root id="menubar-disabled">
<Menubar.menu value="file">
<Menubar.trigger id="menubar-disabled-trigger" content_id="menubar-disabled-content">…</Menubar.trigger>
<Menubar.content id="menubar-disabled-content">
<Menubar.item class="DemoMenubarItem" disabled>…</Menubar.item>
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
</Menubar.content>
</Menubar.menu>
</Menubar.root>
.DemoMenubarItem[data-disabled] {
color: gainsboro;
}
With separators
Use the separator part to add a separator between items.
<Menubar.root id="menubar-separators">
<Menubar.menu value="file">
<Menubar.trigger id="menubar-separators-trigger" content_id="menubar-separators-content">…</Menubar.trigger>
<Menubar.content id="menubar-separators-content">
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
</Menubar.content>
</Menubar.menu>
</Menubar.root>
With labels
Use the label part to help label a section.
<Menubar.root id="menubar-labels">
<Menubar.menu value="file">
<Menubar.trigger id="menubar-labels-trigger" content_id="menubar-labels-content">…</Menubar.trigger>
<Menubar.content id="menubar-labels-content">
<Menubar.label class="DemoMenubarLabel">Label</Menubar.label>
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
</Menubar.content>
</Menubar.menu>
</Menubar.root>
With checkbox items
Use the checkbox_item part to add an item that can be checked. Pass checked from LiveView assigns to control state.
<Menubar.root id="menubar-checkbox">
<Menubar.menu value="view">
<Menubar.trigger id="menubar-checkbox-trigger" content_id="menubar-checkbox-content">…</Menubar.trigger>
<Menubar.content id="menubar-checkbox-content">
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
<Menubar.item class="DemoMenubarItem">…</Menubar.item>
<Menubar.separator class="DemoMenubarSeparator" />
<Menubar.checkbox_item checked={@checked} class="DemoMenubarCheckboxItem" text_value="Checkbox item">
<Menubar.item_indicator class="DemoMenubarItemIndicator">✓</Menubar.item_indicator>
Checkbox item
</Menubar.checkbox_item>
</Menubar.content>
</Menubar.menu>
</Menubar.root>
With radio items
Use the radio_group and radio_item parts to add an item that can be checked amongst others.
<Menubar.root id="menubar-radio">
<Menubar.menu value="profiles">
<Menubar.trigger id="menubar-radio-trigger" content_id="menubar-radio-content">…</Menubar.trigger>
<Menubar.content id="menubar-radio-content">
<Menubar.radio_group value={@color}>
<Menubar.radio_item value="red" checked={@color == "red"} class="DemoMenubarRadioItem">
<Menubar.item_indicator class="DemoMenubarItemIndicator">●</Menubar.item_indicator>
Red
</Menubar.radio_item>
<Menubar.radio_item value="blue" checked={@color == "blue"} class="DemoMenubarRadioItem">
<Menubar.item_indicator class="DemoMenubarItemIndicator">●</Menubar.item_indicator>
Blue
</Menubar.radio_item>
</Menubar.radio_group>
</Menubar.content>
</Menubar.menu>
</Menubar.root>
With complex items
You can add extra decorative elements in the item parts, such as images.
<Menubar.root id="menubar-complex">
<Menubar.menu value="people">
<Menubar.trigger id="menubar-complex-trigger" content_id="menubar-complex-content">…</Menubar.trigger>
<Menubar.content id="menubar-complex-content">
<Menubar.item class="DemoMenubarItem">
<img src="…" alt="" />
Adolfo Hess
</Menubar.item>
<Menubar.item class="DemoMenubarItem">
<img src="…" alt="" />
Miyah Myles
</Menubar.item>
</Menubar.content>
</Menubar.menu>
</Menubar.root>
Constrain the content/sub-content size
You may want to constrain the width of the content (or sub-content) so that it matches the trigger width, or 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.
<Menubar.root id="menubar-constrain">
<Menubar.menu value="file">
<Menubar.trigger id="menubar-constrain-trigger" content_id="menubar-constrain-content">…</Menubar.trigger>
<Menubar.content id="menubar-constrain-content" class="DemoMenubarContent" side_offset={5}>
…
</Menubar.content>
</Menubar.menu>
</Menubar.root>
.DemoMenubarContent {
width: var(--radix-menubar-trigger-width);
max-height: var(--radix-menubar-content-available-height);
}
Origin-aware animations
We expose a CSS custom property --radix-menubar-content-transform-origin. Use it to animate the content from its computed origin based on side, side_offset, align, and any collisions.
<Menubar.root id="menubar-origin">
<Menubar.menu value="file">
<Menubar.trigger id="menubar-origin-trigger" content_id="menubar-origin-content">…</Menubar.trigger>
<Menubar.content id="menubar-origin-content" class="DemoMenubarContent">…</Menubar.content>
</Menubar.menu>
</Menubar.root>
.DemoMenubarContent {
transform-origin: var(--radix-menubar-content-transform-origin);
animation: scaleIn 0.5s ease-out;
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0);
}
to {
opacity: 1;
transform: scale(1);
}
}
Collision-aware animations
We expose data-side and data-align attributes. Their values change at runtime to reflect collisions. Use them to create collision and direction-aware animations.
<Menubar.root id="menubar-collision">
<Menubar.menu value="file">
<Menubar.trigger id="menubar-collision-trigger" content_id="menubar-collision-content">…</Menubar.trigger>
<Menubar.content id="menubar-collision-content" class="DemoMenubarContent">…</Menubar.content>
</Menubar.menu>
</Menubar.root>
.DemoMenubarContent {
animation-duration: 0.6s;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.DemoMenubarContent[data-side="top"] {
animation-name: slideUp;
}
.DemoMenubarContent[data-side="bottom"] {
animation-name: slideDown;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
Accessibility
Adheres to the Menu Button WAI-ARIA design pattern and uses roving tabindex to manage focus movement among menu items.
Keyboard Interactions
Keyboard Interactions
| Key | Description |
|---|---|
Space
|
When focus is on `Menubar.trigger`, opens the menubar and focuses the first item. When focus is on an item, activates the focused item. |
Enter
|
When focus is on `Menubar.trigger`, opens the associated menu. When focus is on an item, activates the focused item. |
ArrowDown
|
When focus is on `Menubar.trigger`, opens the associated menu. When focus is on an item, moves focus to the next item. |
ArrowUp
|
When focus is on an item, moves focus to the previous item. |
ArrowRight, ArrowLeft
|
When focus is on a `Menubar.trigger`, moves focus to the next or previous item. When focus is on a `Menubar.sub_trigger`, opens or closes the submenu depending on reading direction. When focus is within a `Menubar.content`, opens the next menu in the menubar. |
Esc
|
Closes the currently open menu and moves focus to its `Menubar.trigger`. |