projectstorm / react-diagrams

a super simple, no-nonsense diagramming library written in react that just works
https://projectstorm.cloud/react-diagrams
MIT License
8.51k stars 1.17k forks source link

Show custom context menu when right-clicking at a port #844

Closed drnguyenn closed 3 years ago

drnguyenn commented 3 years ago

Hi. I was implementing a custom context menu when right-clicking the port. I'm trying to achieve this by using React's onContextMenu on my port. I'm using MaterialUI's Menu component, too. The problem is every time I right-click on the port, I see a new link from that port is also created and I don't know how to get rid of that.

My code is as below

import { memo, useCallback, useState } from 'react';
import { PortWidget } from '@projectstorm/react-diagrams';

import { Menu, MenuItem } from '@material-ui/core';

import {
  CustomNodeStyles,
  PortStyles
} from './custom-node.styles';

const INITIAL_MENU = {
  mouseX: null,
  mouseY: null
};

const CustomNodeWidget = ({ engine, node }) => {
  const [portActionMenu, setPortActionMenu] = useState(INITIAL_MENU);
  const { mouseX, mouseY } = portActionMenu;

  const ports = node.getPorts();

  const handleSpeedDialOpen = useCallback(() => {
    setSpeedDialOpen(true);
  }, []);

  const handleSpeedDialClose = useCallback(() => {
    setSpeedDialOpen(false);
  }, []);

  const handlePortActionMenuOpen = useCallback(event => {
    event.preventDefault();

    setPortActionMenu({
      mouseX: event.clientX - 2,
      mouseY: event.clientY - 4
    });
  }, []);

  const handlePortActionMenuClose = useCallback(() => {
    setPortActionMenu(INITIAL_MENU);
  }, []);

  const PortActionMenu = memo(() => (
    <Menu
      open={Boolean(mouseY)}
      onClose={handlePortActionMenuClose}
      anchorReference='anchorPosition'
      anchorPosition={
        mouseY && mouseX ? { top: mouseY, left: mouseX } : undefined
      }
    >
      <MenuItem
        onClick={() => {
          handlePortActionMenuClose();
        }}
      >
        Switch port
      </MenuItem>
      <MenuItem
        onClick={() => {
          handlePortActionMenuClose();
        }}
      >
        Remove
      </MenuItem>
    </Menu>
  ));

  return (
    <CustomNodeStyles>
      {Object.keys(ports).map(key => {
        const port = ports[key];
        return (
          <PortWidget key={port.options.id} engine={engine} port={port}>
            <PortStyles
              onContextMenu={handlePortActionMenuOpen}
            />
          </PortWidget>
        );
      })}

      <PortActionMenu />
    </CustomNodeStyles>
  );
};

ezgif com-gif-maker

Any solution ? Thank you.