JSFiddle - React, Tailwind, and code Playground
by Sam Wray
HTML
<div class=context></div>
CSS
html, body {
margin: 0;
background-color: white;
height: 100%;
}
.context {
width: 100px;
height: 150px;
background-color: red;
position: fixed;
opacity: 0;
transition: opacity 300ms;
}
.context.menu-show {
opacity: 1;
transition: opacity 30ms;
}
JavaScript
let contextDiv = document.querySelector('.context');
document.addEventListener('click', (e) => {
if(e.target !== contextDiv) contextDiv.classList.remove('menu-show');
});
document.addEventListener('contextmenu', (e) => {
e.preventDefault();
contextDiv.classList.remove('menu-show');
contextDiv.classList.add('menu-show');
let x = e.clientX;
let y = e.clientY;
let width = contextDiv.clientWidth;
let height = contextDiv.clientHeight;
if((x + width) > window.innerWidth) {
x = window.innerWidth - width;
}
if((y + height) > window.innerHeight) {
y = window.innerHeight - height;
}
contextDiv.style.left = x + 'px';
contextDiv.style.top = y + 'px';
});
class Menu {
constructor(settings = {}) {
const typeEnum = ['contextmenu', 'menubar'];
let items = [];
let type = isValidType(settings.type) ? settings.type : 'contextmenu';
Object.defineProperty(this, 'items', {
get: () => {
return items;
}
});
Object.defineProperty(this, 'type', {
get: () => {
return type;
},
set: (typeIn) => {
type = isValidType(typeIn) ? typeIn : type;
}
});
this.append = item => {
if(!(item instanceof MenuItem)) {
console.error('appended item must be an instance of MenuItem');
return false;
}
return items.push(item);
};
this.insert = (item, index) => {
if(!(item instanceof MenuItem)) {
console.error('inserted item must be an instance of MenuItem');
return false;
}
items.splice(index, 0, item);
return true;
};
this.remove = item => {
if(!(item instanceof MenuItem)) {
console.error('item to be removed is not an instance of MenuItem');
return false;
}
let index = items.indexOf(item);
if(index < 0) {
console.error('item to be removed was not found in this.items');
return false;
} else {
...