Skip to content

Instantly share code, notes, and snippets.

@pferreirafabricio
Created September 4, 2023 13:13
Show Gist options
  • Save pferreirafabricio/d8a9d46181e5a9a155ac174ef00b2653 to your computer and use it in GitHub Desktop.
Save pferreirafabricio/d8a9d46181e5a9a155ac174ef00b2653 to your computer and use it in GitHub Desktop.
🤚 A React Hook to make an HTML element (e.g. a table, list, div with large text) scrollable with the mouse
import { useEffect, useState } from 'react';
export function useScrollByDrag({
elementToScroll,
scrollVelocity = 1,
}: {
elementToScroll: HTMLElement | null;
scrollVelocity?: number;
}) {
useEffect(() => {
if (!elementToScroll) return;
let startX = 0;
let scrollLeft = 0;
let isDown = false;
const onMouseDown = (event: MouseEvent) => {
isDown = true;
elementToScroll.style.cursor = 'grabbing';
startX = event.pageX - elementToScroll.offsetLeft;
scrollLeft = elementToScroll.scrollLeft;
};
const onMouseLeave = () => {
isDown = false;
elementToScroll.style.cursor = 'default';
};
const onMouseUp = () => {
isDown = false;
elementToScroll.style.cursor = 'default';
};
const onMouseMove = (event: MouseEvent) => {
if (!isDown) return;
event.preventDefault();
elementToScroll.style.cursor = 'grabbing';
const x = event.pageX - elementToScroll.offsetLeft;
const walk = (x - startX) * scrollVelocity;
elementToScroll.scrollLeft = scrollLeft - walk;
};
elementToScroll.addEventListener('mousedown', onMouseDown);
elementToScroll.addEventListener('mouseleave', onMouseLeave);
elementToScroll.addEventListener('mouseup', onMouseUp);
elementToScroll.addEventListener('mousemove', onMouseMove);
return () => {
elementToScroll.removeEventListener('mousedown', onMouseDown);
elementToScroll.removeEventListener('mouseleave', onMouseLeave);
elementToScroll.removeEventListener('mouseup', onMouseUp);
elementToScroll.removeEventListener('mousemove', onMouseMove);
};
}, [scrollVelocity, elementToScroll]);
}
@pferreirafabricio
Copy link
Author

pferreirafabricio commented Sep 4, 2023

Usage:

useScrollByDrag({
  elementToScroll: document.querySelector('.class-to-your-element') as HTMLElement
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment