use-draggable-scroll
Version:
React hook to add draggability to scrollable content easily
68 lines (55 loc) • 2.39 kB
JavaScript
function useDraggableScroll(ref, options) {
if (options === void 0) {
options = {
direction: 'both'
};
}
if (process.env.NODE_ENV === 'development') {
if (typeof ref !== 'object' || typeof ref.current === 'undefined') {
console.error('`useDraggableScroll` expects a single ref argument.');
}
}
var _options = options,
direction = _options.direction; // The initial position (scroll progress and mouse location) when the mouse is pressed down on the element
var initialPosition = {
scrollTop: 0,
scrollLeft: 0,
mouseX: 0,
mouseY: 0
};
var mouseMoveHandler = function mouseMoveHandler(event) {
if (ref.current) {
// Calculate differences to see how far the user has moved
var dx = event.clientX - initialPosition.mouseX;
var dy = event.clientY - initialPosition.mouseY; // Scroll the element according to those differences
if (direction !== 'horizontal') ref.current.scrollTop = initialPosition.scrollTop - dy;
if (direction !== 'vertical') ref.current.scrollLeft = initialPosition.scrollLeft - dx;
}
};
var mouseUpHandler = function mouseUpHandler() {
// Return to cursor: grab after the user is no longer pressing
if (ref.current) ref.current.style.cursor = 'grab'; // Remove the event listeners since it is not necessary to track the mouse position anymore
document.removeEventListener('mousemove', mouseMoveHandler);
document.removeEventListener('mouseup', mouseUpHandler);
};
var onMouseDown = function onMouseDown(event) {
if (ref.current) {
// Save the position at the moment the user presses down
initialPosition = {
scrollLeft: ref.current.scrollLeft,
scrollTop: ref.current.scrollTop,
mouseX: event.clientX,
mouseY: event.clientY
}; // Show a cursor: grabbing style and set user-select: none to avoid highlighting text while dragging
ref.current.style.cursor = 'grabbing';
ref.current.style.userSelect = 'none'; // Add the event listeners that will track the mouse position for the rest of the interaction
document.addEventListener('mousemove', mouseMoveHandler);
document.addEventListener('mouseup', mouseUpHandler);
}
};
return {
onMouseDown: onMouseDown
};
}
export default useDraggableScroll;
//# sourceMappingURL=use-draggable-scroll.esm.js.map