JSFiddle - React, Tailwind, and code Playground

by Adam Boduch

HTML

<div class="ui-widget">
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
</div>

CSS

body {
    font-size: 0.8em;
}

.ui-editable-menu {
    display: inline-block;
}

JavaScript

(function( $ ) {
    $.widget( "app.editable", {
        
        _create: function() {
                      
            this._on({
                contextmenu: "onContextMenu",
                blur: "onBlur"
            });
            
        },
        
        _destroy: function() {
            
        },
        
        _destroyMenu: function() {
            if ( this.menu && this.menu.is( ":ui-menu" ) ) {
                this.menu.menu( "destroy" )
                    .remove();           
            } else {
                this.menu.remove();    
            }
        },
                
        onContextMenu: function( e ) {
            
            e.preventDefault();
            
            this.menu = $( "<a/>" )
                .appendTo( "body" )
                .attr( "href", "#" )
                .text( "Edit" )
                .wrap( "<li/>" )
                .parent()
                .wrap( "<ul/>" )
                .parent()
                .addClass( "ui-editable-menu" )
                .position( { my: "left top", of: e } )
                .menu();
            
            this._on( this.menu, {
                menublur: "onMenuBlur",
                menufocus: "onMenuFocus",
                menuselect: "onMenuSelect"
            });
            
            setTimeout( $.proxy( function() {
                if ( !this.focused ) {
                    this._destroyMenu();    
                }
            }, this ), 1000 );
            
        },
        
        onBlur: function( e ) {
            console.log(this.element.attr("contenteditable"));    
        },
        
        onMenuBlur: function( e ) {
            this._destroyMenu();           
        },
        
        onMenuFocus: function( e ) {
            this.focused = true;    
        },
        
        onMenuSelect: function( e ) {
            this.element.attr( "contenteditable", true ).get(0).focus();
        }
        
    });
})( jQuery );

$(function() {
        
...