Menu

A menu component based on BrConfigProvider global theme configuration, replicating the shadcn-vue design system. It supports multi-level nesting, shortcut annotations, and keyboard navigation. This component is primarily used to implement context menus (Right-click Context Menu).

Component Features

  • 🎨 Theme Adaptation: Deeply integrated with BrConfigProvider, supporting CSS variables to configure background, foreground, radius, shadow, etc.
  • 📋 Multi-level Nesting: Supports infinite levels of nested submenus.
  • ⌨️ Keyboard Navigation: Full support for Tab, Arrow Up/Down/Left/Right, Enter, Esc key operations.
  • ⌨️ Shortcuts: Supports shortcut key annotations for menu items.
  • 📦 Group Dividers: Supports menu groups and separator lines.
  • 🎯 Collision Detection: Automatically adjusts the pop-up position to prevent overflowing the viewport.

Basic Usage

The simplest context menu containing a few basic operations.

<script setup lang="ts">
import {
  BrMenu,
  BrMenuTrigger,
  BrMenuContent,
  BrMenuItem,
  BrMenuSeparator,
} from '@breezeui/vue';
</script>

<template>
  <BrMenu>
    <BrMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
      Right click here
    </BrMenuTrigger>
    <BrMenuContent class="w-64">
      <BrMenuItem inset>Back</BrMenuItem>
      <BrMenuItem inset disabled>Forward</BrMenuItem>
      <BrMenuItem inset>Reload</BrMenuItem>
      <BrMenuSeparator />
      <BrMenuItem inset>Save As...</BrMenuItem>
      <BrMenuItem inset>Print...</BrMenuItem>
    </BrMenuContent>
  </BrMenu>
</template>

Complex Menu

A complex context menu supporting groups, icons, shortcuts, and multi-level nesting, as shown in the preview.

<script setup lang="ts">
import {
  BrMenu,
  BrMenuTrigger,
  BrMenuContent,
  BrMenuItem,
  BrMenuSeparator,
  BrMenuLabel,
  BrMenuGroup,
  BrMenuSub,
  BrMenuSubTrigger,
  BrMenuSubContent,
} from '@breezeui/vue';
import {
  User,
  CreditCard,
  Settings,
  Keyboard,
  Users,
  UserPlus,
  Mail,
  MessageSquare,
  PlusCircle,
  Plus,
  Github,
  LifeBuoy,
  Cloud,
  LogOut,
} from 'lucide-vue-next';
</script>

<template>
  <BrMenu>
    <BrMenuTrigger
      class="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm font-medium"
    >
      Right-click in this area (Right click here)
    </BrMenuTrigger>
    <BrMenuContent class="w-64">
      <BrMenuItem inset>
        Back
        <template #shortcut>⌘[</template>
      </BrMenuItem>
      <BrMenuItem inset disabled>
        Forward
        <template #shortcut>⌘]</template>
      </BrMenuItem>
      <BrMenuItem inset>
        Reload
        <template #shortcut>⌘R</template>
      </BrMenuItem>
      <BrMenuSeparator />
      <BrMenuItem inset>
        Show Bookmarks Bar
        <template #shortcut>⌘⇧B</template>
      </BrMenuItem>
      <BrMenuItem inset>Show Full URLs</BrMenuItem>
      <BrMenuSeparator />
      <BrMenuLabel inset>People</BrMenuLabel>
      <BrMenuSeparator />
      <BrMenuGroup>
        <BrMenuItem>
          <User class="mr-2 h-4 w-4" />
          <span>Profile</span>
          <template #shortcut>⇧⌘P</template>
        </BrMenuItem>
        <BrMenuItem>
          <CreditCard class="mr-2 h-4 w-4" />
          <span>Billing</span>
          <template #shortcut>⌘B</template>
        </BrMenuItem>
        <BrMenuItem>
          <Settings class="mr-2 h-4 w-4" />
          <span>Settings</span>
          <template #shortcut>⌘S</template>
        </BrMenuItem>
        <BrMenuItem>
          <Keyboard class="mr-2 h-4 w-4" />
          <span>Keyboard shortcuts</span>
          <template #shortcut>⌘K</template>
        </BrMenuItem>
      </BrMenuGroup>
      <BrMenuSeparator />
      <BrMenuGroup>
        <BrMenuItem>
          <Users class="mr-2 h-4 w-4" />
          <span>Team</span>
        </BrMenuItem>
        <BrMenuSub>
          <BrMenuSubTrigger>
            <UserPlus class="mr-2 h-4 w-4" />
            <span>Invite users</span>
          </BrMenuSubTrigger>
          <BrMenuSubContent class="w-48">
            <BrMenuItem>
              <Mail class="mr-2 h-4 w-4" />
              <span>Email</span>
            </BrMenuItem>
            <BrMenuItem>
              <MessageSquare class="mr-2 h-4 w-4" />
              <span>Message</span>
            </BrMenuItem>
            <BrMenuSeparator />
            <BrMenuItem>
              <PlusCircle class="mr-2 h-4 w-4" />
              <span>More...</span>
            </BrMenuItem>
          </BrMenuSubContent>
        </BrMenuSub>
        <BrMenuItem>
          <Plus class="mr-2 h-4 w-4" />
          <span>New Team</span>
          <template #shortcut>⌘+T</template>
        </BrMenuItem>
      </BrMenuGroup>
      <BrMenuSeparator />
      <BrMenuItem>
        <Github class="mr-2 h-4 w-4" />
        <span>GitHub</span>
      </BrMenuItem>
      <BrMenuItem>
        <LifeBuoy class="mr-2 h-4 w-4" />
        <span>Support</span>
      </BrMenuItem>
      <BrMenuItem disabled>
        <Cloud class="mr-2 h-4 w-4" />
        <span>API</span>
      </BrMenuItem>
      <BrMenuSeparator />
      <BrMenuItem>
        <LogOut class="mr-2 h-4 w-4" />
        <span>Log out</span>
        <template #shortcut>⇧⌘Q</template>
      </BrMenuItem>
    </BrMenuContent>
  </BrMenu>
