Skip to content

上下文菜单

Props ​

名称类型默认值说明
itemsContextMenuOption[]-数据驱动的菜单内容。元素可以是动作条目、分隔线 { type: 'divider' } 或分组 { type: 'section', title, items };条目自带 items 时变成子菜单。省略时使用 content 插槽。
menuWidthnumber | stringundefined菜单面板宽度。数字按像素处理。不设置时面板至少 160px 并随内容伸缩;无论哪种方式都不会超出视口。
size'sm' | 'md' | 'lg''md'条目密度,只改变上下内边距。字体、圆角与面板样式在各档一致。
labelstring'Context menu'菜单的无障碍名称,作为面板的 aria-label 在打开时被朗读。
isDisabledbooleanfalse为真时不拦截右键、不打开菜单,原生浏览器菜单照常出现;已经打开的菜单会被关闭。
triggerAs'div' | 'span''div'触发器渲染成块级 div 还是行内 span。行文中的词需要上下文菜单时用 span。
v-model:isOpenboolean-受控的开关状态。绑定后组件完全跟随这个值;不绑定时组件自己管理状态,右键、菜单键或长按都会打开它。

插槽 ​

名称说明
default触发器区域:在这块内容上点右键就会打开菜单。
content复合模式的菜单内容,用 ContextMenuItem、ContextMenuDivider、ContextMenuGroup、ContextMenuSubMenu 组合。给出 items 时忽略该插槽。

事件与模板引用 ​

名称签名说明
openChange(isOpen: boolean) => void菜单打开或关闭时触发,先于焦点移动。
select(item: ContextMenuItemData, event: MouseEvent) => void数据驱动模式下某个条目被激活时触发,包含被激活的条目和触发它的那次点击。子菜单里的条目同样会冒泡到这里。
update:isOpen(isOpen: boolean) => void由 v-model:isOpen 自动监听,一般不需要手动处理。
elementHTMLElement | null触发器元素,通过模板引用暴露。
open()() => void在触发器左上角打开菜单,用于没有指针事件的调用方。
close()() => void关闭菜单并把焦点交还给打开前的元素。
focus() / blur()() => void聚焦或失焦触发器元素。

子组件 ​

复合模式与数据模式共用同一批行组件,行样式、键盘行为和主题变量完全一致。

组件Props说明
ContextMenuItemicon、label、description、endContent、href、target、rel、isDisabled、hasCloseOnSelect、variant一个动作条目,渲染为 role="menuitem"。带 href 时根元素是真正的 <a>,修改键点击和中键点击保持浏览器自身的语义。插槽:label、icon、description、endContent;激活时触发 click 事件。
ContextMenuDividervariant分组之间的分隔线,渲染为 role="separator",因此不会成为方向键的一站。
ContextMenuGrouptitle带标题的分组,渲染为 role="group" 并用标题作为无障碍名称。插槽:default。
ContextMenuSubMenuicon、label、description、isDisabled、items会展开下一级菜单的条目,行上带 aria-haspopup="menu" 与 aria-expanded。items 用在数据模式,插槽 default 用在复合模式;打开或关闭时触发 openChange。

主题 ​

css
.my-context-menu {
  --astryx-context-menu-background: #ffffff;
  --astryx-context-menu-item-focus-background: #0536590c;
}
  • --astryx-context-menu-background:面板背景。
  • --astryx-context-menu-foreground:面板文字颜色。
  • --astryx-context-menu-shadow:面板投影。
  • --astryx-context-menu-item-foreground:条目文字颜色。
  • --astryx-context-menu-item-focus-background:条目被高亮(悬停或键盘聚焦)时的背景。
  • --astryx-context-menu-item-pressed-background:鼠标按住条目时的背景,仅在支持悬停的设备上出现。
  • --astryx-context-menu-item-description-foreground:条目次要说明文字颜色。
  • --astryx-context-menu-item-error-foreground:variant="destructive" 条目的文字与图标颜色。
  • --astryx-context-menu-section-foreground:分组标题颜色。
  • --astryx-context-menu-block-cap:面板最高高度,默认取 300px 与视口高度中较小者。
  • --astryx-spacing-1、--astryx-radius-container、--astryx-text-label-size:内边距、圆角与字号沿用全局 token。

Neutral 主题自动适配明暗模式。

原生属性 ​

根元素是触发器(默认 <div>,triggerAs="span" 时为 <span>)。

以下内容传入触发器元素:

  • HTML 属性(例如 id、data-*)。
  • aria-* 属性。

class 与 style 则作用于菜单面板:面板才是可主题化的绘制表面(对应 astryx-context-menu 这个 CSS 类),与上游把 className、style 交给菜单面板的做法一致。

触发器本身不携带 role、aria-haspopup 或 aria-expanded:它不是按钮,右键是系统级手势,菜单只在打开时以自己的 label 命名。菜单面板被传送到 document.body,因此不会继承触发器上的属性;面板自身带有 data-size、data-placement、data-overflow、data-width、data-astryx-menu-press 供样式与测试使用。