JSFiddle - React, Tailwind, and code Playground

HTML

<div class="drag-target">
    <button class="drag-element" draggable="true" ondragstart="event.dataTransfer.setData('text/plain',null)">
        This div is draggable
    </button>
</div>
<div class="drag-target"></div>
<div class="drag-target"></div>
<div class="drag-target"></div>

CSS

.drag-element {
  width: 200px;
  height: 20px;
  text-align: center;
  background: white;
}

.drag-target {
  width: 200px;
  height: 20px;
  background: blueviolet;
  margin-bottom: 10px;
  padding: 10px;
}

JavaScript

let dragged = null;

function drop_handler( event ) {
  event.preventDefault();

  this.style.background = "";
  dragged.remove();
  this.appendChild( dragged );
}

function dragover_handler( event ) {
  event.preventDefault();
}

function dragstart_handler( event ) {
  dragged = this;
  this.style.color = '#f00';
}

function dragend_handler( event ) {
  this.style.color = "";
}

class Drag {
  drop = drop_handler;
  dragover = dragover_handler;
  dragstart = dragstart_handler;
  dragend = dragend_handler;

  events = ['dragover', 'drop', 'dragstart', 'dragend'];

  constructor(targetSelector, elementSelector) {
    this.targetSelector = targetSelector;
    this.elementSelector = elementSelector;
    this.start();
  }

  handleEvent(event) {
    let { type, target } = event;

    switch(type) {
      case 'dragover':
      case 'drop':
        target = target.closest(this.targetSelector);
        break;
      case 'dragstart':
      case 'dragend':
        target = target.closest(this.elementSelector)
        break;
    }

    if(target)
      this[type].call(target, event);
  }

  start() {
    this.events.forEach(type => document.addEventListener(type, this));
    return this;
  }
  stop() { 
    this.events.forEach(type => document.removeEventListener(type, this));
    return this;
  }
}

const drag = new Drag('.drag-target', '.drag-element');