</template>

Nested Submenus

Support creating multi-level submenus using BrMenuSub.

<script setup lang="ts">
import {
  BrMenu,
  BrMenuTrigger,
  BrMenuContent,
  BrMenuItem,
  BrMenuSub,
  BrMenuSubTrigger,
  BrMenuSubContent,
  BrMenuSeparator,
} from '@breezeui/vue';
import { ChevronRight } from 'lucide-vue-next';
</script>

<template>
  <BrMenu>
    <BrMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
      Right click for Submenu
    </BrMenuTrigger>
    <BrMenuContent class="w-64">
      <BrMenuItem>Item 1</BrMenuItem>
      <BrMenuSub>
        <BrMenuSubTrigger>More Options</BrMenuSubTrigger>
        <BrMenuSubContent class="w-48">
          <BrMenuItem>Save</BrMenuItem>
          <BrMenuItem>Save As...</BrMenuItem>
          <BrMenuSeparator />
          <BrMenuSub>
            <BrMenuSubTrigger>Export</BrMenuSubTrigger>
            <BrMenuSubContent>
              <BrMenuItem>PDF</BrMenuItem>
              <BrMenuItem>HTML</BrMenuItem>
            </BrMenuSubContent>
          </BrMenuSub>
        </BrMenuSubContent>
      </BrMenuSub>
    </BrMenuContent>
  </BrMenu>
</template>

Shortcut Annotations

Use the shortcut slot or property to display keyboard shortcuts.

<script setup lang="ts">
import {
  BrMenu,
  BrMenuTrigger,
  BrMenuContent,
  BrMenuItem,
} from '@breezeui/vue';
</script>

<template>
  <BrMenu>
    <BrMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
      Right click for Shortcuts
    </BrMenuTrigger>
    <BrMenuContent class="w-64">
      <BrMenuItem shortcut="⌘X">Cut</BrMenuItem>
      <BrMenuItem shortcut="⌘C">Copy</BrMenuItem>
      <BrMenuItem shortcut="⌘V">Paste</BrMenuItem>
    </BrMenuContent>
  </BrMenu>
</template>

Theming

BrMenu uses CSS variables from BrConfigProvider for style customization.

Configure global styles through the theme property of BrConfigProvider:

<script setup lang="ts">
import {
  BrConfigProvider,
  BrMenu,
  BrMenuTrigger,
  BrMenuContent,
  BrMenuItem,
} from '@breezeui/vue';
</script>

<template>
  <BrConfigProvider
    :theme="{
      popover: 'hsl(222.2 84% 4.9%)',
      popoverForeground: 'hsl(210 40% 98%)',
      border: 'hsl(217.2 32.6% 17.5%)',
      radius: 1, // 1rem
      zMenu: 100,
    }"
  >
    <BrMenu>
      <BrMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
        Right click (Dark Theme Menu)
      </BrMenuTrigger>
      <BrMenuContent class="w-64">
        <BrMenuItem inset>Item 1</BrMenuItem>
        <BrMenuItem inset>Item 2</BrMenuItem>
        <BrMenuItem inset>Item 3</BrMenuItem>
      </BrMenuContent>
    </BrMenu>
  </BrConfigProvider>
</template>

API Reference

BrMenu (Root)

PropertyTypeDefaultDescription
dir'ltr' | 'rtl'-Reading direction

BrMenuTrigger

PropertyTypeDefaultDescription
disabledbooleanfalseWhether the trigger is disabled

BrMenuContent

PropertyTypeDefaultDescription
loopbooleanfalseWhether keyboard navigation should loop
alignOffsetnumber-Alignment offset

BrMenuItem

PropertyTypeDefaultDescription
disabledbooleanfalseWhether disabled
insetbooleanfalseWhether to leave space for left icon
shortcutstring-Shortcut text

BrMenuSub

PropertyTypeDefaultDescription
defaultOpenbooleanfalseDefault open state
openboolean-Controlled open state