Creating a Inter Draggable Lists with React Beautiful DnD

React Beautiful DnD (Drag and Drop) is a powerful and flexible library that allows developers to add draggable and droppable elements to their React applications. It is built on top of the popular react-dnd library and provides a set of higher-order components that can be used to create draggable and droppable lists, boards, and other interactive elements.

Our example app is using the React Beautiful DnD library, which allows for drag-and-drop functionality. The code creates three lists of items – fruits, vegetables, and vehicles – and renders them in the UI. Users can drag and drop items between the lists and the status will update to indicate the item’s current location.

Here is an example of how to use React Beautiful DnD to create a simple draggable list:

 

Install React Beautiful DnD Library

Start by installing the React Beautiful DnD library in your react application by executing the below npm command:

npm install react-beautiful-dnd

 

Next update the App component with below code:

import React, { useState } from "react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";

const fruits = [
  { id: 1, name: "Apple", color: "lightgreen" },
  { id: 2, name: "Banana", color: "lightgreen" },
  { id: 3, name: "Mango", color: "lightgreen" },
  { id: 4, name: "Orange", color: "lightgreen" },
  { id: 5, name: "Grapes", color: "lightgreen" },
];

const vegetables = [
  { id: 6, name: "Carrot", color: "lightblue" },
  { id: 7, name: "Potato", color: "lightblue" },
  { id: 8, name: "Tomato", color: "lightblue" },
  { id: 9, name: "Cucumber", color: "lightblue" },
  { id: 10, name: "Onion", color: "lightblue" },
];

const vehicles = [
  { id: 11, name: "Car", color: "pink" },
  { id: 12, name: "Bike", color: "pink" },
  { id: 13, name: "Bus", color: "pink" },
  { id: 14, name: "Truck", color: "pink" },
  { id: 15, name: "Train", color: "pink" },
];

const App = () => {
  const [fruitsList, setFruitsList] = useState(fruits);
  const [vegetablesList, setVegetablesList] = useState(vegetables);
  const [vehiclesList, setVehiclesList] = useState(vehicles);
  const [status, setStatus] = useState("");

  const onDragEnd = (result) => {
    const { destination, source, draggableId } = result;

    if (!destination) {
      return;
    }

    if (
      destination.droppableId === source.droppableId &&
      destination.index === source.index
    ) {
      return;
    }

    const sourceList =
      source.droppableId === "fruits"
        ? fruitsList
        : source.droppableId === "vegetables"
        ? vegetablesList
        : vehiclesList;
    const destinationList =
      destination.droppableId === "fruits"
        ? fruitsList
        : destination.droppableId === "vegetables"
        ? vegetablesList
        : vehiclesList;

    const item = sourceList.find((i) => i.id.toString() === draggableId);
    sourceList.splice(source.index, 1);
    destinationList.splice(destination.index, 0, item);

    if (destination.droppableId === "fruits") {
      setFruitsList([...destinationList]);
    } else if (destination.droppableId === "vegetables") {
      setVegetablesList([...destinationList]);
    } else {
      setVehiclesList([...destinationList]);
    }
    setStatus(
      `Item: ${item.name} moved from ${source.droppableId} to ${destination.droppableId}`
    );
  };

  return (
    <>
      <div>
        <pre>{status}</pre>
      </div>
      <div
        style={{
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          height: "100vh",
        }}
      >
        <DragDropContext onDragEnd={onDragEnd}>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              width: "80%",
            }}
          >
            <Droppable droppableId="fruits">
              {(provided, snapshot) => (
                <div
                  ref={provided.innerRef}
                  style={{
                    background: snapshot.isDraggingOver
                      ? "lightgreen"
                      : "green",
                    padding: 8,
                    width: "30%",
                    minHeight: "100px",
                  }}
                  {...provided.droppableProps}
                >
                  <h2>Fruits</h2>
                  {fruitsList.map((item, index) => (
                    <Draggable
                      key={item.id}
                      draggableId={item.id.toString()}
                      index={index}
                    >
                      {(provided, snapshot) => (
                        <div
                          ref={provided.innerRef}
                          {...provided.draggableProps}
                          {...provided.dragHandleProps}
                          style={{
                            userSelect: "none",
                            padding: 16,
                            margin: "0 0 8px 0",
                            minHeight: "50px",
                            backgroundColor: snapshot.isDragging
                              ? "lightgreen"
                              : item.color,
                            ...provided.draggableProps.style,
                          }}
                        >
                          {item.name}
                        </div>
                      )}
                    </Draggable>
                  ))}
                  {provided.placeholder}
                </div>
              )}
            </Droppable>
            <Droppable droppableId="vegetables">
              {(provided, snapshot) => (
                <div
                  ref={provided.innerRef}
                  style={{
                    background: snapshot.isDraggingOver ? "lightblue" : "blue",
                    padding: 8,
                    width: "30%",
                    minHeight: "100px",
                  }}
                  {...provided.droppableProps}
                >
                  <h2>Vegetables</h2>
                  {vegetablesList.map((item, index) => (
                    <Draggable
                      key={item.id}
                      draggableId={item.id.toString()}
                      index={index}
                    >
                      {(provided, snapshot) => (
                        <div
                          ref={provided.innerRef}
                          {...provided.draggableProps}
                          {...provided.dragHandleProps}
                          style={{
                            userSelect: "none",
                            padding: 16,
                            margin: "0 0 8px 0",
                            minHeight: "50px",
                            backgroundColor: snapshot.isDragging
                              ? "lightblue"
                              : item.color,
                            ...provided.draggableProps.style,
                          }}
                        >
                          {item.name}
                        </div>
                      )}
                    </Draggable>
                  ))}
                  {provided.placeholder}
                </div>
              )}
            </Droppable>
            <Droppable droppableId="vehicles">
              {(provided, snapshot) => (
                <div
                  ref={provided.innerRef}
                  style={{
                    background: snapshot.isDraggingOver ? "pink" : "red",
                    padding: 8,
                    width: "30%",
                    minHeight: "100px",
                  }}
                  {...provided.droppableProps}
                >
                  <h2>Vehicles</h2>
                  {vehiclesList.map((item, index) => (
                    <Draggable
                      key={item.id}
                      draggableId={item.id.toString()}
                      index={index}
                    >
                      {(provided, snapshot) => (
                        <div
                          ref={provided.innerRef}
                          {...provided.draggableProps}
                          {...provided.dragHandleProps}
                          style={{
                            userSelect: "none",
                            padding: 16,
                            margin: "0 0 8px 0",
                            minHeight: "50px",
                            backgroundColor: snapshot.isDragging
                              ? "pink"
                              : item.color,
                            ...provided.draggableProps.style,
                          }}
                        >
                          {item.name}
                        </div>
                      )}
                    </Draggable>
                  ))}
                  {provided.placeholder}
                </div>
              )}
            </Droppable>
          </div>
        </DragDropContext>
      </div>
    </>
  );
};

