17 - Drag-and-Drop Feature for Rearranging Items

Description

Create a React application that displays an ordered list of items and allows users to drag and drop to change the order. The application should visually indicate the drag state and drop target.

Algorithm

  1. Create a state variable to store the list of items.

  2. Define a function to handle the drag start event.

  3. Define a function to handle the drag over event.

  4. Define a function to handle the drop event.

  5. Update the state variable when the user drops an item.

  6. Render the list of items with a drag handle and a drop target indicator.

Classes

  • DraggableItem: A component that represents a single item in the list.

  • DraggableList: A component that renders the list of items and handles the drag and drop events.

Code

DraggableItem.js

import React from 'react';

function DraggableItem({ item, onDragStart, onDragOver, onDrop }) {
  return (
    <div>
      <div
        draggable="true"
        onDragStart={onDragStart}
        onDragOver={onDragOver}
        onDrop={onDrop}
      >
        {item.name}
      </div>
      <div className="drag-handle" />
    </div>
  );
}

export default DraggableItem;

DraggableList.js

import React, { useState } from 'react';
import DraggableItem from './DraggableItem';

function DraggableList() {
  const [items, setItems] = useState([
    { id: 1, name: 'Item 1' },
    { id: 2, name: 'Item 2' },
    { id: 3, name: 'Item 3' },
  ]);
  const [dragging, setDragging] = useState(null);

  const handleDragStart = (item) => {
    setDragging(item);
  };

  const handleDragOver = (item) => {
    // Update the drop target indicator
    const dropTarget = event.target.closest('.draggable-item');
    if (dropTarget) {
      dropTarget.classList.add('drop-target');
    }
  };

  const handleDrop = (item) => {
    // Update the list of items
    setItems(
      items.map((item1) =>
        (item.id === item1.id ? item1 : dragging)
      )
    );
    // Reset the currently dragging item
    setDragging(null);
  };

  return (
    <div>
      {items.map((item) => (
        <DraggableItem
          key={item.id}
          item={item}
          onDragStart={handleDragStart}
          onDragOver={handleDragOver}
          onDrop={handleDrop}
        />
      ))}
    </div>
  );
}

export default DraggableList;

index.css

.draggable-item {
  padding: 10px;
  border: 1px solid #ccc;
  background-color: #fff;
  cursor: move;
}

.drag-handle {
  font-size: 16px;
  cursor: move;
}

.drop-target {
  background-color: #ccc;
}

Explanation

The DraggableItem component represents a single item in the list and handles the drag start, drag over, and drop events. The DraggableList component renders the list of items and handles the drag and drop events. The component uses the useState hook to store the list of items and the currently dragging item. The component updates the list of items when the user drops an item.

Possible Future Enhancements

  • Add more features to the drag and drop functionality (e.g., sorting, grouping).

  • Use a more advanced drag and drop library (e.g., React DnD).

  • Display a placeholder item during the drag operation.

Last updated