62 lines
1.7 KiB
JavaScript
62 lines
1.7 KiB
JavaScript
import { HTML5Backend } from 'react-dnd-html5-backend';
|
|
import { findDOMNode } from 'react-dom';
|
|
import { DragSource, DropTarget, DndContext } from 'react-dnd';
|
|
|
|
const cardSource = {
|
|
beginDrag(props) {
|
|
return {
|
|
id: props.key,
|
|
index: props.index,
|
|
prevIndex: props.index,
|
|
};
|
|
},
|
|
};
|
|
|
|
const cardTarget = {
|
|
// eslint-disable-next-line complexity
|
|
hover(props, monitor, component) {
|
|
const dragIndex = monitor.getItem().index;
|
|
const hoverIndex = props.index;
|
|
|
|
if (dragIndex === hoverIndex) {
|
|
return;
|
|
}
|
|
/* eslint-disable react/no-find-dom-node */
|
|
const hoverBoundingRect = findDOMNode(component).getBoundingClientRect();
|
|
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
|
|
const clientOffset = monitor.getClientOffset();
|
|
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
|
|
|
|
// Dragging downwards
|
|
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
|
|
return;
|
|
}
|
|
|
|
// Dragging upwards
|
|
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
|
|
return;
|
|
}
|
|
|
|
props.onDNDMove(dragIndex, hoverIndex);
|
|
monitor.getItem().index = hoverIndex;
|
|
},
|
|
|
|
drop(props, monitor) {
|
|
const dragIndex = monitor.getItem().prevIndex;
|
|
const dropIndex = props.index;
|
|
if (props.onDNDDrop) {
|
|
props.onDNDDrop(dragIndex, dropIndex);
|
|
}
|
|
},
|
|
};
|
|
|
|
export const DNDContext = DndContext(HTML5Backend);
|
|
|
|
export const DNDSource = name => DragSource(name, cardSource, (connect, monitor) => ({
|
|
connectDragSource: connect.dragSource(),
|
|
isDragging: monitor.isDragging(),
|
|
}));
|
|
|
|
export const DNDTarget = name => DropTarget(name, cardTarget, connect => ({
|
|
connectDropTarget: connect.dropTarget(),
|
|
}));
|