I have this dustbin component that accepts some numbers. But after accepting numbers, I want to drag that box too rather than picking numbers from the left and right side of my window. Here's my current Dustbin.js code:
import { memo } from 'react';
import { useDrop } from 'react-dnd';
const style = {
height: '6rem',
width: '6rem',
marginRight: '5px',
padding: '1rem',
textAlign: 'center',
fontSize: '1rem',
lineHeight: 'normal',
};
export const Dustbin = memo(function Dustbin({ shouldAccept, accept, lastDroppedItem, onDrop, }) {
const [{ isOver, canDrop }, drop] = useDrop({
accept,
drop: onDrop,
collect: (monitor) => ({
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}),
});
const isActive = isOver && canDrop;
let backgroundColor = '#CBD5E1';
if (isActive) {
backgroundColor = 'darkgreen';
}
else if (canDrop) {
backgroundColor = 'darkkhaki'
}
return (<div ref={drop} className='flex justify-center items-center' role="Dustbin" style={{ ...style, backgroundColor }}>
{
lastDroppedItem && lastDroppedItem?.name == shouldAccept && `${shouldAccept}`}
</div>);
});
Here's a picture of what my application looks like right now.
To make ondrop components draggable, just put an ondrag next to ondrop like this:
const [{ isDragging }, drag] = useDrag({
type: 'box-drag',
item: () => {
return { number: YourBoxNumber };
},
collect: (monitor: any) => ({
isDragging: monitor.isDragging(),
}),
});
then update your useDrop to accept the dragging type box-type you may need to write another usedrop with the dragging type box-type for this.
const [{ handlerId }, drop] = useDrop({
accept: 'box-drag',
collect(monitor) {
return {
handlerId: monitor.getHandlerId(),
};
},
hover(item: { number }, monitor) {
// do something on hover
},
drop(item: { number }, monitor: DropTargetMonitor) {
// do something when another box dropped on it.
},
});
After all
drag(drop(ref))
ref is the ref for your box (currently your ref is drop, after it's dragging the name shall be updated either).