菜单栏 Menubar

基于 Radix Vue Menubar 原语的水平菜单栏组件,支持多级嵌套子菜单、键盘导航、图标、快捷键和 ARIA 无障碍访问。

组件特性

  • 📋 嵌套子菜单:支持无限级嵌套的子菜单,适用于复杂的层级结构。
  • ⌨️ 键盘导航:完整的键盘操作支持,包括方向键、Enter、Escape 和类型补全。
  • 🏷️ 快捷键显示:可为菜单项配置快捷键显示,提升操作体验。
  • 🎨 主题定制:基于 BrConfigProvider 支持全局主题定制,同时支持 TailwindCSS 局部样式覆盖。
  • 无障碍访问:基于 Radix Vue Menubar 构建,提供完整的 ARIA 支持,包括正确的角色、焦点管理和屏幕阅读器播报。

基础用法

最基础的菜单栏,包含顶级菜单和下拉菜单项。

<script setup lang="ts">
import {
  BrMenubar,
  BrMenubarMenu,
  BrMenubarTrigger,
  BrMenubarContent,
  BrMenubarItem,
  BrMenubarSeparator,
} from '@breezeui/vue'
</script>

<template>
  <BrMenubar>
    <BrMenubarMenu>
      <BrMenubarTrigger>File</BrMenubarTrigger>
      <BrMenubarContent>
        <BrMenubarItem>New Tab</BrMenubarItem>
        <BrMenubarItem>New Window</BrMenubarItem>
        <BrMenubarSeparator />
        <BrMenubarItem>Save</BrMenubarItem>
        <BrMenubarItem>Save As...</BrMenubarItem>
        <BrMenubarSeparator />
        <BrMenubarItem>Print</BrMenubarItem>
      </BrMenubarContent>
    </BrMenubarMenu>

    <BrMenubarMenu>
      <BrMenubarTrigger>Edit</BrMenubarTrigger>
      <BrMenubarContent>
        <BrMenubarItem>Undo</BrMenubarItem>
        <BrMenubarItem>Redo</BrMenubarItem>
        <BrMenubarSeparator />
        <BrMenubarItem>Cut</BrMenubarItem>
        <BrMenubarItem>Copy</BrMenubarItem>
        <BrMenubarItem>Paste</BrMenubarItem>
      </BrMenubarContent>
    </BrMenubarMenu>

    <BrMenubarMenu>
      <BrMenubarTrigger>View</BrMenubarTrigger>
      <BrMenubarContent>
        <BrMenubarItem>Zoom In</BrMenubarItem>
        <BrMenubarItem>Zoom Out</BrMenubarItem>
        <BrMenubarItem>Reset Zoom</BrMenubarItem>
        <BrMenubarSeparator />
        <BrMenubarItem>Fullscreen</BrMenubarItem>
      </BrMenubarContent>
    </BrMenubarMenu>
  </BrMenubar>
</template>

嵌套子菜单与快捷键

通过 BrMenubarSub / BrMenubarSubTrigger / BrMenubarSubContent 实现多级嵌套子菜单,通过 shortcut 属性配置快捷键显示。

<script setup lang="ts">
import {
  BrMenubar,
  BrMenubarMenu,
  BrMenubarTrigger,
  BrMenubarContent,
  BrMenubarItem,
  BrMenubarSeparator,
  BrMenubarSub,
  BrMenubarSubTrigger,
  BrMenubarSubContent,
} from '@breezeui/vue'
import { Save, File, Download } from 'lucide-vue-next'
</script>

