JSFiddle - React, Tailwind, and code Playground

by fxi

HTML

<ul id="root">

</ul>

CSS

ul {
  width: 50%;
  display: flex;
  flex-direction: column;
  padding: 0px;
  margin: 0px;
}

#pos {
  width: 10px;
  height: 10px;
  position: absolute;
  background: red;
  z-index: 1200;
}

.draggable {
  width: 100%;
  height: 50px;
  padding: 0px;
  margin: 2px;
  background-color: #ccc;
  list-style: none;
  border-radius: 3px;
  overflow: hidden;

}

.dragged {
  cursor: grabbing;
  cursor: -moz-grabbing;
  cursor: -webkit-grabbing;
}

.handle {
  width: 100%;
  height: 20px;
  background-color: #bbb;
  color: white;
    cursor: move;
  /* fallback if grab cursor is unsupported */
  cursor: grab;
  cursor: -moz-grab;
  cursor: -webkit-grab;
}

.drop-area {
  border-radius: 5px;
  width: 100%;
  height: 10px;
  background: rgba(212, 212, 212, 0.34);
}

.grabbable {}

JavaScript

var root = document.getElementById("root");
var elPos = document.getElementById("pos");
/**
 * Init ui
 */
for (var i = 0; i < 10; i++) {
  var li = document.createElement("li");
  var elHandle = document.createElement("div");
  elHandle.className = "handle";
  li.className = "draggable";
  li.id = "li_" + i;
  li.appendChild(elHandle);
  root.appendChild(li);
  elHandle.innerText = i;
}

sortable({
  selector: root
})


function sortable(o) {

  o.listener = {};
  var sortableOpt = o;

  if (o.selector instanceof Node) {
    o.elRoot = o.selector;
  } else {
    o.elRoot = document.querySelector(o.selector);
  }

  o.classHandle = o.classHandle || "handle";
  o.classDraggable = o.classDraggable || "draggable";
  o.classDropArea = o.classDropArea || "drop-area";

  /**
   * On init
   */
  o.listener.mousedown = function(event) {

    var elHandle = event.target;
    var isHandle = elHandle.classList.contains(o.classHandle);

    if (isHandle && !o.elDrag) {

      o.elDrag = findParentByClass({
        selector: elHandle,
        class: o.classDraggable
      })

      if (o.elDrag) {

        draggable({
          event: event,
          elRoot: o.elRoot,
          selector: o.elDrag,
          classHandle: o.classHandle,
          classDraggable: o.classDraggable,
          classDropArea: o.classDropArea,
          onDragStart: o.listener.onDragStart,
          onDragMove: o.listener.onDragMove,
          onDragEnd: o.listener.onDragEnd
        })
      }
    }
  };

  o.elRoot.addEventListener('mousedown', o.listener.mousedown, false);


  /**
   * On drag start
   */
  o.listener.onDragStart = function(o, e) {
    setDragArea(o, o.el);
  };


  /**
   * On drag move
   */
  o.listener.onDragMove = function(o, e) {

    o.elOver = getOver(o);

    var isOver =
      o.elOver instanceof Node &&
      o.elOver !== o.el &&
      o.elOver !== o.elOverPrevious;

    if (isOver) {
      setDragArea(o, o.elOver);
      o.elOverPrevious = o.elOver;

     ...