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

Scroll position jumps after auto scrolling during drag and drop

Open shawnshuang opened this issue 2 years ago • 17 comments

Description

I’m running into an issue where the scroll position jumps after I auto scroll while dragging and dropping an element. I’m also not sure if this issue is coming from how I’m using dnd-kit or react-virtuoso (the virtual list library that I’m using), so I’m creating GitHub issues in both repos.

The issue seems to occur sporadically. It occurs only if there’s auto scrolling during drag and drop. And it occurs only if the auto scrolling is done downwards.

Do you think this issue is coming from how I’m using dnd-kit? If so, would you have any suggestions on how I can get rid of the scroll jump?

CodeSandbox

Here is a simplified CodeSandbox that reproduces the issue. (Excuse the comments; they’re for explaining parts of dnd-kit to the author of react-virtuoso.)

Video

Below is a video that illustrates the issue. You can see that the elements are dropped in the correct order in the list, but the scroll position shifts when the element is dropped, which is disorientating.

https://user-images.githubusercontent.com/7409323/178077335-fd97f79d-9671-46aa-9374-23c9f341f092.mov

shawnshuang avatar Jul 08 '22 22:07 shawnshuang

Also seeing this issue, exactly as described.

sjc5 avatar Jan 23 '23 03:01 sjc5

Confirming this happens with react-window, simply by having the rows draggable (no droppables, no sort manager). I noticed that the jumps always land on the initial scroll position when the drag has started, as if there's some 'reset'.

chkp-michaelo avatar Jan 26 '23 17:01 chkp-michaelo

Also confirming I see this behavior with react-window.

@MichaelOstrovsky or @shawnshuang - Any luck finding a workaround?

LeviRemi avatar Mar 07 '23 23:03 LeviRemi

As a temporary workaround, can you try setting the layoutShiftCompensation option of the autoScroll prop to false?

Something like:

<DndContext autoScroll={{layoutShiftCompensation: false}}>

clauderic avatar Mar 07 '23 23:03 clauderic

Major thanks, @clauderic! That completely eliminated the jumping on drag-and-scroll. I was not aware this was even an option. Are all of the autoScroll customizations documented somewhere?

LeviRemi avatar Mar 07 '23 23:03 LeviRemi

@clauderic Before I forget.. another question for autoScroll options:

Is there any way to completely eliminate horizontal auto-scroll?

LeviRemi avatar Mar 07 '23 23:03 LeviRemi

Is there any way to completely eliminate horizontal auto-scroll?

<DndContext autoScroll={{ threshold: { x: 0, y: 0.2 } }} >

Are all of the autoScroll customizations documented somewhere

The autoScroll config is a bit experimental so is only documented via the type definitions: https://github.com/clauderic/dnd-kit/blob/master/packages/core/src/hooks/utilities/useAutoScroller.ts#L15-L32

clauderic avatar Mar 08 '23 02:03 clauderic

@clauderic Thanks for taking the time to respond! Unfortunately, I'm still seeing the issue. I updated the code in my sandbox with the layoutShiftCompensation option if you'd like to see for yourself. I'm not sure if it would have done anything, but I also made sure to update @dnd-kit/core in the sandbox from 6.0.2 to 6.0.8 and @dnd-kit/sortable from 7.0.0 to 7.0.2.

I'm not sure if the issue that I'm seeing has to do with the virtualization library that I'm using, react-virtuoso. It seems the option resolved the issue for @LeviRemi, who was using react-window.

@MichaelOstrovsky I see that you're also using react-window; I would love to know if the layoutShiftCompensation option ends up resolving the issue for you!

shawnshuang avatar Mar 08 '23 22:03 shawnshuang

I was seeing something similar on horizontal autoScroll and when I set acceleration: 1 it helped a ton.

<DndContext autoScroll={{ acceleration: 1 }}>

gudlyf avatar Jul 11 '23 23:07 gudlyf

https://github.com/inokawa/virtua may help because it suports similar usecases to react-virtuoso and it works well with dnd-kit.

https://inokawa.github.io/virtua/?path=/story/advanced-with-dnd-kit--default https://github.com/inokawa/virtua/blob/main/stories/react/advanced/With%20dnd-kit.stories.tsx

inokawa avatar Oct 22 '23 12:10 inokawa

Is there another solution to this? I'm using https://github.com/TanStack/virtual, layoutShiftCompensation workaround did not work for me.

My hacky solution: I have resorted to patching the package, adding a new shouldScrollIntoView boolean prop (default: true) to DragOverlay, passing that prop to useDropAnimation, and only running the scrollIntoViewIfNeeded function if the boolean is true. When I don't want the scrolling to happen, I set the shouldScrollIntoView prop of DragOverlay to false.

There must be a better way...

moxxuk avatar Dec 13 '23 10:12 moxxuk

Hi @clauderic, I've implemented react-dnd-kit, and it's working fine for both vertical and horizontal auto-scrolling. However, when I have multiple columns (e.g., 4 columns per row, then the next 4 in the second row) and one column has more than 100 items, sometimes when dragging an item, the auto-scrolling gets stuck for a few milliseconds, causing lagging and not flexing properly. Could you please share a solution for this?"

subratre avatar Feb 09 '24 13:02 subratre

I'm also facing the same issue. setting layoutShiftCompensation to false is not helping. I am not using react-virtuoso.

niranjan821 avatar Mar 26 '24 08:03 niranjan821

I was seeing something similar on horizontal autoScroll and when I set acceleration: 1 it helped a ton.

<DndContext autoScroll={{ acceleration: 1 }}>

My problem is similar, when doing validations inside my "Droppable" component I used overflow-y-scroll and it generated the same error on my scroll x, I used a "useEffect" with the isOver variable of the useDroppable so that when the element lands in the container, overflow-y-scroll will be hidden

 useEffect(() => {
        isOver
            ? setClassNameContent("")
            : setClassNameContent("overflow-y-scroll");
    }, [isOver]);

odin0v avatar Apr 05 '24 11:04 odin0v

@shawnshuang, @clauderic

In my case it works with: autoScroll={{ layoutShiftCompensation: false, enable: false }}

sarten8 avatar May 02 '24 18:05 sarten8