<template>
  <BrMenubar>
    <BrMenubarMenu>
      <BrMenubarTrigger>File</BrMenubarTrigger>
      <BrMenubarContent>
        <BrMenubarItem>
          <File class="mr-2 h-4 w-4" />
          New File
        </BrMenubarItem>
        <BrMenubarSeparator />
        <BrMenubarSub>
          <BrMenubarSubTrigger>
            <Save class="mr-2 h-4 w-4" />
            Save As
          </BrMenubarSubTrigger>
          <BrMenubarSubContent>
            <BrMenubarItem>PDF</BrMenubarItem>
            <BrMenubarItem>PNG</BrMenubarItem>
            <BrMenubarItem>SVG</BrMenubarItem>
            <BrMenubarSeparator />
            <BrMenubarSub>
              <BrMenubarSubTrigger>More Formats</BrMenubarSubTrigger>
              <BrMenubarSubContent>
                <BrMenubarItem>JSON</BrMenubarItem>
                <BrMenubarItem>XML</BrMenubarItem>
                <BrMenubarItem>CSV</BrMenubarItem>
              </BrMenubarSubContent>
            </BrMenubarSub>
          </BrMenubarSubContent>
        </BrMenubarSub>
        <BrMenubarSeparator />
        <BrMenubarItem>
          <Download class="mr-2 h-4 w-4" />
          Export
        </BrMenubarItem>
      </BrMenubarContent>
    </BrMenubarMenu>

    <BrMenubarMenu>
      <BrMenubarTrigger>Edit</BrMenubarTrigger>
      <BrMenubarContent>
        <BrMenubarItem shortcut="⌘Z">Undo</BrMenubarItem>
        <BrMenubarItem shortcut="⇧⌘Z">Redo</BrMenubarItem>
        <BrMenubarSeparator />
        <BrMenubarItem shortcut="⌘X">Cut</BrMenubarItem>
        <BrMenubarItem shortcut="⌘C">Copy</BrMenubarItem>
        <BrMenubarItem shortcut="⌘V">Paste</BrMenubarItem>
      </BrMenubarContent>
    </BrMenubarMenu>
  </BrMenubar>
</template>

复杂示例

结合了图标、快捷键、分割线、分组、标签、禁用状态、自定义样式的复杂应用场景。

<script setup lang="ts">
import {
  BrMenubar,
  BrMenubarMenu,
  BrMenubarTrigger,
  BrMenubarContent,
  BrMenubarItem,
  BrMenubarSeparator,
  BrMenubarGroup,
  BrMenubarLabel,
} from '@breezeui/vue'
import {
  User,
  Mail,
  Settings,
  Plus,
  FolderOpen,
  Save,
  Scissors,
  Copy,
  Clipboard,
  Search,
} from 'lucide-vue-next'
</script>

<template>
  <BrMenubar>
    <BrMenubarMenu>
      <BrMenubarTrigger>File</BrMenubarTrigger>
      <BrMenubarContent>
        <BrMenubarItem shortcut="⌘N">
          <Plus class="mr-2 h-4 w-4" />
          New File
        </BrMenubarItem>
        <BrMenubarItem shortcut="⌘O">
          <FolderOpen class="mr-2 h-4 w-4" />
          Open
        </BrMenubarItem>
        <BrMenubarSeparator />
        <BrMenubarItem shortcut="⌘S">
          <Save class="mr-2 h-4 w-4" />
          Save
        </BrMenubarItem>
        <BrMenubarSeparator />
        <BrMenubarItem shortcut="⌘Q">
          Quit
        </BrMenubarItem>
      </BrMenubarContent>
    </BrMenubarMenu>

    <BrMenubarMenu>
      <BrMenubarTrigger>Edit</BrMenubarTrigger>
      <BrMenubarContent>
        <BrMenubarItem shortcut="⌘X">
          <Scissors class="mr-2 h-4 w-4" />
          Cut
        </BrMenubarItem>
        <BrMenubarItem shortcut="⌘C">
          <Copy class="mr-2 h-4 w-4" />
          Copy
        </BrMenubarItem>
        <BrMenubarItem shortcut="⌘V">
          <Clipboard class="mr-2 h-4 w-4" />
          Paste
        </BrMenubarItem>
        <BrMenubarSeparator />
        <BrMenubarItem shortcut="⌘F">
          <Search class="mr-2 h-4 w-4" />
          Find
        </BrMenubarItem>
      </BrMenubarContent>
    </BrMenubarMenu>

    <BrMenubarMenu>
      <BrMenubarTrigger>Account</BrMenubarTrigger>
      <BrMenubarContent>
        <BrMenubarGroup>
          <BrMenubarLabel>Profile</BrMenubarLabel>
          <BrMenubarItem>
            <User class="mr-2 h-4 w-4" />
            View Profile
          </BrMenubarItem>
          <BrMenubarItem>Edit Profile</BrMenubarItem>
        </BrMenubarGroup>
        <BrMenubarSeparator />
        <BrMenubarGroup>
          <BrMenubarLabel>Communication</BrMenubarLabel>
          <BrMenubarItem>
            <Mail class="mr-2 h-4 w-4" />
            Inbox
          </BrMenubarItem>
          <BrMenubarItem disabled>
            <Mail class="mr-2 h-4 w-4" />
            Notifications (Coming Soon)
          </BrMenubarItem>
        </BrMenubarGroup>
        <BrMenubarSeparator />
        <BrMenubarItem>
          <Settings class="mr-2 h-4 w-4" />
          Settings
        </BrMenubarItem>
      </BrMenubarContent>
    </BrMenubarMenu>

    <BrMenubarMenu>
      <BrMenubarTrigger disabled>Disabled</BrMenubarTrigger>
      <BrMenubarContent>
        <BrMenubarItem>Should not appear</BrMenubarItem>
      </BrMenubarContent>
    </BrMenubarMenu>
  </BrMenubar>
