Menubar

The File, Edit, View row of a desktop-style app. One tab stop, arrow keys across the menus, and once one is open the next opens on hover. The menus are Dropdown Menu's panels, so both read as one object.

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add menubar

Usage#

usage.tsxTSX
import {  Menubar,  MenubarMenu,  MenubarTrigger,  MenubarContent,  MenubarItem,  MenubarShortcut,} from "@/components/ui/menubar"export function Example() {  return (    <Menubar>      <MenubarMenu>        <MenubarTrigger>File</MenubarTrigger>        <MenubarContent>          <MenubarItem>            New document <MenubarShortcut>⌘N</MenubarShortcut>          </MenubarItem>        </MenubarContent>      </MenubarMenu>    </Menubar>  )}

Anatomy#

import {  Menubar,  MenubarMenu,  MenubarTrigger,  MenubarContent,  MenubarItem,  MenubarCheckboxItem,  MenubarRadioGroup,  MenubarRadioItem,  MenubarLabel,  MenubarSeparator,  MenubarShortcut,  MenubarSub,  MenubarSubTrigger,  MenubarSubContent,} from "@/components/ui/menubar"<Menubar>  <MenubarMenu>    <MenubarTrigger />    <MenubarContent>      <MenubarLabel />      <MenubarItem>        <MenubarShortcut />      </MenubarItem>      <MenubarCheckboxItem />      <MenubarRadioGroup>        <MenubarRadioItem />      </MenubarRadioGroup>      <MenubarSeparator />      <MenubarSub>        <MenubarSubTrigger />        <MenubarSubContent>…</MenubarSubContent>      </MenubarSub>    </MenubarContent>  </MenubarMenu></Menubar>

Variants#

outline (the default) is the Toolbar's band: a 12px radius around 4px of padding and 8px triggers, so the corners nest concentrically, with an inset edge that takes no layout. plain drops the band for an app header that already owns one. Either way the open menu lights its trigger, so the bar always shows which menu you are in.

outline
plain

Checkbox, radio and switch rows#

The rows are Dropdown Menu's: a checked row or the chosen radio carries the ink check on the right, on the same 12px edge line as the shortcuts. variant="switch" on a checkbox row draws a mini Switch there instead, for a setting that applies the moment it flips, and keeps the menu open so several can be flipped in a row.

Density#

The menus follow the density around the bar: 36px rows when comfortable, 32px when compact. React context crosses the portal the menus open in, so one DensityProvider around the bar sets every menu in it. The edge inset and the corners stay put at either density.

comfortable
compact

Keyboard#

The whole bar is one tab stop. Left and Right move between menus, Down or Enter opens one, and once a menu is open, Left and Right (or the pointer) open its neighbours instead, the way an application menu behaves. Escape closes the menu and puts focus back on its trigger. Shortcuts are display only: bind the keys yourself.

API reference#

Menubar

The bar, role="menubar", over Radix Menubar.Root, and forwards its props. Every part accepts className, merged last.

PropTypeDefaultDescription
variant"outline" | "plain""outline"outline is the concentric band with an inset edge; plain drops it for a header that owns one.
valuestring-The open menu's value, controlled.
defaultValuestring-The menu open on first render, uncontrolled.
onValueChange(value: string) => void-Called when a menu opens or closes (an empty string when none is open).
loopbooleantrueArrow keys wrap from the last trigger to the first.
dir"ltr" | "rtl"-Reading direction for arrow-key navigation.

MenubarMenu

One menu: wraps its trigger and content. Radix Menubar.Menu, re-exported as is.

PropTypeDefaultDescription
valuestring-Identifies the menu for the bar's value. Generated when omitted.

MenubarTrigger

The button that opens its menu; it lights while the menu is open. Forwards Radix Menubar.Trigger props.

Data attributeDescription
data-stateopen while its menu is open, otherwise closed.
data-highlightedPresent while the trigger has keyboard focus.
data-disabledPresent when disabled.

MenubarContent

The menu panel, portalled to the body and built from Dropdown Menu's recipe. Forwards Radix Menubar.Content props.

PropTypeDefaultDescription
align"start" | "center" | "end""start"Alignment against the trigger.
alignOffsetnumber-2Puts the rows' text on the trigger's text line.
sideOffsetnumber8Gap from the trigger, clearing the band's padding.
collisionPaddingnumber8Keeps the panel off the viewport edge.
density"comfortable" | "compact"-Row height (36 or 32px). Inherits the nearest DensityProvider when unset.
Data attributeDescription
data-stateopen or closed, for the enter and exit animation.
data-sideThe side the panel landed on after collision handling.
data-alignThe resolved alignment.
CSS variableDescription
--radix-menubar-content-transform-originThe point the panel scales from, set by Radix.
--radix-menubar-content-available-heightRoom between the trigger and the viewport edge.

MenubarItem

A command row. Forwards Radix Menubar.Item props (onSelect, disabled, textValue).

PropTypeDefaultDescription
variant"default" | "destructive""default"destructive turns the whole row red, icon included.
insetbooleanfalseIndents the text to line up with icon-bearing rows.
density"comfortable" | "compact"-Row height (36 or 32px). Inherits the nearest DensityProvider when unset.
Data attributeDescription
data-highlightedPresent while the row is highlighted by pointer or keyboard.
data-disabledPresent when disabled.
data-insetPresent when inset.

MenubarCheckboxItem

A toggle row. Forwards Radix Menubar.CheckboxItem props (checked, onCheckedChange).

PropTypeDefaultDescription
variant"check" | "switch""check"check is the ink check; switch is a mini Switch, for a setting that applies the moment it flips.
closeOnSelectboolean-Closes the menu on toggle. Defaults to true for check and false for switch.
density"comfortable" | "compact"-Row height (36 or 32px). Inherits the nearest DensityProvider when unset.
Data attributeDescription
data-statechecked, unchecked or indeterminate.
data-highlightedPresent while the row is highlighted.
data-disabledPresent when disabled.

MenubarRadioGroup

Groups radio rows. Radix Menubar.RadioGroup, re-exported as is.

PropTypeDefaultDescription
valuestring-The checked row's value.
onValueChange(value: string) => void-Called when another row is picked.

MenubarRadioItem

One exclusive choice inside a MenubarRadioGroup, sharing the checkbox row's ink check. Forwards Radix Menubar.RadioItem props.

PropTypeDefaultDescription
value*string-The value the group reports.
density"comfortable" | "compact"-Row height (36 or 32px). Inherits the nearest DensityProvider when unset.
Data attributeDescription
data-statechecked or unchecked.
data-highlightedPresent while the row is highlighted.

MenubarLabel

A non-interactive heading over a run of rows. Forwards Radix Menubar.Label props.

PropTypeDefaultDescription
insetbooleanfalseIndents the text to line up with icon-bearing rows.
density"comfortable" | "compact"-Row height (36 or 32px). Inherits the nearest DensityProvider when unset.

MenubarSeparator

A hairline between groups of rows. Forwards Radix Menubar.Separator props.

PropTypeDefaultDescription
density"comfortable" | "compact"-Row height (36 or 32px). Inherits the nearest DensityProvider when unset.

MenubarShortcut

The row's shortcut, a small Kbd chip on the right edge. Display only: bind the keys yourself. Forwards Kbd props.

MenubarGroup

Groups related rows for assistive tech. Radix Menubar.Group, re-exported as is.

MenubarSub

A nested menu: wraps a sub-trigger and its panel. Radix Menubar.Sub, re-exported as is.

PropTypeDefaultDescription
openboolean-Controlled open state.
defaultOpenboolean-Open on first render, uncontrolled.
onOpenChange(open: boolean) => void-Called when the submenu opens or closes.

MenubarSubTrigger

The row that opens a submenu, with a trailing caret. Forwards Radix Menubar.SubTrigger props.

PropTypeDefaultDescription
insetbooleanfalseIndents the text to line up with icon-bearing rows.
density"comfortable" | "compact"-Row height (36 or 32px). Inherits the nearest DensityProvider when unset.
Data attributeDescription
data-stateopen while its submenu is open, otherwise closed.
data-highlightedPresent while the row is highlighted.

MenubarSubContent

The submenu panel, portalled to the body. Forwards Radix Menubar.SubContent props.

PropTypeDefaultDescription
density"comfortable" | "compact"-Row height (36 or 32px). Inherits the nearest DensityProvider when unset.
Data attributeDescription
data-stateopen or closed.
data-sideThe side the panel landed on.

MenubarPortal

Radix Menubar.Portal, re-exported for custom panels. MenubarContent and MenubarSubContent already portal themselves.

FAQ#

A Menubar is a vocabulary of menus for an app with many commands (File, Edit, View). One menu behind a button is a Dropdown Menu. A row of icon actions, toggles and separators is a Toolbar.