#ContextMenu 上下文菜单
基于 BrConfigProvider 实现全局主题配置,支持右键唤起、嵌套子菜单、自适应定位的企业级上下文菜单组件,可无缝集成 BrTable、BrTree、BrCard 等组件,支持自定义快捷键唤起和全键盘导航。
#组件特性
- 🖱️ 原生右键劫持:完美替代浏览器默认右键菜单,提供一致的 UI 体验。
- 📋 嵌套子菜单:支持无限级嵌套的子菜单,适用于复杂的层级结构。
- ⌨️ 键盘无障碍:完全支持键盘上下左右导航,支持 Esc 关闭,符合 W3C 标准。
- 🎯 自适应定位:基于浮层引擎自动计算位置,防止菜单在屏幕边缘被遮挡。
- 🎨 主题定制:基于
BrConfigProvider支持全局主题定制,同时支持 TailwindCSS 局部样式覆盖。
#基础用法
在区域内右键点击,展示基础的操作菜单,包含普通项和禁用项,以及快捷键标注。
<script setup lang="ts">
import {
BrContextMenu,
BrContextMenuTrigger,
BrContextMenuContent,
BrContextMenuItem,
BrContextMenuSeparator
} from '@breezeui/vue'
</script>
<template>
<BrContextMenu>
<BrContextMenuTrigger class="flex h-[150px] w-full items-center justify-center rounded-md border border-dashed text-sm">
Right-click here (Right click here)
</BrContextMenuTrigger>
<BrContextMenuContent class="w-64">
<BrContextMenuItem shortcut="⌘[">
Back (Back)
</BrContextMenuItem>
<BrContextMenuItem shortcut="⌘]" disabled>
Forward (Forward)
</BrContextMenuItem>
<BrContextMenuItem shortcut="⌘R">
Reload (Reload)
</BrContextMenuItem>
<BrContextMenuSeparator />
<BrContextMenuItem shortcut="⌘S">
Save As... (Save As...)
</BrContextMenuItem>
<BrContextMenuItem shortcut="⌘P">
Print... (Print...)
</BrContextMenuItem>
</BrContextMenuContent>
</BrContextMenu>
</template>#嵌套子菜单
支持多层级嵌套的子菜单,且能自动处理边缘溢出问题。
<script setup lang="ts">
import {
BrContextMenu,
BrContextMenuTrigger,
BrContextMenuContent,
BrContextMenuItem,
BrContextMenuSeparator,
BrContextMenuSub,
BrContextMenuSubTrigger,
BrContextMenuSubContent
} from '@breezeui/vue'
</script>
<template>
<BrContextMenu>
<BrContextMenuTrigger class="flex h-[150px] w-full items-center justify-center rounded-md border border-dashed text-sm">
Right-click to open nested menu (Right click to open nested menu)
</BrContextMenuTrigger>
<BrContextMenuContent class="w-64">
<BrContextMenuItem>
New File (New File)
</BrContextMenuItem>
<BrContextMenuItem>
New Folder (New Folder)
</BrContextMenuItem>
<BrContextMenuSeparator />
<BrContextMenuSub>
<BrContextMenuSubTrigger>
Open With (Open With)
</BrContextMenuSubTrigger>
<BrContextMenuSubContent class="w-48">
<BrContextMenuItem>Breeze Code</BrContextMenuItem>
<BrContextMenuItem>System Default (System Default)</BrContextMenuItem>
<BrContextMenuSeparator />
<BrContextMenuItem>Select Other App... (Choose other app...)</BrContextMenuItem>
</BrContextMenuSubContent>
</BrContextMenuSub>
<BrContextMenuSeparator />
<BrContextMenuItem shortcut="⌘⌫" class="text-destructive focus:text-destructive-foreground">
Delete (Delete)
</BrContextMenuItem>
</BrContextMenuContent>
</BrContextMenu>
</template>#与卡片集成
在卡片或复杂区域绑定右键操作。可以使用 as-child 将触发器属性绑定到自定义组件上。
<script setup lang="ts">
import {
BrContextMenu,
BrContextMenuTrigger,
BrContextMenuContent,
BrContextMenuItem,
BrContextMenuSeparator,
BrCard,
BrCardHeader,
BrCardTitle,
BrCardDescription,
BrCardContent
} from '@breezeui/vue'
</script>
<template>
<BrContextMenu>
<BrContextMenuTrigger as-child>
<BrCard class="w-[350px] cursor-context-menu transition-shadow hover:shadow-md">
<BrCardHeader>
<BrCardTitle>Breeze UI Project (Breeze UI Project)</BrCardTitle>
<BrCardDescription>Right-click the card to view actions (Right click card to see actions)</BrCardDescription>
</BrCardHeader>
<BrCardContent>
The current project contains various enterprise-level UI Components。
(This project contains various enterprise-level UI components.)
</BrCardContent>
</BrCard>
</BrContextMenuTrigger>
<BrContextMenuContent class="w-48">
<BrContextMenuItem>Pin project (Pin Project)</BrContextMenuItem>
<BrContextMenuItem>Share link... (Share Link...)</BrContextMenuItem>
<BrContextMenuSeparator />
<BrContextMenuItem>Rename (Rename)</BrContextMenuItem>
<BrContextMenuItem class="text-destructive focus:text-destructive">Delete project (Delete Project)</BrContextMenuItem>
</BrContextMenuContent>
</BrContextMenu>
</template>#表格行右键操作
演示如何将右键菜单与数据表格无缝结合,在每一行绑定右键事件。
<script setup lang="ts">
import { ref } from 'vue'
import {
BrContextMenu,
BrContextMenuTrigger,
BrContextMenuContent,
BrContextMenuItem,
BrContextMenuSeparator
} from '@breezeui/vue'
const tableData = ref([
{ id: 1, name: 'Breeze-Core', status: 'Active' },
{ id: 2, name: 'Breeze-Vue', status: 'Developing' },
])
const handleAction = (action: string, row: any) => {
console.log(`Execute action: ${action} on project: ${row.name}`)
}
</script>
<template>
<div class="rounded-md border">
<table class="w-full text-sm">
<thead>
<tr class="border-b bg-muted/50 text-left">
<th class="p-4 font-medium">Project Name (Project Name)</th>
<th class="p-4 font-medium">Status (Status)</th>
</tr>
</thead>
<tbody>
<template v-for="row in tableData" :key="row.id">
<BrContextMenu>
<!-- as-child Allows merging trigger attributes into native tr elements -->
<BrContextMenuTrigger as-child>
<tr class="border-b transition-colors hover:bg-muted/50 cursor-context-menu">
<td class="p-4">{{ row.name }}</td>
<td class="p-4">{{ row.status }}</td>
</tr>
</BrContextMenuTrigger>
<BrContextMenuContent>
<BrContextMenuItem @select="handleAction('View', row)">View Details (View Details)</BrContextMenuItem>
<BrContextMenuItem @select="handleAction('Edit', row)">Edit (Edit)</BrContextMenuItem>
<BrContextMenuSeparator />
<BrContextMenuItem class="text-destructive focus:text-destructive" @select="handleAction('Delete', row)">Delete (Delete)</BrContextMenuItem>
</BrContextMenuContent>
</BrContextMenu>
</template>
</tbody>
</table>
</div>
</template>#主题定制
BrContextMenu 的样式完全接入了 BrConfigProvider 的系统。您可以通过配置 CSS 变量来全局或局部调整其外观。
<script setup lang="ts">
import {
BrContextMenu,
BrContextMenuTrigger,
BrContextMenuContent,
BrContextMenuItem,
BrConfigProvider
} from '@breezeui/vue'
</script>
<template>
<BrConfigProvider
:theme="{
radius: '0.25rem',
popover: '#f8fafc',
popoverForeground: '#0f172a',
}"
>
<BrContextMenu>
<BrContextMenuTrigger class="flex h-[150px] w-full items-center justify-center rounded-md border border-dashed text-sm">
Right-click to view custom theme (Right click to view custom theme)
</BrContextMenuTrigger>
<BrContextMenuContent class="w-64">
<BrContextMenuItem>Custom Theme Item 1 (Custom Theme Item 1)</BrContextMenuItem>
<BrContextMenuItem>Custom Theme Item 2 (Custom Theme Item 2)</BrContextMenuItem>
<BrContextMenuItem class="focus:bg-blue-500 focus:text-white">
Local Override Style Item (Local override style item)
</BrContextMenuItem>
</BrContextMenuContent>
</BrContextMenu>
</BrConfigProvider>
</template>#API 说明
#BrContextMenu
包裹整个右键菜单的根组件,负责管理右键状态和事件。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
dir | 'ltr' | 'rtl' | 'ltr' | 菜单阅读方向 |
modal | boolean | true | 是否为模态模式(打开时阻止外部交互) |
| 事件 | 类型 | 说明 |
|---|---|---|
@update:open | (open: boolean) => void | 菜单打开/关闭时触发 |
#BrContextMenuTrigger
触发菜单的区域。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
asChild | boolean | false | 是否将触发器属性传递给子元素,用于替换默认包裹的 span/div |
class | any | - | 自定义类名 |
#BrContextMenuContent
右键唤起后的菜单内容容器。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
alignOffset | number | 0 | 对齐偏移量 |
avoidCollisions | boolean | true | 是否自动避开屏幕边缘 |
collisionBoundary | Element | Element[] | [] | 碰撞检测边界 |
collisionPadding | number | Record | 0 | 碰撞检测内边距 |
loop | boolean | false | 键盘导航是否循环 |
class | any | - | 容器类名 |
#BrContextMenuItem
单个菜单项。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
disabled | boolean | false | 是否禁用 |
textValue | string | - | 用于键盘导航的首字母匹配文本 |
shortcut | string | - | 快捷键展示文本(如 ⌘P) |
inset | boolean | false | 是否内进展示(通常用于对齐带图标的项) |
class | any | - | 菜单项类名 |
| 事件 | 类型 | 说明 |
|---|---|---|
@select | (event: Event) => void | 选中时触发,可调用 event.preventDefault() 阻止默认关闭行为 |
#BrContextMenuSub & BrContextMenuSubTrigger & BrContextMenuSubContent
用于构建嵌套的子菜单,其属性基本等同于 Root 对应的容器组件,增加了对 hover 触发展开/收起的支持。
#BrContextMenuEmpty & BrContextMenuLoading
用于处理数据为空和异步加载状态的预设占位组件。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
text | string | 'No items' / 'Loading...' | 提示文本 |