JSFiddle - React, Tailwind, and code Playground
by mrtoxas
HTML
<div class="tiles tiles-default">
<a href="#" class="tile">
<div class="tile__header">
<div class="tile__fav"></div>
<div class="tile__title">1</div>
</div>
<div class="tile__body">
</div>
</a>
<a href="#" class="tile">
<div class="tile__header">
<div class="tile__fav"></div>
<div class="tile__title">2</div>
</div>
<div class="tile__body">
</div>
</a>
<a href="#" class="tile">
<div class="tile__header">
<div class="tile__fav"></div>
<div class="tile__title">3</div>
</div>
<div class="tile__body">
</div>
</a>
<a href="#" class="tile">
<div class="tile__header">
<div class="tile__fav"></div>
<div class="tile__title">4</div>
</div>
<div class="tile__body">
</div>
</a>
<a href="#" class="tile">
<div class="tile__header">
<div class="tile__fav"></div>
<div class="tile__title">5</div>
</div>
<div class="tile__body">
</div>
</a>
<a href="#" class="tile">
<div class="tile__header">
<div class="tile__fav"></div>
<div class="tile__title">6</div>
</div>
<div class="tile__body">
</div>
</a>
<a href="#" class="tile">
<div class="tile__header">
<div class="tile__fav"></div>
<div class="tile__title">7</div>
</div>
<div class="tile__body">
</div>
</a>
<button onclick="alert('!!!')" class="tiles__plus-btn" draggable="false">
+
</button>
</div>
SCSS
:root {
--tile-width: 200px;
--tile-header-height: 32px;
--column-grap: 15px;
--column-count: 3;
}
* {
box-sizing: border-box;
}
body{
padding:20px;
}
.tiles {
display: grid;
grid-template-columns: repeat(var(--column-count), minmax(calc(var(--column-count) * 1%), var(--tile-width)));
grid-gap: var(--column-grap);
justify-content: center;
align-content: flex-start;
grid-auto-columns: 1fr;
}
.tile {
text-decoration: none;
position: relative;
cursor: pointer;
}
.tile__header{
display:grid;
grid-template-columns:30px 1fr;
height:30px;
border-bottom:1px solid #eee;
}
.tile__title{
white-space:nowrap;
overflow: hidden;
text-overflow: ellipsis;
align-self: center;
line-height:14px;
padding-right:5px;
}
.tile__fav {
background-image: url(http://www.google.com/s2/favicons?domain=video.coma);
background-size: 16px;
background-repeat: no-repeat;
background-position:center;
}
.tile__body{
padding-top:50%;
}
.grabbable > .grabbable-dummy{
background-color:#eee;
}
.tiles__plus-btn{
pointer-events:none;
background:#eee;
color:#ccc;
border:0;
font-size:36px;
}
//themes - default
.tiles-default .tile{
background: rgb(250, 250, 250);
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
transition: box-shadow 0.2s linear;
font-family: arial, sans-serif;
border-radius: 2px;
font-size: 12px;
color: #757575;
&:hover {
box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.08);
}
&:focus,
&:focus-within {
filter: brightness(92%);
}
&:active {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
}
@media(max-width:480px){
font-size: 12px;
}
}
JavaScript
"use strict";
!(function() {
var callCallback = function(elem) {
if (document.createEventObject) {
elem.fireEvent("ondragged");
} else {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("dragged", false, true);
elem.dispatchEvent(evt);
}
};
var dummy = null,
bg = null;
var createDummy = function() {
bg = document.createElement("div");
bg.style.position = "absolute";
bg.style.width = "1px";
bg.style.height = "1px";
bg.style.overflow = "hidden";
dummy = document.createElement("div");
dummy.className = "grabbable-dummy";
dummy.style.position = "relative";
dummy.addEventListener("drop", function(e) {
var data = e.dataTransfer.getData("text");
if (data != "draggable") return;
e.preventDefault();
e.stopPropagation();
while (bg.children.length > 0) {
var elem = bg.children[0];
this.parentNode.insertBefore(elem, this);
}
dummy.style.display = "none";
callCallback(dummy.parentNode);
});
var x = document.querySelector("body");
x.appendChild(dummy);
x.appendChild(bg);
};
var updateDummy = function(el) {
bg.style.left = el.offsetLeft + "px";
bg.style.top = el.offsetTop + "px";
dummy.style.maxWidth = el.offsetWidth + "px";
dummy.style.height = el.offsetHeight + "px";
var style = window.getComputedStyle(el);
dummy.style.display = style.display;
dummy.style.margin =
style.marginTop +
" " +
style.marginRight +
" " +
style.marginBottom +
" " +
style.marginLeft;
dummy.style.padding =
style.paddingTop +
" " +
style.paddingRight +
" " +
style.paddingBottom +
" " +
style.paddingLeft;
};
var initGrabbable = function() {
createDummy();
};
var prevent = function(e) {
e.preventDefault();
e.stopPropagation();
};
var allowDrop = function(e) {
...