import { useCallback, useRef, useState } from 'react'; import { NodeMouseHandler, useReactFlow } from 'reactflow'; import styles from './index.less'; export interface INodeContextMenu { id: string; top: number; left: number; right?: number; bottom?: number; [key: string]: unknown; } export function NodeContextMenu({ id, top, left, right, bottom, ...props }: INodeContextMenu) { const { getNode, setNodes, addNodes, setEdges } = useReactFlow(); const duplicateNode = useCallback(() => { const node = getNode(id); const position = { x: node?.position?.x || 0 + 50, y: node?.position?.y || 0 + 50, }; addNodes({ ...(node || {}), data: node?.data, selected: false, dragging: false, id: `${node?.id}-copy`, position, }); }, [id, getNode, addNodes]); const deleteNode = useCallback(() => { setNodes((nodes) => nodes.filter((node) => node.id !== id)); setEdges((edges) => edges.filter((edge) => edge.source !== id)); }, [id, setNodes, setEdges]); return (

node: {id}

); } /* @deprecated */ export const useHandleNodeContextMenu = (sideWidth: number) => { const [menu, setMenu] = useState({} as INodeContextMenu); const ref = useRef(null); const onNodeContextMenu: NodeMouseHandler = useCallback( (event, node) => { // Prevent native context menu from showing event.preventDefault(); // Calculate position of the context menu. We want to make sure it // doesn't get positioned off-screen. const pane = ref.current?.getBoundingClientRect(); // setMenu({ // id: node.id, // top: event.clientY < pane.height - 200 ? event.clientY : 0, // left: event.clientX < pane.width - 200 ? event.clientX : 0, // right: event.clientX >= pane.width - 200 ? pane.width - event.clientX : 0, // bottom: // event.clientY >= pane.height - 200 ? pane.height - event.clientY : 0, // }); setMenu({ id: node.id, top: event.clientY - 144, left: event.clientX - sideWidth, // top: event.clientY < pane.height - 200 ? event.clientY - 72 : 0, // left: event.clientX < pane.width - 200 ? event.clientX : 0, }); }, [sideWidth], ); // Close the context menu if it's open whenever the window is clicked. const onPaneClick = useCallback( () => setMenu({} as INodeContextMenu), [setMenu], ); return { onNodeContextMenu, menu, onPaneClick, ref }; };