JSFiddle - React, Tailwind, and code Playground
by Abdul Ahmad
HTML
<div class='editor-menu'>
<div class='item add-container'>
+ Add container
</div>
<div class='item add-component'>
+ Add component
</div>
<div class='item'>
<div>
Border color:
</div>
<div class='colors'>
<div class='color white item'>
<div class='white'></div>
</div>
<div class='color green item'>
<div class='green'></div>
</div>
<div class='color red item'>
<div class='red'></div>
</div>
<div class='color blue item'>
<div class='blue'></div>
</div>
</div>
</div>
</div>
<div class='colors'>
<div class='add-color white item'>
<div class='white'></div>
</div>
<div class='add-color green item'>
<div class='green'></div>
</div>
<div class='add-color red item'>
<div class='red'></div>
</div>
<div class='add-color blue item'>
<div class='blue'></div>
</div>
</div>
<div class='playground-box'>
<div class='playground editable nestable'></div>
</div>
CSS
html, body {
height: 100%;
margin: 0;
font-family: sans-serif;
font-size: 14px;
}
.editor-menu {
position: fixed;
top: 10px;
left: 10px;
background-color: white;
border: 1px solid #ddd;
max-width: 150px;
}
.editor-menu > .item {
padding: 5px 10px;
border-bottom: 1px solid #ddd;
color: #666;
}
.editor-menu .item:hover {
cursor: pointer;
color: black;
}
.editor-menu .item:last-of-type {
border-bottom: none;
}
.playground-box {
text-align: center;
height: 100%;
}
.playground {
margin-top: 10px;
display: inline-block;
background-color: #eee;
border: 1px solid #ccc;
min-width: 300px;
width: 95%;
min-height: 100px;
}
.container-box {
width: 100%;
text-align: center;
}
.container {
display: inline-block;
width: 90%;
height: 40px;
border: 1px dashed #ddd;
}
.container .designable {
width: 100%;
height: 100%;
}
.component {
display: inline-block;
border: 1px dashed #ccc;
margin: 10px;
}
.component .designable {
width: 40px;
height: 40px;
}
.editing {
border: 1px solid #00FF00;
border-color: #82E882;
border: 1px dashed red;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
.white {
background-color: white;
}
.colors {
text-align: center;
}
.colors > .item {
display: inline-block;
margin: 3px;
border-radius: 100%;
width: 20px;
height: 20px;
opacity: 0.7;
}
.colors .item:hover {
cursor: pointer;
opacity: 1;
}
JavaScript
var editingElement = null;
var clickTimeStamp = null;
var editingClass = 'editing';
var playground = $('.playground');
var availableColors = [
'white',
'green',
'red',
'blue',
];
$(function() {
$('.playground-box').on('click', '.editable', function(event) {
handleOnlyFirstClick(event.timeStamp, this);
});
$('.playground-box').on('dblclick', '.editable', function() {
editingElement = null;
removeClassIfExists($(this), editingClass);
});
$('.add-container').on('click', function() {
$(playground).append(getContainer());
});
$('.add-component').on('click', function() {
if(nestable(editingElement)) {
$(editingElement).append(getComponent());
} else if(editingElement === null) {
$(playground).append(getComponent());
}
});
$('.add-color').on('click', function() {
if(editingElement !== null) {
console.log($(this).children().first().attr('class'));
removeColorClassesIfExist(
getDesignableElement(editingElement)
);
addClassIfNotExists(
getDesignableElement(editingElement),
$(this).children().first().attr('class')
);
}
});
});
function handleOnlyFirstClick(timeStamp, element) {
if(clickTimeStamp === null) {
clickTimeStamp = timeStamp;
nullifyEditingElement();
assignNewEditingElement(element);
setTimeout(function() {
clickTimeStamp = null;
}, 100);
}
}
function nullifyEditingElement() {
if(editingElement !== null) {
removeClassIfExists($(editingElement), editingClass);
editingElement = null;
}
}
function assignNewEditingElement(element) {
editingElement = $(element);
addClassIfNotExists($(element), editingClass);
}
function addClassIfNotExists(element, klass) {
if(!$(element).hasClass(klass)) {
$(element).addClass(klass);
}
}
function removeClassIfExists(element, klass) {
if($(element).hasClass(klass)) {
$(element).removeClass(klass);
}
}
function removeClassesIfExist(element, classes) {
for(var i =...