menubar
A visually persistent menu common in desktop applications that provides quick access to a consistent set of commands.
Philosophy
Menubars bring desktop-application navigation patterns to the web. The keyboard model (arrow keys between menus, type-ahead navigation, submenu traversal) follows established platform conventions and is powered by @gentleduck/primitives/menubar.
Installation
npx @gentleduck/cli add menubar
npx @gentleduck/cli add menubar
Usage
import {
Menubar,
MenubarContent,
MenubarItem,
MenubarMenu,
MenubarSeparator,
MenubarShortcut,
MenubarTrigger,
} from "@/components/ui/menubar"import {
Menubar,
MenubarContent,
MenubarItem,
MenubarMenu,
MenubarSeparator,
MenubarShortcut,
MenubarTrigger,
} from "@/components/ui/menubar"<Menubar>
<MenubarMenu>
<MenubarTrigger>File</MenubarTrigger>
<MenubarContent>
<MenubarItem>
New Tab <MenubarShortcut>⌘T</MenubarShortcut>
</MenubarItem>
<MenubarItem>New Window</MenubarItem>
<MenubarSeparator />
<MenubarItem>Share</MenubarItem>
<MenubarSeparator />
<MenubarItem>Print</MenubarItem>
</MenubarContent>
</MenubarMenu>
</Menubar><Menubar>
<MenubarMenu>
<MenubarTrigger>File</MenubarTrigger>
<MenubarContent>
<MenubarItem>
New Tab <MenubarShortcut>⌘T</MenubarShortcut>
</MenubarItem>
<MenubarItem>New Window</MenubarItem>
<MenubarSeparator />
<MenubarItem>Share</MenubarItem>
<MenubarSeparator />
<MenubarItem>Print</MenubarItem>
</MenubarContent>
</MenubarMenu>
</Menubar>Component Composition
API Reference
Components in this file wrap @gentleduck/primitives/menubar.
Menubar
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | '' | Controlled currently-open menu value |
defaultValue | string | '' | Initial open menu value for uncontrolled usage |
onValueChange | (value: string) => void | -- | Callback when open menu value changes |
loop | boolean | true | Loops roving focus across triggers |
dir | 'ltr' | 'rtl' | -- | Text direction. Resolved by primitives useDirection (dir prop -> DirectionProvider -> 'ltr'). |
className | string | -- | Additional CSS classes |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root> | -- | Additional props inherited from MenubarPrimitive.Root |
MenubarMenu
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | auto-generated | Unique identifier for this menu |
children | React.ReactNode | -- | Trigger and content elements for this menu |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Menu> | -- | Additional props inherited from MenubarPrimitive.Menu |
MenubarTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional CSS classes |
children | React.ReactNode | -- | Trigger label/content |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger> | -- | Additional props inherited from MenubarPrimitive.Trigger |
MenubarPortal
| Prop | Type | Default | Description |
|---|---|---|---|
container | HTMLElement | -- | Optional portal container |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Portal> | -- | Additional props inherited from MenubarPrimitive.Portal |
MenubarContent
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional CSS classes |
side | 'top' | 'right' | 'bottom' | 'left' | -- | Preferred side relative to the trigger |
align | 'start' | 'center' | 'end' | 'start' | Alignment on the chosen side |
sideOffset | number | 8 | Main-axis offset from trigger |
alignOffset | number | -4 | Cross-axis offset from trigger |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content> | -- | Additional props inherited from MenubarPrimitive.Content |
MenubarItem
| Prop | Type | Default | Description |
|---|---|---|---|
inset | boolean | false | Adds start padding for alignment with indicators/icons |
className | string | -- | Additional CSS classes |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> | -- | Additional props inherited from MenubarPrimitive.Item |
MenubarCheckboxItem
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | -- | Controlled checked state |
onCheckedChange | (checked: boolean) => void | -- | Callback when checked state changes |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem> | -- | Additional props inherited from MenubarPrimitive.CheckboxItem |
MenubarRadioGroup
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | -- | Controlled selected value |
onValueChange | (value: string) => void | -- | Callback when selected value changes |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioGroup> | -- | Additional props inherited from MenubarPrimitive.RadioGroup |
MenubarRadioItem
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | (required) | Value represented by this radio item |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem> | -- | Additional props inherited from MenubarPrimitive.RadioItem |
MenubarLabel
| Prop | Type | Default | Description |
|---|---|---|---|
inset | boolean | false | Adds start padding for alignment |
className | string | -- | Additional CSS classes |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> | -- | Additional props inherited from MenubarPrimitive.Label |
MenubarSeparator
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional CSS classes |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator> | -- | Additional props inherited from MenubarPrimitive.Separator |
MenubarShortcut
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional CSS classes |
children | React.ReactNode | -- | Shortcut hint content (for example, ⌘S) |
...props | React.HTMLAttributes<HTMLSpanElement> | -- | Additional props to spread to the shortcut <span> |
MenubarGroup
| Prop | Type | Default | Description |
|---|---|---|---|
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Group> | -- | Additional props inherited from MenubarPrimitive.Group |
MenubarSub
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | -- | Sub-trigger and sub-content elements |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Sub> | -- | Additional props inherited from MenubarPrimitive.Sub |
MenubarSubTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
inset | boolean | false | Adds start padding for alignment |
className | string | -- | Additional CSS classes |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> | -- | Additional props inherited from MenubarPrimitive.SubTrigger |
MenubarSubContent
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional CSS classes |
side | 'top' | 'right' | 'bottom' | 'left' | -- | Preferred side relative to the sub-trigger |
align | 'start' | 'center' | 'end' | -- | Alignment on the chosen side |
sideOffset | number | -- | Main-axis offset from sub-trigger |
alignOffset | number | -- | Cross-axis offset from sub-trigger |
...props | React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent> | -- | Additional props inherited from MenubarPrimitive.SubContent |
RTL Support
Set dir="rtl" on Menubar for a local override, or set DirectionProvider once at app/root level for global direction.