skip to Main Content

I’d to add a id or some attribute to the MenuItem, something like <MenuItem id="foo" onClick={handleClose}>Copy Ctrl+C</MenuItem> so that I can acess it from event.target in the context menu event handler in my TreeView.

Currently the code look like this:

export default function FileSystemNavigator() {
  const [contextMenu, setContextMenu] = React.useState<{
    mouseX: number;
    mouseY: number;
  } | null>(null);

  const handleContextMenu = (event: React.MouseEvent) => {
    // get the HTML element with the id, e.g., id="foo" in the attributes of event.target
    event.preventDefault();
    setContextMenu(
      contextMenu === null
        ? {
            mouseX: event.clientX + 2,
            mouseY: event.clientY - 6
          }
        : // repeated contextmenu when it is already open closes it with Chrome 84 on Ubuntu
          // Other native context menus might behave different.
          // With this behavior we prevent contextmenu from the backdrop to re-locale existing context menus.
          null
    );
  };

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

  return (
    <div onContextMenu={handleContextMenu} style={{ cursor: "context-menu" }}>
      <TreeView
        aria-label="file system navigator"
        defaultCollapseIcon={<ExpandMoreIcon />}
        defaultExpandIcon={<ChevronRightIcon />}
        sx={{ height: 240, flexGrow: 1, maxWidth: 400, overflowY: "auto" }}
      >
        <TreeItem nodeId="1" label="Applications">
          <TreeItem nodeId="2" label="Calendar" />
        </TreeItem>
        <TreeItem nodeId="5" label="Documents">
          <TreeItem nodeId="10" label="OSS" />
          <TreeItem nodeId="6" label="MUI">
            <TreeItem nodeId="8" label="index.js" />
          </TreeItem>
        </TreeItem>
      </TreeView>
      <Menu
        open={contextMenu !== null}
        onClose={handleClose}
        anchorReference="anchorPosition"
        anchorPosition={
          contextMenu !== null
            ? { top: contextMenu.mouseY, left: contextMenu.mouseX }
            : undefined
        }
      >
        <MenuItem onClick={handleClose}>Copy Ctrl+C</MenuItem>
        <MenuItem onClick={handleClose}>Delete</MenuItem>
        <MenuItem onClick={handleClose}>Move</MenuItem>
        <MenuItem onClick={handleClose}>Email</MenuItem>
      </Menu>
    </div>
  );
}

Here's a live code example

2

Answers


  1. There are a few options to achieve this:

    • by passing a different function to each of your MenuItem:
    const handleCopy = () => {
        // Do whatever you need
        handleClose();
    };
    
    const handleDelete = () => {
        // Do whatever you need
        handleClose();
    };
    
    <MenuItem onClick={handleCopy}>Copy Ctrl+C</MenuItem>
    <MenuItem onClick={handleDelete}>Delete</MenuItem>
    
    • you can use data- attributes:
    const handleClose = (event) => {
        const { action } = event.target.dataset
        // Here can be a switch/case statement to iterate the action
        setContextMenu(null);
    };
    
    <MenuItem data-action="copy" onClick={handleClose}>
        Copy Ctrl+C
    </MenuItem>
    
    • just use the inline function:
    <MenuItem onClick={() => handleClose({action: 'copy'})}>Copy Ctrl+C</MenuItem>
    
    Login or Signup to reply.
  2. One way you can have a span tag and pass an id to it inside your MenuItem like this :

    <MenuItem onClick={handleClose}>
              <span id="Copy Ctrl+C">Copy Ctrl+C </span>
            </MenuItem>
            <MenuItem onClick={handleClose}>
              <span id="Delete">Delete </span>
            </MenuItem>
            <MenuItem onClick={handleClose}>
              <span id="Move">Move </span>
            </MenuItem>
            <MenuItem onClick={handleClose}>
              <span id="Email">Email </span>
            </MenuItem>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search