ContextMenu
右键菜单:在指针位置弹出,与 DropdownMenu 共用同一套菜单逻辑与部件,同样支持勾选 / 单选 / 分组 / 子菜单与键盘导航。
安装
添加组件
pnpm dlx @elyri/cli@latest add context-menu示例
基础用法
在区域内点击右键,菜单在指针位置弹出;选中项显示在下方。
Selected: Nothing yet
import { useState } from 'react';
import { ContextMenu } from './components/elyri/ContextMenu';
export function Example() {
const [selected, setSelected] = useState('Nothing yet');
return (
<div className="demo-ui-row">
<ContextMenu>
<ContextMenu.Trigger className="demo-context-area">Right-click this area</ContextMenu.Trigger>
<ContextMenu.Content>
<ContextMenu.Item onSelect={() => setSelected('Duplicate')}>Duplicate</ContextMenu.Item>
<ContextMenu.Item onSelect={() => setSelected('Rename')}>Rename</ContextMenu.Item>
<ContextMenu.Separator />
<ContextMenu.Item onSelect={() => setSelected('Delete')} danger>
Delete
</ContextMenu.Item>
</ContextMenu.Content>
</ContextMenu>
<span className="demo-ui-label">Selected: {selected}</span>
</div>
);
}勾选、单选与子菜单
与下拉菜单一致的能力:可勾选、可单选、可逐级展开子菜单。
Sort: name · Compact: on
import { useState } from 'react';
import { ContextMenu } from './components/elyri/ContextMenu';
export function Example() {
const [sort, setSort] = useState('name');
const [compact, setCompact] = useState(true);
return (
<div className="demo-ui-row">
<ContextMenu>
<ContextMenu.Trigger className="demo-context-area">Right-click for options</ContextMenu.Trigger>
<ContextMenu.Content>
<ContextMenu.Label>Sort by</ContextMenu.Label>
<ContextMenu.RadioGroup value={sort} onValueChange={setSort}>
<ContextMenu.RadioItem value="name">Name</ContextMenu.RadioItem>
<ContextMenu.RadioItem value="date">Date modified</ContextMenu.RadioItem>
</ContextMenu.RadioGroup>
<ContextMenu.Separator />
<ContextMenu.CheckboxItem checked={compact} onCheckedChange={setCompact}>
Compact density
</ContextMenu.CheckboxItem>
<ContextMenu.Sub>
<ContextMenu.SubTrigger>Open with</ContextMenu.SubTrigger>
<ContextMenu.SubContent>
<ContextMenu.Item>Editor</ContextMenu.Item>
<ContextMenu.Item>Terminal</ContextMenu.Item>
</ContextMenu.SubContent>
</ContextMenu.Sub>
</ContextMenu.Content>
</ContextMenu>
<span className="demo-ui-label">Sort: {sort} · Compact: {compact ? 'on' : 'off'}</span>
</div>
);
}属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
open | boolean | — | 受控开关 |
defaultOpen | boolean | false | 非受控初始开关 |
onOpenChange | (open: boolean) => void | — | 开关变化回调 |
placement | 'top' | 'bottom' | 'left' | 'right' | 'bottom' | 相对指针的期望方向:top / bottom / left / right |
align | 'start' | 'center' | 'end' | 'start' | 交叉轴对齐:start / center / end |
offset | number | 2 | 与指针的间距 |
ContextMenu.Trigger | HTMLAttributes | — | 右键触发区域;asChild 时合并到唯一子元素 |
ContextMenu.Content | HTMLAttributes | — | 菜单容器,role="menu" |
ContextMenu.Item | ButtonHTMLAttributes | — | 菜单项,role="menuitem",选中后默认关闭 |
onSelect | (event) => void | — | 选中回调;调用 event.preventDefault() 可让菜单保持打开 |
ContextMenu.CheckboxItem | ButtonHTMLAttributes | — | 可勾选菜单项,切换后保持打开 |
ContextMenu.RadioGroup | HTMLAttributes | — | 单选项分组 |
ContextMenu.RadioItem | ButtonHTMLAttributes | — | 单选菜单项,选中后保持打开 |
ContextMenu.Sub | object | — | 子菜单根组件 |
ContextMenu.SubTrigger | ButtonHTMLAttributes | — | 子菜单触发项,悬停或方向键展开 |
ContextMenu.SubContent | HTMLAttributes | — | 子菜单容器,默认在右侧展开 |
ContextMenu.Group | HTMLAttributes | — | 分组容器 |
ContextMenu.Label | HTMLAttributes | — | 分组标题 |
ContextMenu.Separator | HTMLAttributes | — | 分隔线 |
ContextMenu.Shortcut | HTMLAttributes | — | 右侧快捷键提示 |