Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add a custom attribute to the generated React Menu item?

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

like image 772
Jack Avatar asked Oct 14 '25 18:10

Jack


2 Answers

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>
like image 68
monim Avatar answered Oct 17 '25 23:10

monim


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>
like image 38
Entity Avatar answered Oct 18 '25 00:10

Entity



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!