react-spectrum
react-spectrum copied to clipboard
Drag and drop bug fixes
This fixes a few bugs found while writing drag and drop docs:
- When starting a drag with the keyboard, the nearest drop target (positionally) is focused by default rather than the first one on the page.
- When pressing a modifier key while dragging to change the drop operation, the cursor sometimes did not update correctly. Also, if
getDropOperation
returns an operation that isn't allowed, the drag is now canceled. - Drop target state would sometimes get stuck because of the logic with counting the number of times onDragEnter and onDragLeave are called. Instead, we now use
relatedTarget
to determine if we're in a nested target, similar to howuseFocusWithin
is implemented. - Moved
getDropOperationForPoint
into aDragTargetDelegate
interface to make it reusable, and implemented aListDragTargetDelegate
. This uses the DOM for layout. A separate implementation is also provided inListLayout
for virtualizer uses. Also removes a hard coded condition in ListView for specific folder dnd behavior, and behaves better when only certain drop positions are supported. - Added some states to the return types of hooks.
Build successful! 🎉
I'm having trouble in Chrome with the reoder story, indicator gets stuck and won't move down in the list.
https://reactspectrum.blob.core.windows.net/reactspectrum/893c40ba2e4a05e87d6384776f8c28dda7cadd7a/storybook/index.html?path=/story/listview-drag-and-drop--drag-within-list-reorder&providerSwitcher-toastPosition=bottom
Build successful! 🎉
@snowystinger that should be handled here: https://github.com/adobe/react-spectrum/pull/3391/files#diff-f9405406c2dc605226f231a1af6ab2a05f64a6c2f83ab9eaf3f2b8c7dd8b7ae2R413-R418. It filters out any out of view items.
Build successful! 🎉
@reidbarber I see it too in Safari, i can get drop indicators to get stuck in the visible state, and they flicker a lot
I can get the indicator stuck visible in chrome as well if I drag from left of the row checkbox on the second list directly off to the left. It doesn't flicker in chrome though.
That was due to relatedTarget
always being null in Safari: https://bugs.webkit.org/show_bug.cgi?id=66547.
But in Chrome, the dragleave event sometimes never fires for some elements. I tracked this to the drag indicators, which get removed from the DOM before dragleave fires. So I came up with the workaround above, which tracks the entered elements in a set and removes the ones that are no longer in the DOM on dragleave.
Build successful! 🎉