</template>

主题定制

结合 BrConfigProvider,可以全局覆盖组件默认样式,例如修改圆角、悬浮态颜色、菜单阴影等。同时可以通过 TailwindCSS 局部覆盖样式。

<script setup lang="ts">
import {
  BrMenubar,
  BrMenubarMenu,
  BrMenubarTrigger,
  BrMenubarContent,
  BrMenubarItem,
  BrMenubarSeparator,
  BrConfigProvider,
} from '@breezeui/vue'
</script>

<template>
  <BrConfigProvider
    :theme="{
      light: {
        radius: '1rem',
        primary: '220 90% 56%',
        popover: '0 0% 100%',
        'popover-foreground': '240 10% 3.9%',
      },
      dark: {
        radius: '1rem',
        primary: '220 90% 56%',
        popover: '240 10% 3.9%',
        'popover-foreground': '0 0% 98%',
      }
    }"
  >
    <BrMenubar class="border-primary/20 shadow-md">
      <BrMenubarMenu>
        <BrMenubarTrigger>File</BrMenubarTrigger>
        <BrMenubarContent class="border-primary/20 shadow-xl">
          <BrMenubarItem class="focus:bg-primary focus:text-primary-foreground">New File</BrMenubarItem>
          <BrMenubarItem>Open</BrMenubarItem>
          <BrMenubarSeparator />
          <BrMenubarItem>Save</BrMenubarItem>
        </BrMenubarContent>
      </BrMenubarMenu>

      <BrMenubarMenu>
        <BrMenubarTrigger>Edit</BrMenubarTrigger>
        <BrMenubarContent class="border-primary/20 shadow-xl">
          <BrMenubarItem class="focus:bg-primary focus:text-primary-foreground">Undo</BrMenubarItem>
          <BrMenubarItem>Redo</BrMenubarItem>
        </BrMenubarContent>
      </BrMenubarMenu>
    </BrMenubar>
  </BrConfigProvider>
</template>

API 说明

BrMenubar

属性类型默认值说明
modelValue (v-model)string-当前激活菜单的值
defaultValuestring-默认打开的菜单值
dir'ltr' | 'rtl''ltr'文本阅读方向
loopbooleanfalse是否在键盘导航时循环

BrMenubarMenu

包裹单个顶级菜单(触发器 + 内容),无需额外配置属性。

BrMenubarTrigger

属性类型默认值说明
classany-自定义类名
disabledbooleanfalse是否禁用触发器
asChildbooleanfalse合并属性到子元素
textValuestring-用于类型补全的文本值

BrMenubarContent

属性类型默认值说明
classany-自定义类名
sideOffsetnumber4与触发器的距离
align'start' | 'center' | 'end''start'相对于触发器的对齐方式

BrMenubarItem

属性类型默认值说明
classany-自定义类名
disabledbooleanfalse是否禁用菜单项
insetbooleanfalse是否包含左侧缩进(用于图标对齐)
shortcutstring-快捷键文本(如 "⌘K")
textValuestring-用于类型补全的文本值

事件: @select — 菜单项被选中时触发。

BrMenubarSeparator

属性类型默认值说明
classany-自定义类名

BrMenubarSub

嵌套子菜单的根容器,无需额外配置属性。

BrMenubarSubTrigger

属性类型默认值说明
classany-自定义类名
disabledbooleanfalse是否禁用
insetbooleanfalse是否包含左侧缩进

BrMenubarSubContent

属性类型默认值说明
classany-自定义类名

BrMenubarGroup

属性类型默认值说明
classany-自定义类名

BrMenubarLabel

属性类型默认值说明
classany-自定义类名
insetbooleanfalse是否包含左侧缩进