dnd-kit icon indicating copy to clipboard operation
dnd-kit copied to clipboard

Variable Height Sortable - unable to pull some items all the way down

Open rob-gordon opened this issue 2 years ago • 2 comments

I implemented a variable height sortable, but something about the way it's observing intersections is preventing me from dragging larger items below smaller ones in my list. Is there anything in the library that can solve something like this?

https://github.com/clauderic/dnd-kit/assets/159949/29f618ee-08b1-489d-84fa-19b8f42f7d15

Current code:

<DndContext
  modifiers={[restrictToVerticalAxis, restrictToParentElement]}
  onDragEnd={({ over, active }) => {
    if (active.id && over?.id) {
      const fromId = active.id;
      const toId = over.id;
      if (typeof fromId === "string" && typeof toId === "string")
        moveFeature(fromId, toId);
    }
  }}
>
  <SortableContext
    items={tasks}
    strategy={verticalListSortingStrategy}
  >
    <div className="grid gap-1 py-1">
      {tasks.map((task) => (
        <TaskRow key={task.id} {...task} />
      ))}
    </div>
  </SortableContext>
</DndContext>

export function TaskRow(task: Feature) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
    setActivatorNodeRef,
  } = useSortable({ id: task.id });

  const style = {
    transform: CSS.Translate.toString(transform),
    transition,
    zIndex: isDragging ? 1 : undefined,
    position: isDragging ? ("relative" as const) : undefined,
    height,
  };

  return (
    <div ref={setNodeRef} style={style} data-is-dragging={isDragging}>
      <div
        className={classNames(
          classNames(
            ROW_HEIGHT,
            "grid grid-cols-[24px_minmax(0,1fr)_62px_44px]"
          )
        )}
      >
        <button
          className={classNames(
            ROW_HEIGHT,
            "group cursor-move w-6 flex items-center justify-end outline-none touch-none"
          )}
          ref={setActivatorNodeRef}
          {...attributes}
          {...listeners}
        >
          <GripVertical className="w-4 h-4 opacity-20" />
        </button>
        {/** ... */}
    </div>
  );
}

rob-gordon avatar Sep 08 '23 16:09 rob-gordon

use the DnDContext prop named collisionDetection, try to set closestCenter, im almost sure it will help you. doc: https://docs.dndkit.com/api-documentation/context-provider/collision-detection-algorithms

williamisnotdefined avatar Dec 21 '24 03:12 williamisnotdefined

I'm having the same issue as above. I've tried all the collision detections available, but all of them have issues when it comes to variable height elements. I'm also seeing big issues with keyboard navigation.

Without having looked at the source code for dnd-kit I suspect it has something to do with using a handle (although i have not confirmed this), and the context treating the handle (setActivatorNodeRef) as the "source of truth" as to where the element is on screen, instead of using the actual element (setNodeRef)

This video was recorded with the closestCenter detection model.

Transcript:

  • First is using the keyboard, resulting in lines overlaying
  • Second is demonstrating the same issue as OP

https://github.com/user-attachments/assets/3f14eb40-7187-41c1-b92f-c855bf4d6acc

bekworks avatar Mar 05 '25 10:03 bekworks