export default App;

The code starts by importing the necessary libraries and dependencies for the project, including React, the useState hook, and the DragDropContext, Droppable, and Draggable components from the react-beautiful-dnd library.

Next, three arrays are defined that contain data for different types of items (fruits, vegetables, and vehicles). Each item in the arrays has an id, name, and color property.

The App component is defined as a functional component that uses React’s useState hook to manage the state of the fruitsList, vegetablesList, and vehiclesList arrays, as well as a status string.

The onDragEnd function is defined as a callback for the DragDropContext component’s onDragEnd prop. This function is called whenever a draggable item is dropped in a droppable area. It takes a single argument, the result of the drag and drop action, which contains information about the source and destination of the item, as well as the id of the draggable item.

Within the onDragEnd function, a series of conditional statements are used to check if the draggable item was dropped in a valid destination. If not, the function exits. If the destination is valid, the item is removed from the source array and added to the destination array.

Depending on the destination droppableId, the relevant state is updated to reflect the change in the arrays. The status string is also updated to show the movement of item.

The App component’s return statement renders the components that make up the UI of the application. It starts by rendering a <div> that displays the current status of the drag and drop action.

The next <div> is used to center the drag and drop area on the screen and has some styling applied to it. Inside this div, the DragDropContext component is rendered.

Within the DragDropContext component, a <div> is rendered with some styling applied to it. This div contains three Droppable components, one for each of the fruitsList, vegetablesList, and vehiclesList arrays.

Each Droppable component is passed a droppableId prop that corresponds to the array it represents. Inside each Droppable component, a map function is used to render a Draggable component for each item in the corresponding array.

The Draggable component is passed a key, draggableId, and index prop that correspond to the item’s id, id as a string and index in the array. Inside each Draggable component, the item’s name and color are rendered, and some styling is applied to it.

The Draggable component also receives the provided object, which contains props that need to be spread on the DOM element. The innerRef prop is used to pass a ref to the top-level DOM node, and the draggableProps and dragHandleProps props are used to make the element draggable.

Finally, run your app to show the dynamically created lists so that you can drag items inter between the lists.

Conclusion

In conclusion, this code uses the React library and the react-beautiful-dnd library to create a drag and drop functionality for different lists of items. The items are grouped into three different lists: fruits, vegetables, and vehicles. Each list is represented by a Droppable component, which allows for items to be dragged and dropped within the same list or between different lists.

The onDragEnd function is used to handle the logic of moving items between lists and updating the state of each list. Additionally, the status of the last item moved is displayed for the user. Overall, this code demonstrates the use of the react-beautiful-dnd library to implement a functional and user-friendly drag and drop feature in a React application.

 

Leave a Comment

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