Right Click Menu using React JS

There are few things to take care about with popup menus:

  1. it should be rendered away from its parent and siblings - preferably in an overlay which is the last child of document.body
  2. special logic should take care that it's always displayed on screen and never cropped by screen edges
  3. if there is a hierarchy involved, child popups should be aligned to items from previous popup (opener).

I created a library which you can use to accomplish all of these:

http://dkozar.github.io/react-data-menu/


I was alsolooking for a solution while working with Material UI, So what you want to do is first disable the default behaviour of a browser on right click and then add the menu which you want, here's the working code:

import React from 'react';
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import DraftsIcon from '@material-ui/icons/Drafts';
import SendIcon from '@material-ui/icons/Send';

const StyledMenu = withStyles({
  paper: {
    border: '1px solid #d3d4d5',
  },
})((props) => (
  <Menu
    elevation={0}
    getContentAnchorEl={null}
    anchorOrigin={{
      vertical: 'bottom',
      horizontal: 'center',
    }}
    transformOrigin={{
      vertical: 'top',
      horizontal: 'center',
    }}
    {...props}
  />
));

const StyledMenuItem = withStyles((theme) => ({
  root: {
    '&:focus': {
      backgroundColor: theme.palette.primary.main,
      '& .MuiListItemIcon-root, & .MuiListItemText-primary': {
        color: theme.palette.common.white,
      },
    },
  },
}))(MenuItem);

export default function CustomizedMenus() {
  const [anchorEl, setAnchorEl] = React.useState(null);

  const handleClick = (event) => {
    event.preventDefault();
    setAnchorEl(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  return (
    <div>
      <Button
        aria-controls="customized-menu"
        aria-haspopup="true"
        variant="contained"
        color="primary"
        onContextMenu={handleClick}
      >
        Open Menu
      </Button>
      <StyledMenu
        id="customized-menu"
        anchorEl={anchorEl}
        keepMounted
        open={Boolean(anchorEl)}
        onClose={handleClose}
      >
        <StyledMenuItem>
          <ListItemIcon>
            <SendIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText primary="Sent mail" />
        </StyledMenuItem>
        <StyledMenuItem>
          <ListItemIcon>
            <DraftsIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText primary="Drafts" />
        </StyledMenuItem>
        <StyledMenuItem>
          <ListItemIcon>
            <InboxIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText primary="Inbox" />
        </StyledMenuItem>
      </StyledMenu>
    </div>
  );
}

and the sandbox project


UPDATE:

Figured it out - here is what you can do

var addMenu;

componentWillMount: function() {
    addMenu = new nw.Menu();
    addMenu.append(new nw.MenuItem({
        label: 'doSomething',
        click: function() {
            // doSomething
        }
    }));
},

contextMenu: function(e) {
    e.preventDefault();
    addMenu.popup(e.clientX, e.clientY);
},

render: function(){
    return <button onClick={this.handleClick} onContextMenu={this.contextMenu}>SomethingUseful</button>
}

In render you can pass a function to onContextMenu for when a right click occurs for this react component.