I am using React-dnd, and trying to create a table with sortable rows, which can only be dragged from a handle, which is a small span on the right hand side.
The example they give here https://react-dnd.github.io/react-dnd/examples/customize/handles-and-previews
does not show any sorting. I can get the Handle to work, with a different preview, the problem is if I use the code they provide, the dropzone for sorting the table only works when I hover it directly over the span, not over the row like it should.
my code:
const dragRef = useRef<any>(null)
const [{ isDragging }, drag, preview] = useDrag({
type: DragTypeEnum.ENTRY,
item: () => {
return { id: props.id, index: props.sequence }
},
collect: (monitor: any) => ({
isDragging: monitor.isDragging(),
}),
});
const [{ handlerId }, drop] = useDrop({
accept: DragTypeEnum.ENTRY,
collect(monitor) {
return {
handlerId: monitor.getHandlerId(),
}
},
hover(item: DragItem, monitor: DropTargetMonitor) {
if (!dragRef.current) {
return
}
const dragId = item.id
const hoverId = props.id;
// Don't replace items with themselves
if (dragId === hoverId) {
return
}
// Determine rectangle on screen
const hoverBoundingRect = dragRef.current?.getBoundingClientRect()
// Get vertical middle
const hoverMiddleY =
(hoverBoundingRect.bottom - hoverBoundingRect.top) / 2
// Determine mouse position
const clientOffset = monitor.getClientOffset()
// Get pixels to the top
const hoverClientY = (clientOffset as XYCoord).y - hoverBoundingRect.top
// Only perform the move when the mouse has crossed half of the items height
// When dragging downwards, only move when the cursor is below 50%
// When dragging upwards, only move when the cursor is above 50%
// Dragging downwards
if (dragId < hoverId && hoverClientY < hoverMiddleY) {
console.log("downwards");
return
}
// Dragging upwards
if (dragId > hoverId && hoverClientY > hoverMiddleY) {
console.log("upwards");
return
}
// Time to actually perform the action
props.moveEntry(dragId, hoverId) //ONLY FIRING WHEN I GO OVER THE HANDLE :(
// Note: we're mutating the monitor item here!
// Generally it's better to avoid mutations,
// but it's good here for the sake of performance
// to avoid expensive index searches.
item.id = hoverId
},
});
const opacity = isDragging ? 0 : 1;
drag(drop(dragRef))
And the table tsx is:
<tr
style={{ opacity }}
data-handler-id={handlerId}
ref={preview} //THIS SHOULD BE THE PREVIEW HTML AND ALSO WHERE I CAN DRAG INTO
>
<td>
//emptied for demo purpose
</td>
<td>
//emptied for demo purpose
</td>
<td>
<span ref={dragRef}> // THIS IS MY DRAG HANDLE
<FontAwesomeIcon
icon="bars"
className="pointer"
></FontAwesomeIcon>
</span>
</>
}
</td>
</tr>