Search code examples
javascriptreactjsreact-beautiful-dnd

React-beautiful-dnd doesn't work with overflow auto


I'm creating an app like "Trello", and I'm getting into some issues. I created the "Board", the "Cards" and the "Tasks". Each card have a width of 300px. If I'm creating more cards than the website be able to display, it will go offscreen (and and scrollbar at the bottom of the whole page appears), and I wanted to add that scrollbar only to the "Board" div. That's what I did, and, the scrollbar appeared, and worked as expected.. but the problem is that, I can no longer move tasks between other EMPTY Cards. I can move (sort) between them, but can't move to an empty card... I'm using react with tailwindcss and "@hello-pangea/dnd" as a replacement for react-beautiful-dnd. I've tried with other libraries, but I couldn't make to work (the entire dnd) as I wanted (effect I got with this library...) Here's the entire code:

function Task({ task, index }) { <==TASKS
  return (
    <Draggable draggableId={task._id} index={index} type="task">
      {(provided) => (
        <div
          {...provided.draggableProps}
          {...provided.dragHandleProps}
          ref={provided.innerRef}
          className="bg-white rounded p-4 shadow mb-4 relative"
        >
          {task.name}
        </div>
      )}
    </Draggable>
  );
}

function Section({ section, index }) {  <==CARDS
  return (
    <Draggable draggableId={section._id} index={index}>
      {(provided) => (
        <div
          {...provided.draggableProps}
          {...provided.dragHandleProps}
          ref={provided.innerRef}
          className="w-[300px] p-2 mb-4"
        >
          <div className="bg-white rounded p-4 shadow mb-4">
            <h2 className="text-lg font-bold">{section.name}</h2>
            <Droppable droppableId={section._id} type="task">
              {(provided) => (
                <div
                  {...provided.droppableProps}
                  ref={provided.innerRef}
                  className="min-w-full overflow-visible"
                >
                  {section.tasks.map((task, index) => (
                    <Task
                      key={task._id}
                      task={task}
                      index={index}
                      sectionId={section._id}
                    />
                  ))}
                  {provided.placeholder}
                </div>
              )}
            </Droppable>
            
          </div>
        </div>
      )}
    </Draggable>
  );
}

function Tasks({ project }) { <==BOARD
  const [state, setState] = useState(project);

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

    // If the item was dropped outside of a droppable area, exit
    if (!destination) {
      return;
    }

    // If the item was dropped in the same position, exit
    if (
      destination.droppableId === source.droppableId &&
      destination.index === source.index
    ) {
      return;
    }

    if (type === "task") {
      const sourceSection = state.sections.find(
        (section) => section._id === source.droppableId
      );
      const destinationSection = state.sections.find(
        (section) => section._id === destination.droppableId
      );

      // Move the task to the new section
      const task = sourceSection.tasks.splice(source.index, 1)[0];
      destinationSection.tasks.splice(destination.index, 0, task);

      // Update the state
      setState((prevState) => ({
        ...prevState,
        sections: [...prevState.sections],
      }));
    } else {
      // Move the section to the new position
      const section = state.sections.splice(source.index, 1)[0];
      state.sections.splice(destination.index, 0, section);

      // Update the state
      setState((prevState) => ({
        ...prevState,
        sections: [...prevState.sections],
      }));
    }
  };


  return (
    <div className="flex">** <== HERE I ADDED OVERWFLOW X AUTO**
      <DragDropContext onDragEnd={onDragEnd}>
        <Droppable droppableId="sections" direction="horizontal" className="h-max">
          {(provided, snapshot) => (
            <div {...provided.droppableProps} ref={provided.innerRef}  className="h-full flex">
              {state.sections.map((section, index) => (
                <Section key={section._id} section={section} index={index} />
              ))}
              {provided.placeholder}
            </div>
          )}
          
        </Droppable>
       
      </DragDropContext>
    </div>
  );
}

I've tried to set the height of the div where I added the overflow, to a fixed height, but didn't work.. Nothing else, since I didn't see anyone with this problem...

Edit/ i've tried to add a "dummy" task (empty), but it will look weird... (but worked).

Edit2/ i've tried to get something from here: https://github.com/marconunnari/trello-clone but, since we have different approach over the "app", it's kinda difficult for me...


Solution

  • I fixed it by adding a "min-h-[18px]" CSS class to the section droppable:

    <Droppable droppableId={section._id} type="task">
      {(provided, snapshot) => (
        <div
          {...provided.droppableProps}
          ref={provided.innerRef}
          className={`min-h-[18px] ${
            snapshot.isDraggingOver && "bg-gray-400 rounded-md"
          }`}
        >
          {section.tasks.map((task, index) => (
            <Task
              key={task._id}
              task={task}
              index={index}
              sectionId={section._id}
            />
          ))}
          {provided.placeholder}
        </div>
      )}
    </Droppable>