JSFiddle - React, Tailwind, and code Playground
by Renan Gomes
HTML
<nav id='context-menu' class='context-menu'>
<a href='#'>Novo</a>
<a href='#'>Salvar</a>
<span class='separator'></span>
<a href='#'>Copiar</a>
<a href='#'>Colar</a>
<span class='separator'></span>
<a href='#'>Fechar</a>
</nav>
<p id='log'></p>
CSS
* { box-sizing: border-box }
.context-menu.active {
display: flex;
position: absolute;
}
.context-menu {
border: 1px solid #ccc;
box-shadow: 0 4px 2px rgba(0, 0, 0, .2);
display: none;
flex-flow: column wrap;
padding: 6px 4px;
width: 200px;
height: 190px;
}
.context-menu .separator,
.context-menu a {
display: inline-block
}
.context-menu .separator {
border: 1px solid #ccc;
margin: 4px 0;
width: 100%
}
.context-menu a {
color: #333;
margin-left: 15px;
padding: 5px;
text-decoration: none
}
JavaScript
document.addEventListener('contextmenu', handleContextMenu, false);
var menu = document.querySelector('.context-menu'),
menuItems = menu.querySelectorAll('a');
var size = {width: 0, height: 0};
/**
* Função para exibir o menu de contexto no ponto x/y
* que o usuário clicar com o mouse.
*/
function handleContextMenu(event){
event.preventDefault();
menu.classList.add('active');
updateWindowSize();
var needsWrapWidth = event.clientX > size.width - 200,
needsWrapHeight = event.clientY > size.height - 200;
if(!needsWrapWidth)
menu.style.left = event.clientX + 'px';
else
menu.style.right = '0px';
if(!needsWrapHeight)
menu.style.top = event.clientY + 'px';
else
menu.style.bottom = '0'
}
for(var i = 0; i < menuItems.length; i++){
menuItems[i].addEventListener('click', handleContextMenuClick, false);
}
function handleContextMenuClick(event){
var selection = event.target.innerHTML;
document.getElementById('log').innerHTML = 'Você clicou na opção "' + selection + '".';
menu.classList.remove('active');
}
function updateWindowSize(){
size.width = window.innerWidth || document.documentElement.clientWidth ||
document.body.clientWidth || document.body.offsetWidth;
size.height = window.innerHeight || document.documentElement.clientHeight ||
document.body.clientHeight || document.body.offsetHeight;
}