JSFiddle - React, Tailwind, and code Playground

by sachid

HTML

<ul class='custom-menu'>
  <li data-action = "first">First thing</li>
  <li data-action = "second">Second thing</li>
  <li data-action = "third"> Load file<input id="sss" type="file" class="file-select" name="input-select[]"
                   accept="application/json"/></li>
</ul>
<svg id="canvas" width="500" height="500" style="border:1px solid black">
  <rect width="100" height="50" x="10" y="10" id="hhh"></rect>
</svg>

CSS

.custom-menu {
    display: none;
    z-index: 1000;
    position: absolute;
    overflow: hidden;
    border: 1px solid #CCC;
    white-space: nowrap;
    font-family: sans-serif;
    background: #FFF;
    color: #333;
}

.custom-menu li {
    padding: 8px 12px;
    cursor: pointer;
}

.custom-menu input{
  display:none;
}

.custom-menu li:hover {
    background-color: #DEF;
}

JavaScript

// Trigger action when the contexmenu is about to be shown
$("#hhh").bind("contextmenu", function (event) {
    
    // Avoid the real one
    event.preventDefault();
    
    // Show contextmenu
    $(".custom-menu").finish().toggle(100).
    
    // In the right position (the mouse)
    css({
        top: event.pageY + "px",
        left: event.pageX + "px"
    });
});


// If the document is clicked somewhere
$(document).bind("mousedown", function (e) {
    
    // If the clicked element is not the menu
    if (!$(e.target).parents(".custom-menu").length > 0) {
        
        // Hide it
        $(".custom-menu").hide(100);
    }
});


// If the menu element is clicked
$(".custom-menu li").click(function(){
    // This is the triggered action name
    switch($(this).attr("data-action")) {
        
        // A case for each action. Your actions here
        case "first": alert("first"); break;
        case "second": alert("second"); break;
        case "third": $("input").trigger("click"); break;
    }
  
    // Hide it AFTER the action was triggered
    $(".custom-menu").hide(100);
  });