Adding an AutoScroll with react-dnd
Add auto scroll behaviour in react-dnd
Add auto scroll behaviour in react-dnd
Recently, when I was working on a drag and drop feature, I stumble upon an issue whereby react-dnd itself doesn’t cater auto scroll behavior by default if the content length is beneath the visible view.
I got stumped at first as I have never encounter this type of issue due to lack of experience. After searching thru and using AI-tools, I found an answer that was pretty suitable for general cases.
The code snippet is as below:
const AutoScroller = () => {
const { isDragging, pointer } = useDragLayer((monitor) => ({
isDragging: monitor.isDragging(),
pointer: monitor.getClientOffset(),
}));
const pointerRef = useRef(pointer);
useEffect(() => {
pointerRef.current = pointer;
}, [pointer]);
useEffect(() => {
if (!isDragging) return;
let animationFrameId: number;
const scrollContainer = document.querySelector('.<CONTAINER_CLASSNAME>');
const tick = () => {
if (!scrollContainer || !pointerRef.current) {
animationFrameId = requestAnimationFrame(tick);
return;
}
const { top, bottom } = scrollContainer.getBoundingClientRect();
const { y } = pointerRef.current;
const threshold = 150; // boundary to trigger scrolling
const maxSpeed = 20; // max speed of scrolling
if (y < top + threshold) {
const intensity = (top + threshold - y) / threshold;
scrollContainer.scrollTop -= maxSpeed * intensity;
} else if (y > bottom - threshold) {
const intensity = (y - (bottom - threshold)) / threshold;
scrollContainer.scrollTop += maxSpeed * intensity;
}
animationFrameId = requestAnimationFrame(tick);
};
tick();
return () => cancelAnimationFrame(animationFrameId);
}, [isDragging]);
return null;
};In order to use it, one must insert it as an element within the <DndProvider> from react-dnd. Examples as below:
<DndProvider backend={HTML5Backend}>
<AutoScroller />
...
</DndProvider>Hope it helps!