lowcode-engine/packages/shell/src/components/context-menu.tsx

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,
});
};