hello-pangea / dnd

💅 Beautiful and accessible drag and drop for lists with React. ⭐️ Star to support our work!
https://dnd.hellopangea.com
Other
2.44k stars 95 forks source link

Drag error on second drag. #826

Open TomasGranda opened 2 months ago

TomasGranda commented 2 months ago

I'm having a problem when i try to drag a draggable before i drop it on another droppable.

I get this error. image

Info: I dont have any scroll container I have multiple droppable I have 1 droppable in virtual mode

The error doesn't appear if i remove the virtual mode Droppable

Each blue square with name are droppables with the problem and down red square are the virtual mode droppable I also get this error when i drop any top draggable on the down droppable and then i try to drag any of the top draggable image

Extra: If i drop the down draggable outside (and remove it from the droppable) i am able again to drag any of the top draggables

Code:

Top Blue Draggables:

import {
  Draggable,
  DraggableStateSnapshot,
  DraggableStyle,
  Droppable,
} from "@hello-pangea/dnd";
import React from "react";
import { pocketBarID } from "./DragAndDropWrapper";

function getClassNames(snapshot: DraggableStateSnapshot) {
  if (snapshot.isDragging) {
    return "bg-red-500";
  }

  return "bg-blue-500";
}

function getStyle(
  style: DraggableStyle | undefined,
  snapshot: DraggableStateSnapshot
) {
  if (!snapshot.isDropAnimating || snapshot.draggingOver == pocketBarID) {
    return style;
  }

  return {
    ...style,
    transitionDuration: `0.001s`,
  };
}

export default function DraggableItem({
  character,
}: Readonly<{ character: any }>) {
  return (
    <Droppable
      direction="horizontal"
      droppableId={"droppable/" + character.id}
      isDropDisabled={true}
    >
      {(provided) => (
        <div {...provided.droppableProps} ref={provided.innerRef}>
          <Draggable
            draggableId={JSON.stringify({
              container: "characterContainer",
              type: "draggable",
              id: character.id,
              key: character.uuid,
            })}
            index={0}
          >
            {(provided, snapshot) => (
              <>
                <div
                  className={getClassNames(snapshot) + " h-20 w-20"}
                  ref={provided.innerRef}
                  {...provided.dragHandleProps}
                  {...provided.draggableProps}
                  style={getStyle(provided.draggableProps.style, snapshot)}
                >
                  {character.name}
                </div>
                {snapshot.isDragging && (
                  <div className="bg-blue-500 h-20 w-20">{character.name}</div>
                )}
              </>
            )}
          </Draggable>
        </div>
      )}
    </Droppable>
  );
}

Down Red Droppable:


import {
  Draggable,
  DraggableStateSnapshot,
  DraggableStyle,
  Droppable,
} from "@hello-pangea/dnd";
import React, { Fragment } from "react";
import { pocketBarID } from "./DragAndDropWrapper";
import { useCharactersStore } from "@/app/globalState";
import { v4 as uuidv4 } from "uuid";

function getStyle(
  style: DraggableStyle | undefined,
  snapshot: DraggableStateSnapshot
) {
  if (!snapshot.isDropAnimating) {
    return style;
  }

  return {
    ...style,
    transitionDuration: `0.001s`,
  };
}

const getItemID = (jsonInfo: string) => {
  const info = JSON.parse(jsonInfo);
  return info.id;
};

export default function PocketBar({
  items,
}: Readonly<{ items: { id: string; key: string }[] }>) {
  const characters = useCharactersStore((state) => state.characters);

  return (
    <Droppable
      direction="horizontal"
      droppableId={pocketBarID}
      mode="virtual"
      renderClone={(provided, snapshot, rubric) => (
        <div
          ref={provided.innerRef}
          {...provided.draggableProps}
          {...provided.dragHandleProps}
          style={getStyle(provided.draggableProps.style, snapshot)}
          className="h-20 w-20 bg-red-500"
        >
          {characters.find(
            (character) => character.id == getItemID(rubric.draggableId)
          )?.name ?? "alt"}
        </div>
      )}
    >
      {(provided) => (
        <div
          className="flex w-full h-20 fixed bottom-0"
          {...provided.droppableProps}
          ref={provided.innerRef}
        >
          {items.map((item, index) => (
            <Fragment key={uuidv4()}>
              <Draggable
                draggableId={JSON.stringify({
                  container: pocketBarID,
                  type: "draggable",
                  id: getItemID(item.id),
                  key: item.key,
                })}
                index={index}
              >
                {(provided, snapshot) => (
                  <div
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                    style={getStyle(provided.draggableProps.style, snapshot)}
                    className="h-20 w-20 bg-red-500"
                  >
                    {characters.find(
                      (character) => character.id == getItemID(item.id)
                    )?.name ?? "alt"}
                  </div>
                )}
              </Draggable>
            </Fragment>
          ))}
        </div>
      )}
    </Droppable>
  );
}

Thanks

100terres commented 2 months ago

Could you provide a codesandbox demo.