Open adriantrunzo opened 2 years ago
Hey @adriantrunzo,
Thanks for the detailed report. Originally the idea behind canceling dragging on window resize was to get around some limitations with @dnd-kit at the time.
There's still a couple of limitations at the moment that would prevent this from working well even if you removed the cancel on resize handler in AbstractPointerSensor
, but we should definitely fix this.
It's not acceptable that @dnd-kit no longer works on iOS 15 Safari, so this is definitely going to be high priority to fix.
The main thing that needs to be done for this to work properly is to update the measurements of the scrollable ancestor bounding rectangles when they resize.
@clauderic I wonder we have any workaround for this case?
Not only in Safari, but also on mobile Chrome too. Dragging is cancelling when I start drag item with keyboard open, because keyboard hiding when input loses focus and window resize happen.
The main thing that needs to be done for this to work properly is to update the measurements of the scrollable ancestor bounding rectangles when they resize.
Hi @clauderic, I will have time to work on this issue in the next several weeks. If you are able to point out where in the code those measurements are, I'd be happy to take a look. Thanks!
@clauderic I wonder we have any workaround for this case?
@ducan-ne The workaround I described above is to make sure that the HTML <body>
does not scroll. The body scrolling is what triggers the mobile browser UI to collapse and expand. In other words, apply some style rules like overflow: hidden; height: 100vh; width: 100vw;
to the body element and put your content in a child element that is scrollable. Take a look at the dnd-kit Storybook examples to see an example of this kind of page styling:
Obviously, this workaround is not feasible in all cases. It will also not fix the keyboard hiding trigger that @muerwre pointed out.
Is there any quick fix for this?
Assuming the draggable element is an input or textarea not expected to work even after the keyboard is evoked.
In ios you may need to use window.visualViewport
to get the size of the window and listen for window changes.
Hi 👋 ,
This issue was tricky to track down, so I hope that my explanation here is clear!
The Problem
On iOS 15, Safari hides and shows the browsing tools (location bar, back button, bookmark button, etc) when the page is scrolled up or down, respectively. Showing and hiding the browsing tools appropriately triggers a window resize event. That resize event causes the dragging operation to be cancelled. Before I learned that the resize event was being fired and found that line of code, the behavior was unexpected and seemed very odd, because if the screen had been scrolled just right and I wasn't dragging over a large distance, I didn't notice the issue.
The issue is not present on iOS 14 and earlier.
How to Reproduce
Here's a codesandbox that exhibits the issue: https://codesandbox.io/s/resize-interrupts-ios-15-dnd-kit-wp5d8k. This example is a simple adaptation of the Sortable Stories and very similar to the code in the private repository where I encountered the issue.
Note that how you view the example makes a difference (beyond the fact that you must be on iOS 15). This difference also explains why this behavior is not visible in the Stories.
If you are viewing the example in the default codesandbox view, with the codesandbox interface elements, you will not see the issue. The reason is that the page is not scrollable, just the content section where the dnd-kit elements are. In other words, the HTML body (or root element) has styling like
overflow: hidden; height: 100vh; width: 100vw;
and never scrolls. Notice how the Safari location bar never disappears:https://user-images.githubusercontent.com/1218900/160944223-0091f2bf-d3b9-4b40-a18d-cb452e0a9a88.mov
If you then view the example in a new window, without the codesandbox interface elements, you will encounter the issue. Now the page can scroll and the browser default behavior of showing and hiding the browsing tools comes into effect:
https://user-images.githubusercontent.com/1218900/160944477-cae01126-b2bd-4555-a6f9-5d864637f1a9.mov
Discussion
I am sure there is a good reason to cancel the drag on window resize in some cases, but as shown above it leads to unexpected behavior on iOS 15. One workaround is to update our app to make the page not scrollable using styling like that above. However, that workaround requires a change that affects the entire app and we'd have to accept that the location bar will always be taking up vertical space in our mobile view.
Is the cancel-on-resize handler currently in
AbstractPointerSensor
needed in all cases? Perhaps the drag operation doesn't need to be cancelled if the resize is only vertical?If there is no reasonable, short-term solution to this issue, I suggest updating the documentation to outline that the drag-and-drop elements must be within a page that does not scroll on mobile. An inner container that contains those elements is the one that should scroll.
Thanks for reading and for sharing this great library!