npm install @codecks/dnd
Working with all kinds of dnd approaches for Codecks, it became clear that native html-based drag and drop is still a big pain.
This library is inspired by react-beautiful-dnd but does things differently:
- only offering primitives, (i.e. no built-in reordering, no good accessibility story yet, PRs very welcome!). Thus, it's relatively small (< 7kb gzipped)
- only using Portals for dragged elements (to make a transition to virtualized lists more straight forward)
The library is meant as a substitute for the html-based drag and drop functionality offered via a fairly minimal react-based api.
import {DragController, Draggable} from "@codecks/dnd"
<DragController type="box" renderItem={({id}) => <Box id={id} />}>
<div>
{boxes.map((id) => (
<Draggable key={id} type="box" id={id} itemData={{id, myProp: true}}>
{({handlers, ref}) => <Box {...handlers} ref={ref} id={id} />}
</Draggable>
))}
</div>
</DragController>
renderItem
is used for rendering the dragged item in a portal, so it's compatible with windowing-based lists.
It's using the render props pattern for the child so it can replace the content with a placeholder while dragging.
const DropZone = ({width = 200}) => {
const {isOver, dragItem, ref} = useDropZone({
type: "box",
onDragOver: ({item, position}) => console.log("drag"),
onDrop: ({item, position}) => console.log("drop!"),
});
return <div ref={ref}>Drop Here!</div>;
};
onDragOver's
position will be null when the dragItem leaves the drop zone.
-
My dragged item doesn't appear when dragging!?
First, make sure that the DragController is setup correctly with the correct
type
. Also therenderItem
should not be wrapped with theDraggable
component.
- add pointer-events: none to everything (i.e. body) while dragging (to avoid hover effects, etc)
- drag file support?
Licensed under MIT