1
votes

I am having trouble getting the Material UI Menu to work with React Table@v6.
I want to be able to right-click anywhere in the table (row, td) and show a context menu. This part is working.
But I also want to be able to continuously right-click other locations in the table and always show the context menu the cursor location. This is not working. Currently, you have to click-away to close the menu and then right-click again to re-open the menu.
In the Material UI demo this is working fine:
https://material-ui.com/components/menus/#context-menu

I adopted the example above to work with React Table, but it's not quite working as expected.

My example adoption:
https://codesandbox.io/s/aged-leaf-0nf6b?file=/src/index.js

Any Ideas how to get this to work as in the example?

2

2 Answers

1
votes

This is because you added onContextMenu props to Td, not the table container.

Move onContext Menu to container div, like this:

<div onContextMenu={(e) => {
        e.preventDefault();
        console.log("context menu");
        this.setState({
          mouseX: e.clientX - 2,
          mouseY: e.clientY - 4
        });
      }}>

And it should work.

Enjoy!

0
votes

I ended up creating a popper context menu to replicate all the material-ui behavior for menus.

import React from "react";
import Popper from "@material-ui/core/Popper";
import Typography from "@material-ui/core/Typography";
import MenuList from "@material-ui/core/MenuList";
import MenuItem from "@material-ui/core/MenuItem";
import Paper from "@material-ui/core/Paper";
import { makeStyles } from "@material-ui/core/styles";
import { ClickAwayListener, Fade } from "@material-ui/core";

/* copied from https://github.com/mui-org/material-ui/blob/v4.3.2/packages/material-ui/src/Menu/Menu.js#L21 */
const useMenuStyles = makeStyles({
  /* Styles applied to the `Paper` component. */
  paper: {
    // specZ: The maximum height of a simple menu should be one or more rows less than the view
    // height. This ensures a tapable area outside of the simple menu with which to dismiss
    // the menu.
    maxHeight: "calc(100% - 96px)",
    // Add iOS momentum scrolling.
    WebkitOverflowScrolling: "touch"
  },
  /* Styles applied to the `List` component via `MenuList`. */
  list: {
    // We disable the focus ring for mouse, touch and keyboard users.
    outline: 0
  }
});

