Context Menu
SoDialog Component
Context Menu
可键盘访问的上下文菜单,支持选择器绑定、ARIA 状态、typeahead 和 close-first 弹窗联动。
最短可运行示例
ts
import { bindContextMenu } from 'sodialog'
import 'sodialog/style.css'
bindContextMenu({
target: '#file-row',
items: [
{ id: 'rename', label: '重命名' },
{ id: 'delete', label: '删除' },
],
})Demo / Playground
Context Menu Basic Demo
Open in New TabSource Code
Context Menu to Dialog Demo
Open in New TabSource Code
基础绑定
ts
import { bindContextMenu } from 'sodialog'
bindContextMenu({
target: '#cm-basic-zone',
width: 260,
height: 'auto',
items: [
{ id: 'copy', label: '复制' },
{ id: 'rename', label: '重命名' },
],
onAction: ({ itemId }) => {
console.log(itemId)
},
})target支持选择器、单元素和元素集合。- 菜单项可绑定
id、label和onClick。 width和height支持数字(按 px)或 CSS 尺寸字符串,并继续受minWidth、maxHeight安全限制。
关闭策略与键盘交互
ts
import { bindContextMenu } from 'sodialog'
bindContextMenu({
target: '#cm-policy-zone',
closeOnEsc: true,
closeOnScroll: true,
closeOnWindowBlur: true,
typeaheadEnabled: true,
typeaheadResetMs: 700,
items: [
{ id: 'download', label: '下载 Download' },
{ id: 'rename', label: '重命名 Rename' },
{ id: 'delete', label: '删除 Delete' },
],
onFocusItem: ({ itemId }) => {
console.log('focus', itemId)
},
onTypeahead: ({ query, matched, itemId }) => {
console.log('typeahead', query, matched, itemId)
},
onClose: (reason) => {
console.log('close reason', reason)
},
})- 键盘支持
ArrowUp、ArrowDown、Home、End、Tab。 - 支持字母快速定位,对中英混合标签可匹配并轮转。
菜单触发弹窗(close-first)
ts
import { bindContextMenu, openDialogFromContextMenu } from 'sodialog'
let handle: ReturnType<typeof bindContextMenu> | null = null
handle = bindContextMenu({
target: '#cm-dialog-zone',
items: [
{
id: 'open-dialog',
label: '打开确认弹窗',
onClick: () => {
if (!handle) return
openDialogFromContextMenu(handle, {
title: '来自 ContextMenu',
content: '<p>已执行 close-first-open-next。</p>',
})
},
},
],
})该模式可避免菜单与弹窗同时存在导致的焦点与层级冲突。
可访问性
Context Menu 支持方向键、Home/End、Enter/Space、Escape 与 typeahead。菜单项需要稳定 id 与可读 label,禁用项不能只靠颜色区别状态。