Components / Navigation

Menubar

A persistent desktop-style command bar with managed top-level and nested menu focus.

Preview

Install

Run in your project
Package manager
npx @getweini/cli@latest add menubar

Use cases

Editor commands

Expose File, Edit, and View commands in a persistent desktop-style bar.

Document actions

Group document operations without filling the main toolbar.

Usage example

Vue
<Menubar>
  <MenubarMenu value="file">
    <MenubarTrigger>File</MenubarTrigger>
    <MenubarContent aria-label="File">
      <MenubarItem id="new" label="New">New <template #suffix><Kbd size="sm">Ctrl N</Kbd></template></MenubarItem>
    </MenubarContent>
  </MenubarMenu>
  <MenubarMenu value="edit">
    <MenubarTrigger>Edit</MenubarTrigger>
    <MenubarContent aria-label="Edit">
      <MenubarItem id="undo" label="Undo">Undo <template #suffix><Kbd size="sm">Ctrl Z</Kbd></template></MenubarItem>
    </MenubarContent>
  </MenubarMenu>
</Menubar>

More examples

File and Edit menus

Handle selected item IDs in application code.

File and Edit menus
<script setup lang="ts">
import Menubar from './components/ui/menubar/Menubar.vue'
import MenubarContent from './components/ui/menubar/MenubarContent.vue'
import MenubarItem from './components/ui/menubar/MenubarItem.vue'
import MenubarMenu from './components/ui/menubar/MenubarMenu.vue'
import MenubarTrigger from './components/ui/menubar/MenubarTrigger.vue'
function run(action: { id: string }) { console.log(action.id) }
</script>

<template>
  <Menubar><MenubarMenu value="file" @select="run"><MenubarTrigger>File</MenubarTrigger><MenubarContent aria-label="File commands">
    <MenubarItem id="new" label="New document">New document</MenubarItem>
    <MenubarItem id="open" label="Open document">Open document</MenubarItem>
  </MenubarContent></MenubarMenu>
  <MenubarMenu value="edit" @select="run"><MenubarTrigger>Edit</MenubarTrigger><MenubarContent aria-label="Edit commands">
    <MenubarItem id="undo" label="Undo">Undo</MenubarItem>
  </MenubarContent></MenubarMenu></Menubar>
</template>

View options

A single menu also works when a compact application needs one command group.

View options
<script setup lang="ts">
import Menubar from './components/ui/menubar/Menubar.vue'
import MenubarContent from './components/ui/menubar/MenubarContent.vue'
import MenubarItem from './components/ui/menubar/MenubarItem.vue'
import MenubarMenu from './components/ui/menubar/MenubarMenu.vue'
import MenubarTrigger from './components/ui/menubar/MenubarTrigger.vue'
function select(action: { id: string }) { console.log(action.id) }
</script>

<template>
  <Menubar><MenubarMenu value="view" @select="select"><MenubarTrigger>View</MenubarTrigger><MenubarContent aria-label="View commands">
    <MenubarItem id="zoom-in" label="Zoom in">Zoom in</MenubarItem>
    <MenubarItem id="zoom-out" label="Zoom out">Zoom out</MenubarItem>
  </MenubarContent></MenubarMenu></Menubar>
</template>

Key API

The most useful props, models, slots, events, and methods for this component.

Key API for Menubar
NameTypeDefault or requirement
v-model / defaultValuestringundefined
dirltr | rtlltr
MenubarMenu valuestringrequired
MenubarTrigger data-stateopen | closedclosed

The open menu stays visibly active. Click or use Left and Right to switch top-level menus; hover alone does not switch them. Add #prefix and #suffix content to menu items. Typeahead finds items, and Escape closes the menu.

Implementation notes

  • Menu items emit intent; run commands and enforce permissions in the application.
  • Use stable IDs and labels so keyboard typeahead and selection remain predictable.

Accessibility and localization

  • Top-level menus use managed keyboard focus; name each content region for its command group.
Weini UIDesign system · Vue component library · Free and public