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) {
   ...