-
-
Notifications
You must be signed in to change notification settings - Fork 653
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add verticalSortableList collision detection strategy #805
base: master
Are you sure you want to change the base?
Conversation
|
I spent a few hours trying to understand the weird behavior we were expecting here until I finally found this issue. I can confirm that this collision strategy makes vertical lists that don't use drag overlay work properly. It would be really helpful to have this as a building collision strategy to avoid this boilerplate code everywhere. |
One thing to note is that it doesn't work with autoscrolling (scrolling the container while dragging). We have been using this code with the autoscrolling option turned off for a while now, and it's been working fine, so I think it's solid. |
You could copy the code in to your project and see if it fixes the problem? |
Thanks @ceddlyburge for your reply, May I ask how do I use |
Its surprisingly easy! Just copy all the code in this PR somewhere, and then pass the function in to the DndContext.
|
Awesome, thanks @ceddlyburge 👍 |
@ceddlyburge It works wonderfully! I really appreciate it ♥ BeforeAfter |
No worries, glad you like it :) |
@ceddlyburge dnd.bug.movimport { CollisionDetection, DroppableContainer } from '@dnd-kit/core';
import { sortBy } from 'lodash';
export const horizontalSortableListCollisionDetection: CollisionDetection = (
args
) => {
if (args.collisionRect.left < (args.active.rect.current?.initial?.left ?? 0)) {
return leftmostDroppableContainerMajorityCovered(args);
} else {
return rightmostDroppableContainerMajorityCovered(args);
}
};
const leftmostDroppableContainerMajorityCovered: CollisionDetection = ({
droppableContainers,
collisionRect,
}) => {
const ascendingDroppableContainers = sortBy(
droppableContainers,
(c) => c?.rect.current?.left
);
for (const droppableContainer of ascendingDroppableContainers) {
const {
rect: { current: droppableRect },
} = droppableContainer;
if (droppableRect) {
const coveredPercentage =
(droppableRect.left + droppableRect.width - collisionRect.left) /
droppableRect.width;
if (coveredPercentage > 0.5) {
return [collision(droppableContainer)];
}
}
}
return [collision(ascendingDroppableContainers[0])];
};
const rightmostDroppableContainerMajorityCovered: CollisionDetection = ({
droppableContainers,
collisionRect,
}) => {
const descendingDroppableContainers = sortBy(
droppableContainers,
(c) => c?.rect.current?.left
).reverse();
for (const droppableContainer of descendingDroppableContainers) {
const {
rect: { current: droppableRect },
} = droppableContainer;
if (droppableRect) {
const coveredPercentage =
(collisionRect.right - droppableRect.left) / droppableRect.width;
if (coveredPercentage > 0.5) {
return [collision(droppableContainer)];
}
}
}
return [collision(descendingDroppableContainers[0])];
};
const collision = (droppableContainer?: DroppableContainer) => {
return {
id: droppableContainer?.id ?? '',
value: droppableContainer,
};
}; |
Hi Baris, I'll take a look when I get some time. I can't remember all the details of this, but hopefully it will come back to me fairly quickly :) |
I am waiting for your return, thank you very much |
HI Baris, this looks like it should work to me, do you have some example code I can debug? |
Hi Cedd, I will prepare it quickly and share the link |
Hey Cedd, |
Ah great, glad to hear it! |
Yes of course! |
I've added |
Amazon work @ceddlyburge 👍 @clauderic could this be merged? or is it gonna have some potential conflict with your planned refactoring mentioned [here] ?(#1194 (comment)) |
Fixes #804
Probably this will want a little demo or something added, if you are happy with it, maybe in Stories?