How to add different background colours for each droppable element

Viewed 640

I created a simple drag and drop todo list app using react-beautiful-dnd. However I am unable to know how to change the background colour for each droppable element/ column in this. According to my present output, all 3 columns in my app has the same background colour. I want to have different background colours for each column. I am a beginner for react. Therefore please kindly let me know how to change the background color for each column.

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

const item = {
  id: v4(),
  name: "Clean the house"
}

const item2 = {
  id: v4(),
  name: "Wash the car"
}

function App() {
  const [text, setText] = useState("")
  const [state, setState] = useState({
    //creating 3 columns
    "todo": {
      title: "Todo",
      items: [item, item2]//temporary data valuesa
    },
    "in-progress": {
      title: "In Progress",
      items: []
    },
    "done": {
      title: "Completed",
      items: []
    }
  })

  const handleDragEnd = ({destination, source}) => {
    if (!destination) {
      return
    }

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

    // Creating a copy of item before removing it from state
    const itemCopy = {...state[source.droppableId].items[source.index]}

    setState(prev => {
      prev = {...prev}
      // Remove from previous items array
      prev[source.droppableId].items.splice(source.index, 1)


      // Adding to new items array location
      prev[destination.droppableId].items.splice(destination.index, 0, itemCopy)

      return prev
    })
  }

  const addItem = () => {
    setState(prev => {
      return {
        ...prev,
        todo: {
          title: "Todo",
          items: [
            {
              id: v4(),
              name: text
            },
            ...prev.todo.items
          ]
        }
      }
    })

    setText("")
  }
  //the dragdropcontext is the wrapper for draging elements
  //dropable is the certain area inside the column where u can drop items
  //dragble are the items in the column to be dragged



  //here {_.map(state, (data, key) => { 
    //the above function is used to return the data and key of all 3 elements mentioned under use state() above
    //the key: returns todo,inprogress,and done
    //where as the data returns all the values of the variables within each key
  return (
    <div className="App">
      <div>
        <input type="text" value={text} onChange={(e) => setText(e.target.value)}/>
        <button onClick={addItem}>Add</button>
      </div>
      <DragDropContext onDragEnd={handleDragEnd}>
   
        {_.map(state, (data, key) => {
          return(
            <div key={key} className={"column"}>
              <h3>{data.title}</h3>
              <Droppable droppableId={key}>
                {(provided, snapshot) => {
                  return(
                    <div
                      ref={provided.innerRef}
                      {...provided.droppableProps}
                      key = {"Todo"}
                      className={"droppable-col"}
                    >
                      {data.items.map((el, index) => {
                        return(
                          <Draggable key={el.id} index={index} draggableId={el.id}>
                            {(provided, snapshot) => {
                              console.log(snapshot)
                              return(
                                <div
                                  className={`item ${snapshot.isDragging && "dragging"}`}
                                  ref={provided.innerRef}
                                  {...provided.draggableProps}
                                  {...provided.dragHandleProps}
                                >
                                  {el.name}
                                </div>
                              )
                            }}
                          </Draggable>
                        )
                      })}
                      {provided.placeholder}
                    </div>
                  )
                }}
              </Droppable>
            </div>
          )
        })}
      </DragDropContext>
    </div>
  );
}

export default App;

The css file

    * {
    box-sizing: border-box;
}

.App {
    display: flex;
    width: 100%;
    justify-content: space-around;
}

.App .column {
    width: 30%;
}

.droppable-col {
    width: 100%;
    background-color: gray;
    padding: 10px 10px 0 10px;
    border-radius: 7px;
    display: flex;
    flex-direction: column;
}

.item {
    margin-bottom: 10px;
    background-color: gray;
    color: white;
    border: 1px solid white;
    padding: 5px;
    border-radius: 7px;
}

.item.dragging {
    background-color: coral;
}
1 Answers

You have a tag attribute attached to each column called data-rbd-droppable-id.

By looking at generated HTML you'll see:

<div data-rbd-droppable-id="todo" ... >
  ...
</div>

It's generated from state keys for every single column you define there. So, you have todo, in-progress and done values at the moment.

App.js

const [state, setState] = useState({
  //creating 3 columns
  todo: { // <- key `todo` which is attached to `data-rbd-droppable-id`
    ...
  },
  "in-progress": { // <- key `in-progress` which is attached to `data-rbd-droppable-id`
    ...
  },
  done: { // <- key `done` which is attached to `data-rbd-droppable-id`
    ...
  }
});

Now you're able to control background-color for each column by using CSS below.

App.css

[data-rbd-droppable-id='todo'] {
  background-color: blue;
}

[data-rbd-droppable-id='in-progress'] {
  background-color: orange;
}

[data-rbd-droppable-id='done'] {
  background-color: green;
}

Live demo

Related