react-selectable-box
Version:
A React component used hooks that allows you to select elements in the drag area using the mouse
127 lines (125 loc) • 4.43 kB
JavaScript
import { useEffect, useRef } from 'react';
import { getClientXY } from "../utils";
var DEFAULT_SCROLL_SPEED = 4;
var EDGE_OFFSET = 1;
export default function useScroll() {
var scrollSpeed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_SCROLL_SPEED;
var scrollContainer = arguments.length > 1 ? arguments[1] : undefined;
var topRaf = useRef(null);
var bottomRaf = useRef(null);
var leftRaf = useRef(null);
var rightRaf = useRef(null);
var cancelRaf = function cancelRaf(raf) {
if (raf.current) {
cancelAnimationFrame(raf.current);
raf.current = null;
}
};
var cancelScroll = function cancelScroll() {
cancelRaf(topRaf);
cancelRaf(bottomRaf);
cancelRaf(leftRaf);
cancelRaf(rightRaf);
};
useEffect(function () {
return cancelScroll;
}, []);
var getScrollContainer = function getScrollContainer(axis) {
function getContainer() {
if (scrollContainer) {
var _scrollContainer$inne, _scrollContainer$oute;
if (typeof scrollContainer === 'function') {
return scrollContainer();
}
if (((_scrollContainer$inne = scrollContainer.inner) === null || _scrollContainer$inne === void 0 ? void 0 : _scrollContainer$inne.axis) === axis) {
return scrollContainer.inner.getContainer();
}
if (((_scrollContainer$oute = scrollContainer.outer) === null || _scrollContainer$oute === void 0 ? void 0 : _scrollContainer$oute.axis) === axis) {
return scrollContainer.outer.getContainer();
}
}
return document.body;
}
var container = getContainer();
return container === document.body ? document.documentElement : container;
};
var smoothScroll = function smoothScroll(e) {
var _getClientXY = getClientXY(e),
clientX = _getClientXY.clientX,
clientY = _getClientXY.clientY;
var xScrollContainer = getScrollContainer('x');
var yScrollContainer = getScrollContainer('y');
if (yScrollContainer) {
// top
if (clientY - EDGE_OFFSET <= 0 || clientY <= yScrollContainer.getBoundingClientRect().top) {
if (!topRaf.current) {
var callback = function callback() {
if (yScrollContainer.scrollTop > 0) {
topRaf.current = requestAnimationFrame(function () {
yScrollContainer.scrollTop -= scrollSpeed;
callback();
});
}
};
callback();
}
} else {
cancelRaf(topRaf);
}
// bottom
if (clientY + EDGE_OFFSET >= window.innerHeight || clientY >= yScrollContainer.getBoundingClientRect().bottom) {
if (!bottomRaf.current) {
var _callback = function _callback() {
if (yScrollContainer.scrollTop < yScrollContainer.scrollHeight - yScrollContainer.clientHeight) {
bottomRaf.current = requestAnimationFrame(function () {
yScrollContainer.scrollTop += scrollSpeed;
_callback();
});
}
};
_callback();
}
} else {
cancelRaf(bottomRaf);
}
}
if (xScrollContainer) {
// left
if (clientX - EDGE_OFFSET <= 0 || clientX <= xScrollContainer.getBoundingClientRect().left) {
if (!leftRaf.current) {
var _callback2 = function _callback2() {
if (xScrollContainer.scrollLeft > 0) {
leftRaf.current = requestAnimationFrame(function () {
xScrollContainer.scrollLeft -= scrollSpeed;
_callback2();
});
}
};
_callback2();
}
} else {
cancelRaf(leftRaf);
}
// right
if (clientX + EDGE_OFFSET >= window.innerWidth || clientX >= xScrollContainer.getBoundingClientRect().right) {
if (!rightRaf.current) {
var _callback3 = function _callback3() {
if (xScrollContainer.scrollLeft < xScrollContainer.scrollWidth - xScrollContainer.clientWidth) {
rightRaf.current = requestAnimationFrame(function () {
xScrollContainer.scrollLeft += scrollSpeed;
_callback3();
});
}
};
_callback3();
}
} else {
cancelRaf(rightRaf);
}
}
};
return {
cancelScroll: cancelScroll,
smoothScroll: smoothScroll
};
}