export default function FakedReferencePopper() {
  const [open, setOpen] = React.useState(false);
  const [anchorEl, setAnchorEl] = React.useState<null | any>(null);

  const handleClose = () => {
    setOpen(false);
  };

  const handleContextMenu = (e) => {
    e.preventDefault();
    const { clientX, clientY } = e;
    setOpen(true);
    const virtualElement = {
      getBoundingClientRect: () => ({
        width: 0,
        height: 0,
        top: clientY,
        right: clientX,
        bottom: clientY,
        left: clientX
      })
    };
    setAnchorEl(virtualElement);
  };

  const id = open ? "faked-reference-popper" : undefined;
  const menuClasses = useMenuStyles();
  return (
    <div>
      <div onContextMenu={handleContextMenu}>
        <Typography aria-describedby={id}>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ipsum
          purus, bibendum sit amet vulputate eget, porta semper ligula. Donec
          bibendum vulputate erat, ac fringilla mi finibus nec. Donec ac dolor
          sed dolor porttitor blandit vel vel purus. Fusce vel malesuada ligula.
          Nam quis vehicula ante, eu finibus est. Proin ullamcorper fermentum
          orci, quis finibus massa. Nunc lobortis, massa ut rutrum ultrices,
          metus metus finibus ex, sit amet facilisis neque enim sed neque.
          Quisque accumsan metus vel maximus consequat. Suspendisse lacinia
          tellus a libero volutpat maximus. Lorem ipsum dolor sit amet,
          consectetur adipiscing elit. Nullam ipsum purus, bibendum sit amet
          vulputate eget, porta semper ligula. Donec bibendum vulputate erat, ac
          fringilla mi finibus nec. Donec ac dolor sed dolor porttitor blandit
          vel vel purus. Fusce vel malesuada ligula. Nam quis vehicula ante, eu
          finibus est. Proin ullamcorper fermentum orci, quis finibus massa.
          Nunc lobortis, massa ut rutrum ultrices, metus metus finibus ex, sit
          amet facilisis neque enim sed neque. Quisque accumsan metus vel
          maximus consequat. Suspendisse lacinia tellus a libero volutpat
          maximus. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          Nullam ipsum purus, bibendum sit amet vulputate eget, porta semper
          ligula. Donec bibendum vulputate erat, ac fringilla mi finibus nec.
          Donec ac dolor sed dolor porttitor blandit vel vel purus. Fusce vel
          malesuada ligula. Nam quis vehicula ante, eu finibus est. Proin
          ullamcorper fermentum orci, quis finibus massa. Nunc lobortis, massa
          ut rutrum ultrices, metus metus finibus ex, sit amet facilisis neque
          enim sed neque. Quisque accumsan metus vel maximus consequat.
          Suspendisse lacinia tellus a libero volutpat maximus. Lorem ipsum
          dolor sit amet, consectetur adipiscing elit. Nullam ipsum purus,
          bibendum sit amet vulputate eget, porta semper ligula. Donec bibendum
          vulputate erat, ac fringilla mi finibus nec. Donec ac dolor sed dolor
          porttitor blandit vel vel purus. Fusce vel malesuada ligula. Nam quis
          vehicula ante, eu finibus est. Proin ullamcorper fermentum orci, quis
          finibus massa. Nunc lobortis, massa ut rutrum ultrices, metus metus
          finibus ex, sit amet facilisis neque enim sed neque. Quisque accumsan
          metus vel maximus consequat. Suspendisse lacinia tellus a libero
          volutpat maximus. Lorem ipsum dolor sit amet, consectetur adipiscing
          elit. Nullam ipsum purus, bibendum sit amet vulputate eget, porta
          semper ligula. Donec bibendum vulputate erat, ac fringilla mi finibus
          nec. Donec ac dolor sed dolor porttitor blandit vel vel purus. Fusce
          vel malesuada ligula. Nam quis vehicula ante, eu finibus est. Proin
          ullamcorper fermentum orci, quis finibus massa. Nunc lobortis, massa
          ut rutrum ultrices, metus metus finibus ex, sit amet facilisis neque
          enim sed neque. Quisque accumsan metus vel maximus consequat.
          Suspendisse lacinia tellus a libero volutpat maximus. Lorem ipsum
          dolor sit amet, consectetur adipiscing elit. Nullam ipsum purus,
          bibendum sit amet vulputate eget, porta semper ligula. Donec bibendum
          vulputate erat, ac fringilla mi finibus nec. Donec ac dolor sed dolor
          porttitor blandit vel vel purus. Fusce vel malesuada ligula. Nam quis
          vehicula ante, eu finibus est. Proin ullamcorper fermentum orci, quis
          finibus massa. Nunc lobortis, massa ut rutrum ultrices, metus metus
          finibus ex, sit amet facilisis neque enim sed neque. Quisque accumsan
          metus vel maximus consequat. Suspendisse lacinia tellus a libero
          volutpat maximus.
        </Typography>
      </div>

      <Popper
        id={id}
        open={open}
        anchorEl={anchorEl}
        transition
        placement="bottom-start"
      >
        {({ TransitionProps }) => (
          <ClickAwayListener onClickAway={handleClose}>
            <Fade {...TransitionProps}>
              <Paper className={menuClasses.paper}>
                <MenuList className={menuClasses.list} autoFocus>
                  <MenuItem onClick={handleClose}>Profile</MenuItem>
                  <MenuItem onClick={handleClose}>My account</MenuItem>
                  <MenuItem onClick={handleClose}>Logout</MenuItem>
                </MenuList>
              </Paper>
            </Fade>
          </ClickAwayListener>
        )}
      </Popper>
    </div>
  );
}

Here is codesandbox

https://codesandbox.io/s/popper-context-menu-t1u6r