JSFiddle - React, Tailwind, and code Playground
Updated container example with external parseCSS working.
by nilloc
HTML
<script src="https://paperclipped.com/js/libraries/parseCSS.js"></script>
<!-- <script src="https://raw.githubusercontent.com/mdevils/node-css-selector-parser/master/lib/css-selector-parser.js" type="text/javascipt"></script> -->
<modkit-container id="editor" row="1" col="1">
<modkit-container id="toolbar" row="1" col="n">
toolbar
</modkit-container>
<modkit-container id="drawer" row="n" col="1">
<modkit-style>
default{
top:0;
left:0;
width:200px;
bottom:20px; /* could be switched to footer top */
}
</modkit-style>
drawer
</modkit-container>
<modkit-container id="handle">
<modkit-style>
default{
top:$('#toolbar').bottom();
left:$(':prev-sibling()').right();
right:0;
bottom:20px;
}
</modkit-style>
</modkit-container>
<modkit-container id="stage">
<modkit-style>
default{
top:$('#toolbar').bottom();
left:$('#handle').right();
right:0;
bottom:20px;
}
</modkit-style>
stage
<anchor class="top" contenteditable data-setting="toolbar">toolbar</anchor>
<anchor class="left" contenteditable data-setting="handle">handle</anchor>
<anchor class="right" contenteditable data-setting="0">0</anchor>
<anchor class="bottom" contenteditable data-setting="0">0</anchor>
</modkit-container>
</modkit-container>
SCSS
*{
box-sizing:border-box;
}
modkit-container{
display:block;
position:relative;
user-select:none;
}
modkit-style{
display:none;
}
#editor, #drawer, #handle, #stage{
position:absolute;
}
#editor{
background:darkgray;
top:0;
left:0;
bottom:0;
right:0;
$toolbar-height:60px;
$drawer-width:200px;
$handle-width:4px;
#toolbar{
background:lightgray;
height:$toolbar-height;
padding:10px;
box-shadow:0 2px 3px rgba(0,0,0,0.3);
z-index:900;
}
#drawer{
background:white;
top:$toolbar-height;
left:0;
width:$drawer-width;
bottom:0;
}
#handle{
background:#777;
top:$toolbar-height;
left:$drawer-width;
width:$handle-width;
bottom:0;
cursor:col-resize;
z-index:1000;
}
#stage{
background:#eee;
top:$toolbar-height;
left:$drawer-width+$handle-width;
right:0;
bottom:0;
}
anchor{
display:block;
position:absolute;
height:20px;
width:60px;
background:white;
border:1px solid darkgray;
border-radius:4px;
text-align:center;
outline: none;
overflow:hidden;
&.top, &.bottom{left:calc(50% - 30px);}
&.left, &.right{top:calc(50% - 30px);}
&.top, &.left, &.right{border-radius:0 0 4px 4px;}
&.top{top:0;}
&.bottom{bottom:0; border-radius:4px 4px 0 0;}
&.left{ left:-20px; transform:rotate(-90deg); }
&.right{ right:-20px; transform:rotate(90deg); }
}
}
JavaScript
// Add better position methods to $
$.prototype.top = function (margin = false){
return this.offset().top - ((margin === true)? this.css('margin-top'):0);
}
$.prototype.left = function (margin = false){
console.log("left:", this.offset().left)
return this.offset().left - ((margin === true)? this.css('margin-left'):0);
}
$.prototype.right = function (margin = false){
return this.offset().left + this.outerWidth(margin);
}
$.prototype.bottom = function (margin = false){
return this.offset().top + this.outerHeight(margin);
}
$('anchor').on("input", function(){
console.log($(this).parent(), "changed:", this.textContent);
var $parent = $(this).parent();
if(this.textContent.indexOf('%') > -1){
$parent.css(this.className, this.textContent); // make %
this.dataset.setting = this.textContent;
}else if(this.textContent == parseFloat(this.textContent)){
$parent.css(this.className, this.textContent+"px"); // make abs
this.dataset.setting = this.textContent;
}else{
// search for id and attach based on edge
var $target = $('modkit-container#'+this.textContent);
if($target.length > 0 ){
console.log("found:", $target);
this.dataset.setting = this.textContent;
/* switch(this.className){
case 'top':
console.log($target.offset().top+$target.outerHeight());
$parent.css('top', $target.offset().top+$target.outerHeight()+"px");
break;
case 'left':
$parent.css('left', $target.offset().left+$target.outerWidth()+"px");
break;
case 'right':
$parent.css('right', $target.offset().left+"px");
break;
case 'bottom':
$parent.css('top', $target.offset().top+"px");
break;
}*/
// now class based instead of conditional!
$parent.css(this.className, $target[this.className]()+"px");
}
}
});
$('#handle').on('mousedown', function(){
$('#editor').on('mousemove.handle', function(evt){
//console.log("dragging mouse",...