<aside> 🗒️

Part 1

</aside>

Drag and drop functionality: the bane of every developer aiming to create something highly customizable.

A plethora of libraries attempt to abstract this process for future developers.

This week, I tackled it for a widget system I was tasked with building. As usual, I explored various libraries to avoid reinventing the wheel.

Existing wheels

Neodrag liked that they had different rendering and performance comparisons

Swapy Still in early development. Works on React but breaks on Svelte, according to Theo's video.

Svelte flow Highly customizable with numerous features. Ideal for building Excalidraw-like applications.

Svelte-dnd-action Integrates smoothly with Svelte and is good at vertical and horizontal lists. However, I encountered difficulties adding transitions.

Sortable I liked their nesting feature, but ultimately didn't choose it due to decision fatigue.

Back to Basics

After exploring numerous libraries and burning myself out, I opted for the simple HTML drag and drop API, referring to the MDN docs.

I began by implementing drag, drag over, and drop handlers between components.

This required a draggable element

<script>
  function dragstartHandler(ev) {
    // Add the target element's id to the data transfer object
    ev.dataTransfer.setData("text/plain", ev.target.id);
  }

  window.addEventListener("DOMContentLoaded", () => {
    // Get the element by id
    const element = document.getElementById("p1");
    // Add the ondragstart event listener
    element.addEventListener("dragstart", dragstartHandler);
  });
</script>

<p id="p1" draggable="true">This element is draggable.</p>

And something that’s droppable / a drop zone

<script>
  function dragoverHandler(ev) {
    ev.preventDefault();
    ev.dataTransfer.dropEffect = "move";
  }
  function dropHandler(ev) {
    ev.preventDefault();
    // Get the id of the target and add the moved element to the target's DOM
    const data = ev.dataTransfer.getData("text/plain");
    ev.target.appendChild(document.getElementById(data));
  }
</script>

<p id="target" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
  Drop Zone
</p>

A drop zone is any element that implements both ondrop and ondragover handlers. As MDN explains:

By default, the browser prevents anything from happening when dropping something onto most HTML elements. To change that behavior so that an element becomes a drop zone or is droppable, the element must listen to both dragover and drop events.

At this point, I'm simply logging the events to the console to examine what I'm working with.