Menubar
Persistent horizontal command surface on bits-ui Menubar. Hover across triggers to pass focus; open content zoom-fades in from the top edge.
Usage
menubar.svelte
<script lang="ts">
import { Menubar as MenubarPrimitive } from 'bits-ui';
import { cn } from '$lib/utils.js';
let {
ref = $bindable(null),
class: className,
...restProps
}: MenubarPrimitive.RootProps = $props();
</script>
<MenubarPrimitive.Root
bind:ref
data-slot="menubar"
class={cn('flex h-9 items-center rounded-(--radius-control) border p-1', className)}
{...restProps}
/>
Inverted
Pass variant="inverted" on each menu’s content for a dark
surface over a light app — Bloom’s signature menu identity.
menubar-inverted.svelte
<Menubar.Content variant="inverted">
<Menubar.Item>Undo</Menubar.Item>
<Menubar.Item>Redo</Menubar.Item>
<Menubar.Separator />
<Menubar.Item>Cut</Menubar.Item>
</Menubar.Content>Sub-menu
Menubar.Sub nests another content surface that opens to the
side on hover or keyboard focus.
menubar-sub.svelte
<Menubar.Sub>
<Menubar.SubTrigger>Share</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.Item>Email link</Menubar.Item>
<Menubar.Item>Messages</Menubar.Item>
</Menubar.SubContent>
</Menubar.Sub>Checkbox item
Menubar.CheckboxItem binds to a boolean and toggles in place;
the indicator slot renders a check when checked.
menubar-checkbox.svelte
<Menubar.CheckboxItem bind:checked={bookmarks}>Show bookmarks</Menubar.CheckboxItem>Radio item
Wrap Menubar.RadioItem in a Menubar.RadioGroup with a bound value to enforce single-select.
menubar-radio.svelte
<Menubar.RadioGroup bind:value={layout}>
<Menubar.RadioItem value="comfortable">Comfortable</Menubar.RadioItem>
<Menubar.RadioItem value="compact">Compact</Menubar.RadioItem>
</Menubar.RadioGroup>Menubar.Root props
Inherits bits-ui Menubar.Root props via spread. Renders as a horizontal pill bar (rounded-(--radius-control)) with border.
| Prop | Type | Default | Description |
|---|---|---|---|
string (bindable) | — | The id of the menu currently open, if any. | |
'ltr' | 'rtl' | 'ltr' | Reading direction — affects submenu side. | |
boolean | true | Arrow-key focus wraps at the ends when true. | |
string | — | Merged onto the bar container via tailwind-merge. |
Menubar.Content props
| Prop | Type | Default | Description |
|---|---|---|---|
'default' | 'inverted' | 'default' | Surface treatment. Inverted swaps popover/accent CSS vars to render dark on light (and light on dark) — Bloom’s signature menu identity. | |
'top' | 'right' | 'bottom' | 'left' | 'bottom' | Preferred anchor side relative to the trigger. | |
number | 8 | Distance in px from the bar edge. | |
number | -4 | Cross-axis offset so menus stack flush with the trigger. | |
ComponentProps<Menubar.Portal> | — | Forwarded to the internal portal. |