Нашли решение! Хитрость заключается в том, чтобы закрыть контекстное меню при событии мыши вниз родительского элемента div, а также установить в меню exit transitionSuration, равный 0. Например, посмотрите этот файл demo.tsx (также на Codesandox ):
import React from "react";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
import Typography from "@material-ui/core/Typography";
const initialState = {
mouseX: null,
mouseY: null
};
export default function ContextMenu() {
const [state, setState] = React.useState<{
mouseX: null | number;
mouseY: null | number;
}>(initialState);
const handleClick = (
divName: string,
event: React.MouseEvent<HTMLDivElement>
) => {
console.log(divName);
event.preventDefault();
setState({
mouseX: event.clientX - 2,
mouseY: event.clientY - 4
});
};
const handleClose = () => {
setState(initialState);
};
return (
<div
onContextMenu={e => e.preventDefault()}
onMouseDownCapture={e => {
if (e.button === 2) handleClose();
}}
>
<Menu
keepMounted
open={state.mouseY !== null}
onClose={handleClose}
anchorReference="anchorPosition"
anchorPosition={
state.mouseY !== null && state.mouseX !== null
? { top: state.mouseY, left: state.mouseX }
: undefined
}
transitionDuration={0}
>
<MenuItem onClick={handleClose}>Copy</MenuItem>
<MenuItem onClick={handleClose}>Print</MenuItem>
<MenuItem onClick={handleClose}>Highlight</MenuItem>
<MenuItem onClick={handleClose}>Email</MenuItem>
</Menu>
<div
onContextMenu={e => handleClick("div1", e)}
style={{ cursor: "context-menu" }}
>
<Typography>
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>
-----
<div
onContextMenu={e => handleClick("div2", e)}
style={{ cursor: "context-menu" }}
>
<Typography>
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>
</div>
);
}