Open In App

Sortable Drag and Drop with React and Tailwind CSS

Last Updated : 18 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this tutorial, we’ll learn how to create a sortable drag-and-drop feature in a React application using Vite for quick and efficient development, along with Tailwind CSS for styling. This feature allows users to reorder items in a list by dragging and dropping them, enhancing the user experience of your web application.

Output Preview: Let us have a look at how the final output will look like.

Preview of Sortable Drag and Drop with React and Tailwind CSScreenshot

Preview of Sortable Drag and Drop with React and Tailwind CSS

Prerequisites

Approach to Create a Sortable Drag and Drop

We’ll use Vite for setting up our React project quickly and efficiently. The main functionalities of our sortable drag-and-drop project include:

  • Creating a list of items that users can reorder by dragging and dropping.
  • Implementing drag-and-drop functionality using the react-dnd library.
  • Styling the interface with Tailwind CSS for a simple and modern look.

Steps to Create & Configure the Project

Step 1: Set up and Navigate to the project using the command

npx create-vite@latest sortable-drag-drop --template react
cd  sortable-drag-drop
npm install

Step 2: Install Required Libraries:

npm install react-dnd
npm install react-dnd-html5-backend

Step 3: Install Tailwind and Create the tailwind config file using the command

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Step 4: Rewrite the tailwind.config.js file as follows

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Step 5: Replace the index.css file by follows:

@tailwind base;
@tailwind components;
@tailwind utilities;

Step 6: Create components folder and create SortableList.jsx files

Project Structure:

folder

Folder structure

The updated dependencies in package.json file will look like:

"dependencies": {
    "react": "^18.2.0",
    "react-dnd": "^16.0.1",
    "react-dnd-html5-backend": "^16.0.1",
    "react-dom": "^18.2.0"
},
"devDependencies": {
    "@types/react": "^18.2.56",
    "@types/react-dom": "^18.2.19",
    "@vitejs/plugin-react": "^4.2.1",
    "autoprefixer": "^10.4.18",
    "eslint": "^8.56.0",
    "eslint-plugin-react": "^7.33.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.5",
    "postcss": "^8.4.35",
    "tailwindcss": "^3.4.1",
    "vite": "^5.1.4"
}

Example Code:

Javascript
// SortableList.jsx

import React, { useState } from 'react';
import { useDrag, useDrop } from 'react-dnd';

const ItemTypes = {
    CARD: 'card',
};

const SortableList = ({ items }) => {
    const [sortedItems, setSortedItems] = useState(items);

    const moveItem = (dragIndex, hoverIndex) => {
        const draggedItem = sortedItems[dragIndex];
        const newSortedItems = [...sortedItems];
        newSortedItems.splice(dragIndex, 1);
        newSortedItems.splice(hoverIndex, 0, draggedItem);
        setSortedItems(newSortedItems);
    };

    const Item = ({ item, index }) => {
        const [{ isDragging }, drag] = useDrag({
            type: ItemTypes.CARD,
            item: { type: ItemTypes.CARD, index },
            collect: (monitor) => ({
                isDragging: monitor.isDragging(),
            }),
        });

        const [, drop] = useDrop({
            accept: ItemTypes.CARD,
            hover: (item) => {
                const dragIndex = item.index;
                const hoverIndex = index;

                if (dragIndex === hoverIndex) {
                    return;
                }

                moveItem(dragIndex, hoverIndex);
                item.index = hoverIndex;
            },
        });

        const opacity = isDragging ? 0.5 : 1;

        return (
            <li
                ref={(node) => drag(drop(node))}
                className={
`bg-gray-100 p-4 my-2 rounded-md shadow-md ${isDragging ? 'opacity-50' : ''}`
                }
                style={{ cursor: 'move' }}
            >
                {item}
            </li>
        );
    };

    return (
        <ul>
            {sortedItems.map((item, index) => (
                <Item key={item} item={item} index={index} />
            ))}
        </ul>
    );
};

export default SortableList;
Javascript
// App.js

import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import './App.css';
import SortableList from './components/SortableList';

function App() {
  const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];

  return (
    <DndProvider backend={HTML5Backend}>
      <>
        <h1 className='text-3xl font-bold text-green-600 mb-8'>
            Geeks For Geeks: Sortable Drag and Drop
        </h1>

        <SortableList items={items} />
      </>
    </DndProvider>
  );
}

export default App;

To Run the Application, type the following command in terminal:

npm run dev

Output: Now, open your browser and navigate to http://localhost:5173 to see the sortable drag-and-drop application in action

Sortable Drag and Drop with React and Tailwind CSS

Sortable Drag and Drop with React and Tailwind CSS



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads