63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
import { createContextMenu, parseContextMenuAsReactNode, parseContextMenuProperties } from '@alilc/lowcode-utils';
|
|
import { engineConfig } from '@alilc/lowcode-editor-core';
|
|
import { IPublicModelPluginContext, IPublicTypeContextMenuAction } from '@alilc/lowcode-types';
|
|
import React from 'react';
|
|
|
|
export function ContextMenu({ children, menus, pluginContext }: {
|
|
menus: IPublicTypeContextMenuAction[];
|
|
children: React.ReactElement[] | React.ReactElement;
|
|
pluginContext: IPublicModelPluginContext;
|
|
}): React.ReactElement<any, string | React.JSXElementConstructor<any>> {
|
|
if (!engineConfig.get('enableContextMenu')) {
|
|
return (
|
|
<>{ children }</>
|
|
);
|
|
}
|
|
|
|
const handleContextMenu = (event: React.MouseEvent) => {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
let destroyFn: Function | undefined;
|
|
const destroy = () => {
|
|
destroyFn?.();
|
|
};
|
|
const children: React.ReactNode[] = parseContextMenuAsReactNode(parseContextMenuProperties(menus, {
|
|
destroy,
|
|
pluginContext,
|
|
}), { pluginContext });
|
|
|
|
if (!children?.length) {
|
|
return;
|
|
}
|
|
|
|
destroyFn = createContextMenu(children, { event });
|
|
};
|
|
|
|
// 克隆 children 并添加 onContextMenu 事件处理器
|
|
const childrenWithContextMenu = React.Children.map(children, (child) =>
|
|
React.cloneElement(
|
|
child,
|
|
{ onContextMenu: handleContextMenu },
|
|
));
|
|
|
|
return (
|
|
<>{childrenWithContextMenu}</>
|
|
);
|
|
}
|
|
|
|
ContextMenu.create = (pluginContext: IPublicModelPluginContext, menus: IPublicTypeContextMenuAction[], event: MouseEvent) => {
|
|
const children: React.ReactNode[] = parseContextMenuAsReactNode(parseContextMenuProperties(menus, {
|
|
pluginContext,
|
|
}), {
|
|
pluginContext,
|
|
});
|
|
|
|
if (!children?.length) {
|
|
return;
|
|
}
|
|
|
|
return createContextMenu(children, {
|
|
event,
|
|
});
|
|
}; |