JSFiddle - React, Tailwind, and code Playground

by bgrins

HTML

<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/ui-lightness/jquery-ui.css">
<div id='app'>

<div id='faux' class='faux'>

    <div data-width='100' class='slice v'><b></b></div>
    <div data-flex='1' class='slice v'><b></b></div>
    
    
    <div data-height='100' class='slice h'><b></b></div>
    <div data-flex='1' class='slice h'><b></b></div>
    
    <div class='rail v'><span>Click to add a column</span><em>Drag to remove</em></div>
    <div class='rail h'><span>Click to add a row</span><em>Drag to remove</em></div>
    
</div>

<div id='actual'>

</div>
    
</div>

CSS

#app { position:relative; }
#faux, #actual { width: 400px; height: 400px;  position:absolute; top: 50px; left:50px; border: 2px solid; padding:0; margin:0; }

#faux{  background: rgba(0, 0, 0, .4);  z-index:2; }
#actual{  background: red; z-index:1; }


.rail { position:absolute;  
    background-color: rgba(0, 0, 0, .1); color:white;
    
-webkit-transition: background-color .1s linear;
    color:transparent; padding:3px; text-align:center; 
}

.faux .rail:hover { background-color: rgba(0, 0, 0, .8); color:white; }

body.dragging .rail { background-color: rgba(0, 0, 0, .8); }
body.dragging .faux .rail:hover { background-color: rgba(0, 0, 0, .8); }
body.dragging .rail span { display:none; }
body.dragging  em { display:inline; color:white; }

.rail em { display:none; }
.rail.v span { display:block; display:none; position:absolute;width:150px;  top:150px;
-webkit-transform: rotate(270deg);
-webkit-transform-origin: 0 0;
}
.rail.v { width: 20px; top:-5px; bottom:-5px; left:-46px; 
    }
.rail.h { height: 20px; left:-5px; right:-5px; top:-46px; }




.slice { position:absolute; background:rgba(0, 0, 0, .6); }
.slice.active { background: rgba(255, 0, 0, 1); }


.slice b { position:absolute; width: 10px; height:10px; top:-5px; left:-5px; background: #222; border-radius: 5px; }
.slice.active b { background: orange; }

.slice.v { top:-10px; bottom: -10px; width: 2px; }
.slice.v b { width: 40px; left: -20px;}
.slice.h { right:-10px; left: -10px; height: 2px; }
.slice.h b { height: 40px; top: -20px; }

#actual {
    display:-webkit-box;
    -webkit-box-orient: vertical;
}

JavaScript

$(function() {
   
   
    
    
    $(".rail.h").mousedown(function(e) {
        var newHandle = $(getHSlice(e.layerX));
        $("#faux").append(newHandle);
        
        initDraggable();
        newHandle.find("b").trigger(e);
    });
    
    $(".rail.v").mousedown(function(e) {
        var newHandle = $(getVSlice(e.layerY));
        $("#faux").append(newHandle);
        
        initDraggable();
        newHandle.find("b").trigger(e);
    });
    
    
    $(document).bind("mousedown", function() {
        $(".slice.active").removeClass("active");
    });
    
    $(".faux").bind("mousedown", function(e) {
       
        e.stopPropagation(); 
    });
    initDraggable();
    buildActual()
});

function getHSlice(coord) {
    return "<div style='left: "+coord+"px;' data-flex='1' class='slice v'><b></b></div>"
}
function getVSlice(coord) {
    return "<div style='top: "+coord+"px;' data-flex='1' class='slice h'><b></b></div>"
}

function initDraggable() {
    
    $(".slice.h").draggable({
        handle: "b",
        axis: 'y',
        containment: 'parent',
        drag: drag,
        start: dragStart,
        stop: dragStop
    });
    $(".slice.v").draggable({
        handle: "b",
        axis: 'x',
        containment: 'parent',
        drag: drag,
        start: dragStart,
        stop: dragStop
    });
    
    
    $(".slice b").unbind("mousedown").mousedown(function(e) {
        $(".slice").removeClass("active");
        $(this).closest(".slice").addClass("active");
    });
        
}

function drag() {
    console.log(this, arguments);
}
function dragStart() {
    $("body").addClass("dragging");
}
function dragStop() {
    $("body").removeClass("dragging");
}

function buildActual() {
    
    var sliceVert = $(".slice.v");
    var sliceHoriz = $(".slice.h");
    
    var horiz = sliceHoriz.map(function() {
        return {
            top: this.offsetTop,
            height: $(this).attr("data-height"),
            flex:...