Search code examples
reactjschakra-ui

Trigger Chakra UI menu only on right click


Is it possible to modify the example from the docs to make the menu trigger on right click (context menu) instead of a normal click ?

<Menu>
  <MenuButton as={Button} rightIcon={<ChevronDownIcon />}>
    Actions
  </MenuButton>
  <MenuList>
    <MenuItem>Download</MenuItem>
    <MenuItem>Create a Copy</MenuItem>
    <MenuItem>Mark as Draft</MenuItem>
    <MenuItem>Delete</MenuItem>
    <MenuItem>Attend a Workshop</MenuItem>
  </MenuList>
</Menu>

Solution

  • If you're looking for how to make Menu work as a Context Menu, here's how to achieve that:

    function ContextMenu() {
      const [isOpen, setIsOpen] = useState(false);
    
      return (
        <Menu
          isOpen={isOpen}
          onClose={() => {
            setIsOpen(false);
          }}
        >
          <Button
            onContextMenu={(e) => {
              e.preventDefault();
              setIsOpen(true);
    
              const menu = document.querySelector("[role=menu]");
    
              const popper = menu.parentElement;
    
              const x = e.clientX;
              const y = e.clientY;
    
              Object.assign(popper.style, {
                top: `${y}px`,
                left: `${x}px`
              });
            }}
          >
            Right click to open
          </Button>
          <MenuList
            onAnimationEnd={(e) => {
              const menu = document.querySelector("[role=menu]");
              menu.focus();
            }}
          >
            <MenuItem>Download</MenuItem>
            <MenuItem>Create a Copy</MenuItem>
            <MenuItem>Mark as Draft</MenuItem>
            <MenuItem>Delete</MenuItem>
            <MenuItem>Attend a Workshop</MenuItem>
          </MenuList>
        </Menu>
      );
    }
    

    Essentially, you need to first remove the MenuButton that binds to the default click event and then add in a new button to trigger the context menu.