右键菜单

基于 Portal 的可组合右键菜单组件。支持嵌套子菜单、标签、分隔线和内置颜色选择器。点击外部、滚动、窗口缩放或按下 Escape 时自动关闭。

安装

npm install @dayflow/ui-context-menu
pnpm add @dayflow/ui-context-menu
yarn add @dayflow/ui-context-menu
bun add @dayflow/ui-context-menu

如果你的项目已经使用 Tailwind CSS,请导入仅包含组件样式的入口:

@import '@dayflow/ui-context-menu/dist/styles.components.css';
@import 'tailwindcss';

如果你的项目不使用 Tailwind CSS,则继续导入完整样式:

import {
  ContextMenu,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuLabel,
  ContextMenuSub,
  ContextMenuSubTrigger,
  ContextMenuSubContent,
  ContextMenuColorPicker,
} from '@dayflow/ui-context-menu';
import '@dayflow/ui-context-menu/dist/styles.css';

基础用法

contextmenu 事件中捕获鼠标位置,将其传给 ContextMenu

import { useState } from 'react';
import {
  ContextMenu,
  ContextMenuItem,
  ContextMenuSeparator,
} from '@dayflow/ui-context-menu';

function MyComponent() {
  const [menu, setMenu] = useState<{ x: number; y: number } | null>(null);

  const handleContextMenu = (e: React.MouseEvent) => {
    e.preventDefault();
    setMenu({ x: e.clientX, y: e.clientY });
  };

  return (
    <div onContextMenu={handleContextMenu}>
      在此处右键单击
      {menu && (
        <ContextMenu x={menu.x} y={menu.y} onClose={() => setMenu(null)}>
          <ContextMenuItem onClick={() => console.log('编辑')}>
            编辑
          </ContextMenuItem>
          <ContextMenuItem onClick={() => console.log('复制')}>
            复制
          </ContextMenuItem>
          <ContextMenuSeparator />
          <ContextMenuItem onClick={() => console.log('删除')} danger>
            删除
          </ContextMenuItem>
        </ContextMenu>
      )}
    </div>
  );
}

标签与图标

<ContextMenu x={x} y={y} onClose={onClose}>
  <ContextMenuLabel>操作</ContextMenuLabel>
  <ContextMenuItem icon={<PencilIcon />} onClick={() => onEdit()}>
    编辑事件
  </ContextMenuItem>
  <ContextMenuItem icon={<CopyIcon />} onClick={() => onDuplicate()}>
    复制
  </ContextMenuItem>
  <ContextMenuSeparator />
  <ContextMenuItem icon={<TrashIcon />} onClick={() => onDelete()} danger>
    删除
  </ContextMenuItem>
</ContextMenu>

嵌套子菜单

使用 ContextMenuSub 包裹菜单项以创建悬停触发的子菜单,子菜单会自动调整位置以避免超出视口。

<ContextMenu x={x} y={y} onClose={onClose}>
  <ContextMenuItem onClick={() => onEdit()}>编辑</ContextMenuItem>
  <ContextMenuSub>
    <ContextMenuSubTrigger>移动到</ContextMenuSubTrigger>
    <ContextMenuSubContent>
      <ContextMenuItem onClick={() => onMove('work')}>工作</ContextMenuItem>
      <ContextMenuItem onClick={() => onMove('personal')}>个人</ContextMenuItem>
    </ContextMenuSubContent>
  </ContextMenuSub>
  <ContextMenuSeparator />
  <ContextMenuItem danger onClick={() => onDelete()}>
    删除
  </ContextMenuItem>
</ContextMenu>

颜色选择器

ContextMenuColorPicker 渲染一排预设色块,并可选地提供"自定义颜色"操作。

<ContextMenu x={x} y={y} onClose={onClose}>
  <ContextMenuLabel>日历颜色</ContextMenuLabel>
  <ContextMenuColorPicker
    selectedColor={currentColor}
    onSelect={color => {
      updateCalendarColor(color);
      onClose();
    }}
    onCustomColor={() => openColorDialog()}
    customColorLabel='自定义颜色...'
  />
</ContextMenu>

禁用菜单项

<ContextMenuItem onClick={() => onPaste()} disabled={!hasClipboard}>
  粘贴
</ContextMenuItem>

API 参考

ContextMenu

属性类型说明
xnumber水平位置(如 event.clientX
ynumber垂直位置(如 event.clientY
onClose() => void菜单需要关闭时调用
childrenComponentChildren菜单内容
classNamestring菜单容器的额外 CSS 类名

ContextMenuItem

属性类型默认值说明
onClick() => void点击处理函数
childrenComponentChildren菜单项文本
iconComponentChildren显示在文本左侧的图标
dangerbooleanfalse以危险红色样式渲染
disabledbooleanfalse禁用交互

ContextMenuColorPicker

属性类型默认值说明
selectedColorstring当前选中颜色(十六进制)
onSelect(color: string) => void点击色块时调用
onCustomColor() => void点击自定义颜色行时调用
customColorLabelstring"Custom Color"自定义颜色操作的文案

其他导出

组件说明
ContextMenuSeparator水平分隔线
ContextMenuLabel非交互式分组标题
ContextMenuSub管理子菜单展开状态的包裹组件
ContextMenuSubTrigger悬停时展开子菜单的触发行
ContextMenuSubContent浮动子菜单面板

On this page