Drag & Drop Cards In React

In this article, we will learn how we can drag and drop board in react. We will use react-beautiful-dnd package to drag and drop.

A library ‘react-beautiful-dnd’ that allow for drag and drop interactions within React. It has great set of drag and drop primitives which work especially well with the wildly inconsistent html5 drag and drop feature. It offers a powerful, natural and beautiful drag and drop experience.

If you are new to react or follow the steps to create a react app from here. I assume you have already created a react app. Now you need to follow the below steps.

You can create an app by the below command.

npx create-react-app react-drap-n-drop

Install react-beautiful-dnd, to install this you need to execute the below command in the terminal.

npm i react-beautiful-dnd --save

Now, open your main js or App.js file and add the below imports there.

import React, { useState } from "react";
import './App.css';
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
import {v4 as uuid} from 'uuid';

const itemsFromBackend = [
  { id: uuid(), content: "First task" },
  { id: uuid(), content: "Second task" },
  { id: uuid(), content: "Third task" },
  { id: uuid(), content: "Fourth task" },
  { id: uuid(), content: "Fifth task" },
  { id: uuid(), content: "Sixth task" },
  { id: uuid(), content: "Seventh task" },
  { id: uuid(), content: "Eighth task" }
];

const columnsFromBackend = {
  [uuid()]: {
    name: "All Task",
    items: itemsFromBackend
  },
  [uuid()]: {
    name: "To do",
    items: []
  },
  [uuid()]: {
    name: "In Progress",
    items: []
  },
  [uuid()]: {
    name: "Done",
    items: []
  }
};

const onDragEnd = (result, taskColumns, setTaskColumns) => {
  if (!result.destination) return;
  const { source, destination } = result;

  if (source.droppableId !== destination.droppableId) {
    const sourceColumn = taskColumns[source.droppableId];
    const destColumn = taskColumns[destination.droppableId];
    const sourceItems = [...sourceColumn.items];
    const destItems = [...destColumn.items];
    const [removed] = sourceItems.splice(source.index, 1);
    destItems.splice(destination.index, 0, removed);
    setTaskColumns({
      ...taskColumns,
      [source.droppableId]: {
        ...sourceColumn,
        items: sourceItems
      },
      [destination.droppableId]: {
        ...destColumn,
        items: destItems
      }
    });
  } else {
    const column = taskColumns[source.droppableId];
    const copiedItems = [...column.items];
    const [removed] = copiedItems.splice(source.index, 1);
    copiedItems.splice(destination.index, 0, removed);
    setTaskColumns({
      ...taskColumns,
      [source.droppableId]: {
        ...column,
        items: copiedItems
      }
    });
  }
};
function App() {
  const [taskColumns, setTaskColumns] = useState(columnsFromBackend);
  return (
    <div className="context-wrapper">
      <DragDropContext
        onDragEnd={result => onDragEnd(result, taskColumns, setTaskColumns)}
      >
        {Object.entries(taskColumns).map(([columnId, column], index) => {
          return (
            <div className="column-wrap" key={columnId}>
              <h2>{column.name}</h2>
              <div style={{ margin: 8 }}>
                <Droppable droppableId={columnId} key={columnId}>
                  {(provided, snapshot) => {
                    return (
                      <div className="dropbox"
                        {...provided.droppableProps}
                        ref={provided.innerRef}
                        style={{
                          background: snapshot.isDraggingOver
                            ? "#eee"
                            : "#ddd"
                          
                        }}
                      >
                        {column.items.map((item, index) => {
                          return (
                            <Draggable
                              key={item.id}
                              draggableId={item.id}
                              index={index}
                            >
                              {(provided, snapshot) => {
                                return (
                                  <div className="dragbox"
                                    ref={provided.innerRef}
                                    {...provided.draggableProps}
                                    {...provided.dragHandleProps}
                                    style={{
                                      
                                      backgroundColor: snapshot.isDragging
                                        ? "#929292"
                                        : "#454545",
                                      ...provided.draggableProps.style
                                    }}
                                  >
                                    {item.content}
                                  </div>
                                );
                              }}
                            </Draggable>
                          );
                        })}
                        {provided.placeholder}
                      </div>
                    );
                  }}
                </Droppable>
              </div>
            </div>
          );
        })}
      </DragDropContext>
    </div>
    );
}

export default App;

 

Now, open your App.css file and add the below styles there.

.context-wrapper{
  display: flex;
  justify-content: center;
  height: 100%;
}
.column-wrap{
  display: flex;
  flex-direction: column;
  align-items: center;
}
.dropbox{
  padding: 10px;
  width: 250px;
  min-height: 500px
}
.dragbox{
  user-select: none;
  padding: 15px;
  margin: 0 0 10px 0;
  min-height: 50px;
  color: #fff;
}

That’s it! run your app

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories