@deepdub/react-arborist
Version:
53 lines (48 loc) • 1.49 kB
text/typescript
import { RefObject } from "react";
import { ConnectDropTarget, useDrop } from "react-dnd";
import { useTreeApi } from "../context";
import { NodeApi } from "../interfaces/node-api";
import { DragItem } from "../types/dnd";
import { computeDrop } from "./compute-drop";
import { actions as dnd } from "../state/dnd-slice";
export type DropResult = {
parentId: string | null;
index: number | null;
};
export function useDropHook(
el: RefObject<HTMLElement | null>,
node: NodeApi<any>
): ConnectDropTarget {
const tree = useTreeApi();
const [_, dropRef] = useDrop<DragItem, DropResult | null, void>(
() => ({
accept: "NODE",
canDrop: () => tree.canDrop(),
hover: (_item, m) => {
const offset = m.getClientOffset();
if (!el.current || !offset) return;
const { cursor, drop } = computeDrop({
element: el.current,
offset: offset,
indent: tree.indent,
hitAreaHeight: tree.props.rowHitAreaHeight,
disableReorder: tree.props.disableReorder,
node: node,
prevNode: node.prev,
nextNode: node.next,
});
if (drop) tree.dispatch(dnd.hovering(drop.parentId, drop.index));
if (m.canDrop()) {
if (cursor) tree.showCursor(cursor);
} else {
tree.hideCursor();
}
},
drop: (_, m) => {
if (!m.canDrop()) return null;
},
}),
[node, el.current, tree.props]
);
return dropRef;
}