context-menu-common-react
v0.1.0-beta.2
Published
> 前端经常有用到右键菜单扩展交互能力的需求,不同场景下菜单功能不同,且通常需要根据右键目标的不同显示不同的菜单操作,本文就记录了一种通用的右键菜单解决方案。
Downloads
3
Readme
通用右键菜单
前端经常有用到右键菜单扩展交互能力的需求,不同场景下菜单功能不同,且通常需要根据右键目标的不同显示不同的菜单操作,本文就记录了一种通用的右键菜单解决方案。
Get Started
按开发环境的要求,运行和调试项目
运行和调试组件
pnpm run dev
运行测试用例
pnpm run test
按照社区规范和最佳实践,生成构建产物
pnpm run build
继续创建更多项目要素
pnpm run new
用法
简介
demo演示链接: 右键菜单演示demo
- 每个菜单项都可以设置是否禁用、是否隐藏
- 支持子菜单
- 支持显示icon图标、提示语、快捷键等
- 与业务完全解耦,通过简单配置即可定制出功能各异的菜单
样图演示:
用法
1. 最简单的用法
import { ContextMenu, IContextMenuItem } from 'context-menu-common-react';
// 菜单配置数据
const menuList: IContextMenuItem[] = [
{ text: '复制', key: 'copy' },
{ text: '粘贴', key: 'paste', shortcutKeyDesc: `${cmd}+V` },
{
text: '对齐',
key: 'align',
children: [
{ text: '水平垂直居中', key: 'horizontalVerticalAlign' },
{ text: '水平居中', key: 'horizontalAlign' },
],
},
];
export () => {
const containerDomRef = React.useRef();
// 菜单点击触发
const handleMenuTrigger = (menu: IContextMenuItem) => {
console.log(menu); // { text: '复制', key: 'copy' }
// 这里处理触发菜单后的逻辑....
};
return (
<div
ref={containerDomRef}
style={{ position: 'relative' }}>
<ContextMenu
getContainerDom={() => containerDomRef.current}
menuList={menuList}
onTrigger={handleMenuTrigger}
/>
</div>
);
};
2. 根据右键目标动态控制是否禁用和隐藏
import { ContextMenu, IContextMenuItem } from 'context-menu-common-react';
// 菜单配置数据
const menuList: IContextMenuItem[] = [
{
text: '复制',
key: 'copy',
// 动态判断是否禁用
disable: (ctx) => ctx.event.target?.getAttribute('id') === 'button',
},
{
text: '粘贴',
key: 'paste',
// 动态判断是否隐藏
hide: (ctx) => ctx.event.target?.getAttribute('id') === 'text',
},
];
3. 为判断函数注入更多上下文数据
mergeContextFromEvent
函数会在每次唤起右键菜单前运行一次,其返回值会融合进入disable
hide
等菜单属性函数的参数,作为ctx
上下文用来辅助判断
import { ContextMenu, IContextMenuItem } from 'context-menu-common-react';
// 菜单配置数据
const menuList: IContextMenuItem[] = [
{
text: '复制',
key: 'copy',
// 动态判断是否禁用
disable: (ctx) => ctx.event.target?.getAttribute('id') === 'button',
},
];
export () => {
const containerDomRef = React.useRef();
const selectedNodeRef = useRef(null);
// 菜单点击触发
const handleMenuTrigger = (menu: IContextMenuItem) => {
console.log(menu); // { text: '复制', key: 'copy' }
// 这里处理触发菜单后的逻辑....
};
const mergeContext = () => {
const id = selectedNodeRef.current?.getAttribute('id');
return {
id,
selectedNode: selectedNodeRef.current, // 也可以传ref等值
};
};
return (
<div
ref={containerDomRef}
style={{ position: 'relative' }}>
{/* 这里随便渲染一些节点 */}
{[1,2,3].map(e => <div id={e}>node:{e}</div>)}
<ContextMenu
getContainerDom={() => containerDomRef.current}
menuList={menuList}
onTrigger={handleMenuTrigger}
mergeContextFromEvent={mergeContext}
/>
</div>
);
};
4. text、childen等字段都可以设为动态值以满足复杂场景
// 菜单配置数据
const menuList: IContextMenuItem[] = [
{
// 显示动态文本
text: (ctx) => ctx.event.target?.getAttribute('id') === 'button' ? '复制按钮' : '复制',
key: 'copy',
},
{
text: '对齐',
key: 'align',
children: (ctx) => {
const arr =[
{ text: '水平垂直居中', key: 'horizontalVerticalAlign' },
{ text: '水平居中', key: 'horizontalAlign' },
];
// 某个判断逻辑可以控制子节点是否展示等
if (ctx..event.target?.getAttribute('id') === 'button') {
arr = [];
}
return arr;
},
];