JSFiddle - React, Tailwind, and code Playground
Container Example from before, now with WebComponents
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">
<modkit-style>
default{
top:0;
left:0;
right:0;
height:60px;
background-image: linear-gradient(-180deg, #C1C1C1 0%, #AFAFAF 100%);
box-shadow: 0 1px 3px 0 rgba(0,0,0,0.25);
}
.light{
background-image: linear-gradient(-180deg, #F3F3F3 0%, #E6E6E6 98%);
}
.dark{
background-image: linear-gradient(-180deg, #666666 0%, #4C4C4C 100%);
}
</modkit-style>
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.bottom">toolbar.bottom</anchor>
<anchor class="left" contenteditable data-setting="handle.right">handle.right</anchor>
<anchor class="right" contenteditable data-setting="0">0</anchor>
<anchor class="bottom" contenteditable data-setting="0">0</anchor>
<anchor class="width" contenteditable data-setting="auto">auto</anchor>
<anchor class="height" contenteditable...
SCSS
*{
box-sizing:border-box;
}
modkit-container{
display:block;
position:relative;
user-select:none;
overflow:hidden;
}
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:auto;//$drawer-width+$handle-width;
right:0;
bottom:0;
}
anchor{
display:block;
position:absolute;
height:20px;
width:100px;
background:white;
border:1px solid darkgray;
border-radius:4px;
text-align:center;
outline: none;
overflow:hidden;
&.top, &.bottom, &.height, &.width{left:calc(50% - 50px);}
&.left, &.right{top:calc(50% - 20px);}
&.top, &.left, &.right{border-radius:0 0 4px 4px;}
&.top{top:0;}
&.bottom{bottom:0; border-radius:4px 4px 0 0;}
&.left{ left:-40px; transform:rotate(-90deg); }
&.right{ right:-40px; transform:rotate(90deg); }
&.width{top:calc(50% - 50px);
}
&.height{top:calc(50%);
}
}
#height-label, #width-label{position:absolute; left:calc(50% - 50px);}
#height-label{top:calc(50% - 20px);}
#width-label{top:calc(50% - 70px)}
}
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){
//console.log('alinging to right edge:', this.outerWidth(margin))
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.length);
var $parent = $(this).parent();
var setting = this.textContent;
if(this.textContent.length < 1){
setting = '0';
}
//(this.textContent.length<1)? this.textContent : "0";
if(setting.indexOf('%') > -1){
$parent.css(this.className, setting); // make %
this.dataset.setting = setting;
// TODO: Could split on . when there is a word first and use a different target for position (width or height depending on anchor)
}else if(setting == parseFloat(setting)){
$parent.css(this.className, setting+"px"); // make abs (px)
this.dataset.setting = setting;
}else{
// search for id and attach based on edge
//console.log('new $target:', setting)
var edge = this.className;
if(setting.indexOf('.')>-1){
var settings = setting.split('.');
var $target = $('modkit-container#'+settings[0]);
//if(settings[1] == "top" || settings[1] == "left" || settings[1] == "right"|| settings[1] == "bottom"){
if($target[settings[1]]){
var edge = settings[1];
console.log('found edge:', $target, edge)
}
}else{
var $target = $('modkit-container#'+setting);
}
if($target.length > 0 ){
//console.log("found:", $target);
this.dataset.setting = setting;
/* switch(this.className){
...