JSFiddle - React, Tailwind, and code Playground

HTML

<ul id="nested">
<li id="folder1" class="CMenu"><span>New Folder1</span></li>
<li id="folder2" class="CMenu"><span>New Folder2</span></li>
<li id="folder3" class="CMenu"><span>New Folder3</span></li>
<li id="folder4" class="CMenu"><span>New Folder4</span></li>
<li id="folder5" class="CMenu"><span>New Folder5</span></li>
<li id="folder6" class="CMenu"><span>New Folder6</span></li>
</ul>

CSS

#contextmenu  { border:1px solid #999; padding:0; background:#eee; width:200px; list-style-type:none; display:none; }
#contextmenu .separator  { border-top:1px solid #999; }
#contextmenu li  { margin:0; padding:0;height:30px }
#contextmenu li a { display:block; padding:5px 10px 5px 35px; width:155px; font-size:12px; text-decoration:none; font-family:tahoma,arial,sans-serif; color:#000; background-position:8px 8px; background-repeat:no-repeat; }
#contextmenu li a:hover  { background-color:#ddd; }
#contextmenu li a.disabled { color:#ccc; font-style:italic; }
#contextmenu li a.disabled:hover { background-color:#eee; }
/*#contextmenu li a.edit  { background-image:url(tree/folder_tree_edit.png); }
#contextmenu li a.new  { background-image:url(tree/folder_tree_add.png); }
#contextmenu li a.copy  { background-image:url(copy.png); }
#contextmenu li a.paste  { background-image:url(paste.png); }
#contextmenu li a.delete  { background-image:url(tree/folder_tree_delete.png); }
#contextmenu li a.quit  { background-image:url(quit.png); }*/




/* begin MenuSubItem */
#contextmenu ul{border:1px solid #999;padding:0;visibility: hidden;width:200px; list-style-type:none;z-index: 10;left: 0;top: 0;background:#eee;}
#contextmenu li:hover>ul{visibility: visible;top: 100%;}
#contextmenu li ol, li ul{margin:-29px 0 0 200px;padding:0;}
#contextmenu ul ul a{margin-left: auto;}
/*#contextmenu ul li a.single-upload  { background-image:url(tree/single_upload.png); }*/

JavaScript

var ContextMenu = new Class({

    //implements
    Implements: [Options, Events],

    //options
    options: {
        actions: {},
        menu: 'contextmenu',
        labels: [],
        stopEvent: true,
        targets: 'body',
        trigger: 'contextmenu',
        offsets: {
            x: 0,
            y: 0
        },
        onShow: function() {},
        onHide: function() {},
        onClick: function() {},
        fadeSpeed: 200
    },

    //initialization
    initialize: function(options) {
        //set options
        this.setOptions(options);

        //option diffs menu
        this.menu = this.parseNodes(this.options.labels, this.options.menu).inject(document.body);

        this.targets = $$(this.options.targets);

        //fx
        this.fx = new Fx.Tween(this.menu, {
            property: 'opacity',
            duration: this.options.fadeSpeed
        });

        //hide and begin the listener
        this.hide().startListener();

        //hide the menu
        this.menu.setStyles({
            position: 'absolute',
            top: '-900000px',
            display: 'block'
        });
    },

    //get things started
    startListener: function() { /* all elemnts */
        this.targets.each(function(el) { /* show the menu */
            el.addEvent(this.options.trigger, function(e) {
                //enabled?
                if (!this.options.disabled) {
                    //prevent default, if told to
                    if (this.options.stopEvent) {
                        e.stop();
                    }
                    //record this as the trigger
                    this.options.element = document.id(el);
                    //position the menu
                    this.menu.setStyles({
                        top: (e.page.y + this.options.offsets.y),
                        left: (e.page.x + this.options.offsets.x),
                        position: 'absolute',
                        'z-index': '2000'
                   ...