components
components copied to clipboard
bug(CdkDrag): Drag preview doesn't work well with sticky elements and scrolling
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:
- hold mouse down on element that contains "foo"
- drag a little bit, then scroll vertically while holding the drag
- 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
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.
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?
I can't say when the fix will be prioritized since we already have a bunch of commitments on our roadmap.
I have the same issue and I looking further for a fix