Bug...?
When dragging an item without a drag handle, dragging over other items in the list does not trigger their hover effects. I would expect the same to be the case when using a drag handle.
When I'm dragging an item with a drag handle over other items in the list, the hover effect of those other items gets triggered.
Drag an item by the drag handle over other items.
React are you using?16.6.3
react-beautiful-dnd are you running?10.0.2
Firefox 63.0.3
https://codesandbox.io/s/wnylqopyl
Drag handles in the given example only show up on Item hover. Adding to the observed behaviour above, the handle of the dragged item also disappears on drag, which I would expect not to happen.
@artooras I was seeing this too with the same setup. I am able to remove those hover events while dragging by adding
const style = snapshot.isDraggingOver ? {
"pointer-events": "none"
} : {};
to the droppable. I found that tip mentioned in the (phase: dragging): Droppable element docs.
Excellent, this did indeed solve the problem. Thank you! The only remaining issue is that the drag handle of the dragged item hides on drag. Any ideas how to fix this?
I have seen this before also. I am on the search for a general solution. The trouble with pointer-events: none is that it will stop users being able to scroll scroll containers with their mouse wheel. Not a huge deal as we have auto scrolling, but it is why I have not applied it generically.
I am thinking of applying pointer-events: none to all Draggables during a drag. Currently it is only applied to drag handles. However, this would not stop hover effects on other elements
@artooras The way I keep the drag handle visible while dragging is to pass in the snapshot to whatever function is building up the <Draggable ... /> such that I can ask for snapshot.isDragging. That way I can conditionally render some class that will have the appropriate visibility: hidden; or visible, in this case .show-drag-handle.
renderRow(provided, snapshot) {
const classNames = {
"show-drag-handle": this.state.isHovered || snapshot.isDragging
};
return (
<div className={classNames} .../>
);
}
...
render() {
return (
<Draggable ... >
{(provided, snapshot) => this.renderRow(provided, snapshot)}
</Draggable/>
);
}
I'm not familiar enough with the styled-components lib to provide an example with my earlier fork, but I hope this makes sense. I'd love to hear alternatives to this solution though if there's something built-in that I'm missing.
I should mention that whatever element is building up the row needs to have a couple event listeners for the hover event. Something like:
const handleMouseOver = () => {
this.setState({ isHovered: true });
};
const handleMouseOut = () => {
this.setState({ isHovered: false });
};
In my example above, for example, these would need to be bound on the div.
Another approach for now.
Have a class on body such as is-dragging when dragging and is-not-dragging when there is no drag. Then only apply the hover styles when is-not-dragging.
.is-not-dragging .target:hover {
color: red;
}
OK, I managed to keep displaying the handle on drag by using the snapshot.isDraggable of the Draggable:
<Draggable
index={index}
draggableId={id}
>
{(draggable, snapshot) =>
...
<DragHandle
isDragging={snapshot.isDragging}
{...draggable.dragHandleProps}
/>
}
</Draggable>
and display the DragHandle when dragging:
const DragHandle = styled(({isDragging, ...props}) => <Icon {...props} />)`
cursor: move;
visibility: ${props => !props.isDragging && 'hidden'};
color: ${props => props.isDragging ? props.theme.color : props.theme.colorGrayLight};
&:hover {
color: ${props => props.theme.color};
}
${ParentComponent}:hover & {
visibility: visible;
}
`
The issue still remains when I move items between columns.
So this solution by @masonnl works only on the current column.
const style = snapshot.isDraggingOver ? {
"pointer-events": "none"
} : {};
I guess that storing isDragging state globally for other columns is a way to go.
Can anybody help with a more simple solution?
Most helpful comment
@artooras I was seeing this too with the same setup. I am able to remove those hover events while dragging by adding
to the droppable. I found that tip mentioned in the (phase: dragging): Droppable element docs.
Demo
https://codesandbox.io/s/n9zm6m5j9p