All writing

React modern Drag And Drop (DND) 2024

Drag and drop functionality is an excellent method to empower users with the option to effortlessly sort or relocate content. However, while implementing this feature, I've encountered a challenge – many libraries offering drag and drop capabilities are outdated and lack support for React versions beyond 18. In this article, we will explore the dnd-kit library, which is designed to seamlessly integrate with the latest versions of React.

Installation

To get started with dnd-kit, install the library:

npm install @dnd-kit/core

and then install also

npm install @dnd-kit/sortable

Basic setup

// 🧰 Importing tools for drag and drop
import { DndContext } from "@dnd-kit/core";
import {
  arraySwap,
  rectSwappingStrategy,
  SortableContext,
} from "@dnd-kit/sortable";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { useState } from "react";

export default function HomePage() {
  // 🍎🍊🍓 Setting up our collection
  const [items, setItems] = useState([
    "apple",
    "orange",
    "strawberry",
    "banana",
    "grape",
    "kiwi",
    "blueberry",
    "pineapple",
    "watermelon",
  ]);

  // 🔄 Updating positions after dragging
  const handleDragEnd = event => {
    const { active, over } = event;

    if (active.id !== over.id) {
      setItems(items => {
        const oldIndex = items.indexOf(active.id);
        const newIndex = items.indexOf(over.id);

        return arraySwap(items, oldIndex, newIndex); // 🚀 We can also use other techniques like arrayMove
      });
    }
  };

  // 🏞️ Creating a playground for sorting
  return (
    <DndContext onDragEnd={handleDragEnd}>
      <SortableContext items={items} strategy={rectSwappingStrategy}>
        {/* Our collection goes here */}
        <div className="grid max-w-96 grid-cols-3 gap-5">
          {items.map(item => (
            <SortableItem key={item} id={item} value={item} />
          ))}
        </div>
      </SortableContext>
    </DndContext>
  );
}

const SortableItem = props => {
  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({ id: props.id });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition: transition || undefined,
  };

  return (
    <div
      className={
        "flex size-24 items-center justify-center rounded-lg bg-slate-200"
      }
      ref={setNodeRef}
      style={style}
      {...props}
      {...attributes} // 🖼️ These attributes make the image draggable
      {...listeners} // 🔊 These listeners help capture the dragging actions
    >
      <p>{props.value}</p>
    </div>
  );
};

Conclusion

For more information, you can explore the dnd-kit documentation.