JSFiddle - React, Tailwind, and code Playground

HTML

<div id="container">
  <div id="dropzone1" class="dropzone" dropzone="move">
    <div id="draggable1" class="draggable" draggable="true">1</div>
    <div id="draggable2" class="draggable" draggable="true">2</div>
    <div id="draggable3" class="draggable" draggable="true">3</div>
    <div id="draggable4" class="draggable" draggable="true">4</div>
  </div>

  <div id="dropzone2" class="dropzone" dropzone="move">
  </div>
</div>

<div class="toolBar">
  <label for="monitorEventsToggle">
    <input type="checkbox" id="monitorEventsToggle"/>
    <u>M</u>onitor events
  </label>
  <input type="button" value="Clear Log" onclick="window.eventLog.innerText = ''"/>
</div>

<pre id="eventLog"></pre>

CSS

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  margin-top: 320px;
}

.toolBar {
  position: fixed;
  top: 300px;
  left: 0;
  right: 0;
  user-select: none;
  background: #EEE;
}

.toolBar>* {
  margin: 8px 12px;
}

#container {
  background: #DDD;
  height: 300px;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

.dropzone {
  display: inline-block;
  margin: 20px;
  padding: 20px;
  border: 2px dashed #050;
  background: #EFE;
  width: 200px;
  height: 200px;
  float: left;
}

.draggable {
  display: inline-block;
  margin: 4px;
  border: 1px solid #AAF;
  background: #DEF;
  width: 50px;
  height: 50px;
  cursor: grab;
  text-align: center;
  line-height: 50px;
}

.draggable:active {
  cursor: grabbing;
}

JavaScript

function getStandardEventNames(element) {
  const eventNames = []
  for (const prop in element) {
    if (prop.startsWith("on")) {
      const eventName = prop.slice(2)
      try {
        new Event(eventName)
        eventNames.push(eventName)
      } catch {}
    }
  }
  return eventNames.sort()
}

function monitorEvents(cssSelector, eventNames) {
  for (const element of document.querySelectorAll(cssSelector)) {
    for (const eventName of eventNames) {
      element.addEventListener(eventName, function (event) {
        if (window.monitorEventsToggle.checked) {
          event.stopPropagation();
          window.eventLog.append(
            `${
              event.target.id
                ? `#${event.target.id}`
                : event.target.tagName.toLowerCase()
            } ${event.type}\n`
          )
        }
      })
    }
  }
}

function allowDragging(cssSelector) {
  for (const element of document.querySelectorAll(cssSelector)) {
    element.ondragstart = function (event) {
      event.dataTransfer.effectAllowed = "move"
      event.dataTransfer.clearData()
      event.dataTransfer.setData("text", event.target.id)
    }
  }
}

function allowDropping(cssSelector) {
  for (const element of document.querySelectorAll(cssSelector)) {
    element.ondragover = (event) => event.preventDefault()
    element.ondrop = function (event) {
      event.preventDefault()
      event.target.appendChild(
        document.getElementById(event.dataTransfer.getData("text")),
      )
    }
  }
}

function groupConsoleMessage(duration) {
  console.group()
  setInterval(function () {
    console.groupEnd()
    console.group()
  }, duration)
}

allowDragging(".draggable")
allowDropping(".dropzone")
const events = getStandardEventNames(document.body)
monitorEvents("#container, .dropzone, .draggable", events)
window.onkeypress = event => event.key === 'm' && (window.monitorEventsToggle.checked = !window.monitorEventsToggle.checked);