Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
72 lines
2.5 KiB
TypeScript
72 lines
2.5 KiB
TypeScript
import * as React from 'react';
|
|
import Menu from '@mui/material/Menu';
|
|
import MenuItem from '@mui/material/MenuItem';
|
|
import Typography from '@mui/material/Typography';
|
|
|
|
export default function ContextMenu() {
|
|
const [contextMenu, setContextMenu] = React.useState<{
|
|
mouseX: number;
|
|
mouseY: number;
|
|
} | null>(null);
|
|
|
|
const handleContextMenu = (event: React.MouseEvent) => {
|
|
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,
|
|
);
|
|
|
|
// Prevent text selection lost after opening the context menu on Safari and Firefox
|
|
const selection = document.getSelection();
|
|
if (selection && selection.rangeCount > 0) {
|
|
const range = selection.getRangeAt(0);
|
|
|
|
setTimeout(() => {
|
|
selection.addRange(range);
|
|
});
|
|
}
|
|
};
|
|
|
|
const handleClose = () => {
|
|
setContextMenu(null);
|
|
};
|
|
|
|
return (
|
|
<div onContextMenu={handleContextMenu} 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>
|
|
<Menu
|
|
open={contextMenu !== null}
|
|
onClose={handleClose}
|
|
anchorReference="anchorPosition"
|
|
anchorPosition={
|
|
contextMenu !== null
|
|
? { top: contextMenu.mouseY, left: contextMenu.mouseX }
|
|
: undefined
|
|
}
|
|
>
|
|
<MenuItem onClick={handleClose}>Copy</MenuItem>
|
|
<MenuItem onClick={handleClose}>Print</MenuItem>
|
|
<MenuItem onClick={handleClose}>Highlight</MenuItem>
|
|
<MenuItem onClick={handleClose}>Email</MenuItem>
|
|
</Menu>
|
|
</div>
|
|
);
|
|
}
|