Search code examples
cssreactjsdrag-and-dropuser-experiencednd-kit

Maintain row position during drag n drop when other rows collapsed


I have a draggable/sortable list of accordion items (or expandable rows) and I'm collapsing all of them during drag n drop to make it easier for the user to see what they're doing.

If I do this only for the selected row, or if only rows below the selected one are expanded, then everything works just fine, but if there are any expanded rows above the selected row, then the selected row jumps up and that's obviously not a good user experience.

Codesandbox: https://codesandbox.io/p/devbox/dnd-expand-scroll-x5nt7n

The problem: Collapse all elements while dragging

I've tried to look into dnd-kit documentation and configuration options to see if maybe there's a way to solve this, but I couldn't find anything. Maybe I could find some magical tricks in the dnd-kit source code but I don't have the time or the skills to do that...

I experimented a bit and found one potential solution that could work, which is basically to move the collapsed accordions (above the selected row) closer to the mouse by adding the right amount of padding on top thus keeping the buttons in place:

enter image description here

To test the hacky solution I came up with, uncomment the following line in DraggableItem.tsx:

paddingTop: hideContent && index === 0 ? "168px" : undefined,

Note: only works with items 1 & 2 expanded.

Am I heading in the right direction at all here? I feel like there has to be an easier and more proper way to do this.

I actually moreso feel like maybe this shouldn't be done at all... perhaps it's better UX to only hide the contents of the row that is being dragged? I could also just disable drag n drop if any rows are expanded but I don't think that's good UX and disabling anything is usually bad for accessibility.

Thank you!


Solution

  • We decided not to collapse the rest of the rows/accordions during dnd since it's unlikely to be an issue to users, but I'll post the workaround that I came up with in-case anyone else is interested:

    https://codesandbox.io/p/devbox/dnd-expand-scroll-forked-hx7r2x

    The only reliable solution that I could come up with is to sum up the heights of all the expanded rows' "subcomponents" and use that as top padding for the whole list, resulting in the buttons remaining in place. If anyone has a better solution feel free to post it and I'll mark the best, least-hacky solution to this problem.