components icon indicating copy to clipboard operation
components copied to clipboard

bug(CdkDrag): Drag preview doesn't work well with sticky elements and scrolling

Open br-kwon opened this issue 3 years ago • 3 comments
trafficstars

Is this a regression?

  • [ ] Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

if the cdkDrag directive is applied on an element inside a container with position: sticky, scrolling will reposition the drag preview element. this is especially undesired for configurations such as [cdkDropListLockAxis]="'x'" and [cdkDropListOrientation]="'horizontal'"

Reproduction

https://stackblitz.com/edit/components-issue-rtfk83?file=src/app/example-component.html

Steps to reproduce:

  1. hold mouse down on element that contains "foo"
  2. drag a little bit, then scroll vertically while holding the drag
  3. should see the drag preview reposition even though "lock axis" is configured

Expected Behavior

should not reposition vertically

Actual Behavior

repositions vertically

Environment

  • Angular: 13.3.0
  • CDK/Material: 13.3.0
  • Browser(s): Chrome
  • Operating System (e.g. Windows, macOS, Ubuntu): macOS

br-kwon avatar Jul 14 '22 19:07 br-kwon

I spent a bit of time investigating this and I think it comes down to the fact that we make a lot of assumptions that the ClientRect of the various draggable events is going to change whenever the page scrolls, but that's not the case when they're sticky. This will be tricky to fix, because these assumptions have been made in a ton of places in the drag-drop module. Basically everywhere where we adjust the client rects manually (e.g. each call to adjustClientRect) will have to turn into another getBoundingClientRect call. It was done this way to improve performance, but we may want to re-evaluate, because this has caused other bugs in the past.

As for your case, you may be able to work around it by using cdkDragConstrainPosition instead of cdkDragLockAxis which allows you to tell the drag-drop module where the element should be positioned.

crisbeto avatar Jul 17 '22 09:07 crisbeto

thanks for investigating @crisbeto ! sounds tricky indeed. i tried cdkDragConstrainPosition which works ok, but seems i can shift the drag preview vertically a bit if i drag upwards or downwards fast enough (this is when i keep the y static in the return Point). not a huge deal, but definitely seems like a UX downgrade compared to cdkDropListLockAxis. we're gonna keep using cdkDropListLockAxis with a workaround where we place the directive higher up on the DOM tree where position is not sticky - we sacrifice the "auto scroll" feature though since this element is outside the scroll container.

do you think this issue will be prioritized as a fix?

br-kwon avatar Jul 20 '22 00:07 br-kwon

I can't say when the fix will be prioritized since we already have a bunch of commitments on our roadmap.

crisbeto avatar Jul 20 '22 10:07 crisbeto

I have the same issue and I looking further for a fix

pawelofieldly avatar Jul 12 '23 13:07 pawelofieldly