Navigation · Menubar

Menubar

Desktop File / Edit / View bar. Exactly one menu open at a time; hover a sibling trigger while a menu is open to switch without an intermediate click. Soma owns active-menu state + cross-menu ArrowLeft/Right + typeahead + focus return on Escape. Per-menu Item / Sub / Checkbox / Radio chrome is shared with DropdownMenu — same parts, same recipe, same menu-indicator (checkbox/radio glyphs match the standalone Checkbox / RadioGroup).

parts{compiled.parts.order.length} events{events.length} sizes3 apg menubar ↗ {#if lastSelected} last{lastSelected} {/if}
File New tab New window New incognito (offline) Open recent project.svelte readme.md package.json Clear recent Print… Quit Edit Undo Redo Cut Copy Paste Find… Replace… View Show status bar Layers Ruler Grid Guides Theme Light Dark System Help Documentation Keyboard shortcuts About UIX
trace {#if trace.length === 0} click a trigger or arrow-nav between menus {:else} {#each trace.slice(0, 3) as entry} {entry.event} · {entry.family}{entry.intent ? ' · ' + entry.intent : ''} {fmtTime(entry.at)} {/each} {/if} active {activeMenu || '—'}
{#if tab === 'live'}

Controls

Soma owns active-menu state + keyboard nav across menus. Eidos adds size on the root and propagates it to per-menu Content via context.

soma Provider props
eidos visual size · bar height + trigger padding + font-size + per-menu density
Bound state · mirrors of CheckboxItem / CheckboxGroup / RadioGroup
soma headless · active-menu state + cross-menu nav svelte
{somaSnippet}
eidos visual · bar surface + trigger states + size context svelte
{eidosSnippet}
{/if} {#if tab === 'api'}

API reference

Three menubar-specific parts (Provider, Menu, Trigger, Content) plus DropdownMenu's full inner surface for Item / Sub / Checkbox / Radio. The inner parts share recipes with DropdownMenu — the menu-indicator shared partial (checkbox/radio glyphs) applies automatically.

Provider
PropTypeDefaultDescription
value bindablestring''Identifier of the currently open menu. Empty = none open.
onValueChange(value: string) => void—Fires when the active menu changes.
dir'ltr' | 'rtl''ltr'Direction for cross-menu arrow nav.
loopbooleantrueWrap cross-menu arrow at edges.
size eidosResponsiveProp<'sm' | 'md' | 'lg'>'md'Visual size — bar height + trigger padding + per-menu density (via context).
Menu
PropTypeDefaultDescription
valuestring—Unique identifier for this menu inside the menubar.
onOpenChange / onOpenChangeComplete(open: boolean) => void—Per-menu open/close + animation-settle callbacks.
Trigger
PropTypeDefaultDescription
disabledbooleanfalseDisable opening this menu via this trigger.
…native button attrsPrimitiveButtonAttributes—Renders a native <button>; all HTML button attrs flow through.
Content
PropTypeDefaultDescription
side · sideOffset · align · alignOffset · avoidCollisions · …FloatingLayerProps—Same surface as DropdownMenu.Content.
data-size eidosautofrom Menubar rootStamped via context — no need to pass per Content.
Inner parts (shared with DropdownMenu)

Item, Group, GroupHeading, Separator, Arrow, CheckboxItem, CheckboxGroup, RadioGroup, RadioItem, Sub, SubTrigger, SubContent — identical API to DropdownMenu. Eidos re-uses those wrappers so the recipe (and the menu-indicator shared partial) is one source of truth.

{/if} {#if tab === 'morfo'}

morfo · declarative contract

Source: src/uix/morfo/components/menubar.ts.

FieldValue
name"{menubarMorfo.name}"
kebab"{menubarMorfo.kebab}"
scope[{menubarMorfo.scope.map((s) => `"${s}"`).join(', ')}]
apg{menubarMorfo.apg}
parts.length{menubarMorfo.parts.length}
events.length{events.length}
Parts
{#each partsList as part (part.kebab)} {/each}
PartMarkerElementRoleArchetypeStatesOptional
{part.kebab} [{part.marker}] <{part.defaultElement}> {part.role ?? '—'} {part.archetype ?? '—'} {part.states.length ? part.states.join(' | ') : '—'} {part.optional ? 'yes' : 'no'}
Events declaration
{#each events as action (action.name)} {@const sem = action.semantic} {@const intentDecl = 'intent' in sem ? sem.intent : undefined} {@const intentStr = typeof intentDecl === 'string' ? intentDecl : intentDecl ? `fromProp:${(intentDecl as { fromProp?: string }).fromProp ?? '?'}` : '—'} {/each}
namefamilyverbsequenceintenttarget
{action.name} {sem.family} {sem.verb ?? '—'} {sem.sequence ?? 'pre'} {intentStr} {action.target}
{/if} {#if tab === 'sema'}

sema · events + perceptual signature

One event — commit-select — fires when an Item is activated. Open/close of individual menus rides on DropdownMenu's events via the re-exported parts.

{#each events as action (action.name)} {@const intentDecl = 'intent' in action.semantic ? action.semantic.intent : undefined} {@const effectiveIntent = typeof intentDecl === 'string' ? intentDecl : undefined} {/each}
NameFamilyVerbSequenceIntentPlay
{action.name} {action.semantic.family} {action.semantic.verb ?? '—'} {action.semantic.sequence ?? 'pre'} {effectiveIntent ?? '—'}
{/if} {#if tab === 'recipe'}

Eidos recipe

Selectors at src/uix/eidos/components/menubar/menubar.css (bar + trigger only). Per-menu Content / Item / Sub / Checkbox / Radio chrome is reused from dropdown-menu.css + the shared menu-indicator.css partial because soma's Menubar re-exports the DropdownMenu parts for those slots.

SelectorSourceWhat it paints
[data-menubar]eidosThe bar surface — flex row, border, bg.
[data-menubar][data-size]eidosSize variant (sm/md/lg) — height + padding + gap + font.
[data-menubar-trigger]morfoIn-bar trigger: transparent bg, hover/open tint, focus ring.
[data-menubar-trigger][data-state='open']morfoOpen menu's trigger lights up with primary tint.
[data-dropdown-menu-content], [data-dropdown-menu-item], …eidosInner panel + items — shared with DropdownMenu.
[data-dropdown-menu-checkbox-item]::before, ::aftereidosCheckbox indicator — outlined box / filled + ✓ via shared menu-indicator partial.
{/if} {#if tab === 'a11y'}

Accessibility

Follows the APG menubar pattern. Bar exposes role="menubar"; each per-menu Content is role="menu". Trigger has aria-haspopup="menu", aria-expanded and aria-controls.

Keyboard
KeyAction
ArrowRight / ArrowLeft on TriggerMove focus to next/previous trigger (wraps if loop=true; RTL inverts).
Enter / Space / ArrowDown on TriggerOpen the menu, focus first item.
ArrowUp / ArrowDown on ItemMove within the menu.
ArrowLeft / ArrowRight on ItemClose current menu, focus + open prev/next menu.
EscapeClose the menu, return focus to its Trigger.
Home / EndJump to first / last item.
LetterTypeahead — focus next item starting with that letter.
Pointer
GestureBehavior
Click triggerOpens its menu (or closes if already open).
Hover sibling trigger while a menu is openSwitches to the hovered menu without an intermediate click.
Click outsideCloses the active menu.
ARIA contract
PartAttributeValue
menubarrole"menubar"
triggeraria-haspopup"menu"
triggeraria-expanded{`{open}`}
triggeraria-controls{``}
triggerdata-state"open" | "closed"
contentrole"menu"
contentaria-labelledby{``}
{/if}