Here is my scenario:
- I have a list of items, where the user is able to swap their positions by dragging one over another.
- I’m trying to dynamically add styling to the dragged over item, which would be removed upon either leaving the item or end of dragging.
The two problems I’m facing:
- onDragLeave is firing when I’m dragging over children of dragged over item, rather than only when dragging out of its’ boundary.
- onDragLeave does not fire upon swapping, leaving the previously dragged over item with the ‘draggedOver’ styling until removed again via above situation. And I cannot use onDragEnd, since it’s referring to the dragged item.
How would it be best to go about fixing those issues?
Here’s the relevant code. Do keep in mind that I removed my code attempt to implement this feature, so it is at a ‘clean’ state.
Item:
function Issue({ issue, index, type }) {
const { draggedIssue, dragOverIssue, draggedList, dragOverList } = useDrag();
const dispatch = useDispatch();
const createdDaysAgo = subtractDays(
new Date().toISOString(),
issue.created_at
);
function handleDragEnd() {
dispatch(dropIssue(draggedIssue, dragOverIssue, draggedList, dragOverList));
}
return (
<div
className="text-dark border border-2 border-dark rounded bg-light p-3"
style={{ cursor: "grab" }}
draggable
onDragStart={() => {
draggedIssue.current = index;
draggedList.current = type;
}}
onDragEnter={() => (dragOverIssue.current = index)}
onDragEnd={handleDragEnd}
>
<h4 style={{ fontSize: "18px" }}>{issue.title}</h4>
<p className="text-secondary d-flex gap-4">
<span>#{issue.id}</span>
<span>
opened {createdDaysAgo > 0 ? `${createdDaysAgo} days ago` : "today"}
</span>
</p>
<p className="text-secondary d-flex gap-3">
<span>{issue.user}</span>|<span>Comments: {issue.comments}</span>
</p>
</div>
);
}
export default Issue;
As for useDrag, it’s simply a context that provides refs storing indexes of the two items in question. Used to do the swapping, but perhaps it can be useful here?
For the first issue, I tried using ref to the dragged over item, and upon onDragLeave, return if it’s leaving itself, but in that case I have no way of differentiating if it’s leaving towards children or out of boundaries.