@os-design/use-auto-scroll
Advanced tools
Comparing version 1.0.7 to 1.0.8
@@ -7,18 +7,10 @@ "use strict"; | ||
exports.getScrollableElements = exports["default"] = void 0; | ||
var _useCursorPosition = _interopRequireDefault(require("@os-design/use-cursor-position")); | ||
var _react = require("react"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } | ||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } | ||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } | ||
var FPS = 60; | ||
var FRAME_TIMEOUT = 1000 / FPS; | ||
var getProps = function getProps(props) { | ||
@@ -31,3 +23,2 @@ return { | ||
}; | ||
var getRect = function getRect(el) { | ||
@@ -42,3 +33,2 @@ if (el === document.body) { | ||
} | ||
var rect = el.getBoundingClientRect(); | ||
@@ -52,32 +42,26 @@ return { | ||
}; | ||
/** | ||
* Detects whether the element is scrollable. | ||
*/ | ||
var isScrollable = function isScrollable(el) { | ||
var style = getComputedStyle(el); | ||
if (el !== document.body && !/(auto|scroll)/.test(style.overflow + style.overflowY + style.overflowX)) { | ||
return false; | ||
} | ||
var _getRect = getRect(el), | ||
width = _getRect.width, | ||
height = _getRect.height; | ||
width = _getRect.width, | ||
height = _getRect.height; | ||
return el.scrollWidth > width || el.scrollHeight > height; | ||
}; | ||
/** | ||
* Returns an array of the scrollable elements located under the specified coordinates. The first one is the topmost. | ||
*/ | ||
var getScrollableElements = function getScrollableElements(x, y) { | ||
var elementsFromPoint = document.elementsFromPoint(x, y); | ||
var elements = []; // eslint-disable-next-line no-restricted-syntax | ||
var elements = []; | ||
// eslint-disable-next-line no-restricted-syntax | ||
var _iterator = _createForOfIteratorHelper(elementsFromPoint), | ||
_step; | ||
_step; | ||
try { | ||
@@ -87,7 +71,5 @@ for (_iterator.s(); !(_step = _iterator.n()).done;) { | ||
var el = element === document.documentElement ? document.body : element; | ||
if (isScrollable(el)) { | ||
elements.push(el); | ||
} | ||
if (el === document.body) break; | ||
@@ -100,8 +82,5 @@ } | ||
} | ||
return elements; | ||
}; | ||
exports.getScrollableElements = getScrollableElements; | ||
var getScrollOffset = function getScrollOffset(el) { | ||
@@ -114,3 +93,2 @@ if (el === document.body) { | ||
} | ||
return { | ||
@@ -121,3 +99,2 @@ scrollLeft: el.scrollLeft, | ||
}; | ||
var useAutoScroll = function useAutoScroll() { | ||
@@ -130,12 +107,15 @@ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
var frameRef = (0, _react.useRef)(); | ||
var timeoutRef = (0, _react.useRef)(); // Update the ref to the cursor position if it changes | ||
var timeoutRef = (0, _react.useRef)(); | ||
// Update the ref to the cursor position if it changes | ||
(0, _react.useEffect)(function () { | ||
cursorPositionRef.current = cursorPosition; | ||
}, [cursorPosition]); // Update the props if it changes | ||
}, [cursorPosition]); | ||
// Update the props if it changes | ||
(0, _react.useEffect)(function () { | ||
propsRef.current = getProps(props); | ||
}, [props]); // Cancel the animation frame request and clear the timeout if the component was unmounted | ||
}, [props]); | ||
// Cancel the animation frame request and clear the timeout if the component was unmounted | ||
(0, _react.useEffect)(function () { | ||
@@ -146,15 +126,15 @@ return function () { | ||
}; | ||
}, []); // Returns the max distance from the border of the specified element at which auto scrolling is enabled (in px) | ||
}, []); | ||
// Returns the max distance from the border of the specified element at which auto scrolling is enabled (in px) | ||
var getMaxDist = (0, _react.useCallback)(function (el, axis) { | ||
var distPercent = propsRef.current.distPercent; | ||
var _getRect2 = getRect(el), | ||
width = _getRect2.width, | ||
height = _getRect2.height; | ||
width = _getRect2.width, | ||
height = _getRect2.height; | ||
var size = axis === 'x' ? width : height; | ||
return Math.round(size * distPercent / 100); | ||
}, []); // Returns the distance by which the scroll position should be changed | ||
}, []); | ||
// Returns the distance by which the scroll position should be changed | ||
var getScrollStep = (0, _react.useCallback)(function (dist, maxDist) { | ||
@@ -165,4 +145,5 @@ if (dist < 0 || dist > maxDist) return 0; | ||
return Math.round(Math.exp((maxDist - dist) / divisor)); | ||
}, []); // Scrolls the element to the specified position | ||
}, []); | ||
// Scrolls the element to the specified position | ||
var scrollTo = (0, _react.useCallback)(function (element, options) { | ||
@@ -177,6 +158,5 @@ frameRef.current = window.requestAnimationFrame(function () { | ||
var _cursorPositionRef$cu = cursorPositionRef.current, | ||
x = _cursorPositionRef$cu.x, | ||
y = _cursorPositionRef$cu.y; | ||
x = _cursorPositionRef$cu.x, | ||
y = _cursorPositionRef$cu.y; | ||
var scrollableElements = getScrollableElements(x, y).reverse(); | ||
if (!enabled) { | ||
@@ -186,8 +166,7 @@ isScrollingRef.current = false; | ||
} | ||
isScrollingRef.current = true; | ||
isScrollingRef.current = true; // eslint-disable-next-line no-restricted-syntax | ||
// eslint-disable-next-line no-restricted-syntax | ||
var _iterator2 = _createForOfIteratorHelper(scrollableElements), | ||
_step2; | ||
_step2; | ||
try { | ||
@@ -197,7 +176,5 @@ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { | ||
var rect = getRect(el); | ||
var _getScrollOffset = getScrollOffset(el), | ||
scrollLeft = _getScrollOffset.scrollLeft, | ||
scrollTop = _getScrollOffset.scrollTop; | ||
scrollLeft = _getScrollOffset.scrollLeft, | ||
scrollTop = _getScrollOffset.scrollTop; | ||
var xMaxDist = getMaxDist(el, 'x'); | ||
@@ -218,3 +195,2 @@ var yMaxDist = getMaxDist(el, 'y'); | ||
var left = scrollLeft; | ||
if (canScrollLeft && leftScrollStep > 0) { | ||
@@ -225,5 +201,3 @@ left = Math.max(scrollLeft - leftScrollStep, 0); | ||
} | ||
var top = scrollTop; | ||
if (canScrollTop && topScrollStep > 0) { | ||
@@ -234,3 +208,2 @@ top = Math.max(scrollTop - topScrollStep, 0); | ||
} | ||
if (left !== scrollLeft || top !== scrollTop) { | ||
@@ -250,6 +223,6 @@ scrollTo(el, { | ||
} | ||
isScrollingRef.current = false; | ||
}, [getMaxDist, getScrollStep, scrollTo]); // Start auto scrolling when the cursor position changes only if it is not already running | ||
}, [getMaxDist, getScrollStep, scrollTo]); | ||
// Start auto scrolling when the cursor position changes only if it is not already running | ||
(0, _react.useEffect)(function () { | ||
@@ -259,5 +232,4 @@ if (!isScrollingRef.current && props.enabled) scroll(); | ||
}; | ||
var _default = useAutoScroll; | ||
exports["default"] = _default; | ||
//# sourceMappingURL=index.js.map |
@@ -5,3 +5,2 @@ import useCursorPosition from '@os-design/use-cursor-position'; | ||
const FRAME_TIMEOUT = 1000 / FPS; | ||
const getProps = props => ({ | ||
@@ -12,3 +11,2 @@ enabled: props.enabled !== undefined ? props.enabled : true, | ||
}); | ||
const getRect = el => { | ||
@@ -23,3 +21,2 @@ if (el === document.body) { | ||
} | ||
const rect = el.getBoundingClientRect(); | ||
@@ -33,14 +30,11 @@ return { | ||
}; | ||
/** | ||
* Detects whether the element is scrollable. | ||
*/ | ||
const isScrollable = el => { | ||
const style = getComputedStyle(el); | ||
if (el !== document.body && !/(auto|scroll)/.test(style.overflow + style.overflowY + style.overflowX)) { | ||
return false; | ||
} | ||
const { | ||
@@ -52,24 +46,19 @@ width, | ||
}; | ||
/** | ||
* Returns an array of the scrollable elements located under the specified coordinates. The first one is the topmost. | ||
*/ | ||
export const getScrollableElements = (x, y) => { | ||
const elementsFromPoint = document.elementsFromPoint(x, y); | ||
const elements = []; // eslint-disable-next-line no-restricted-syntax | ||
const elements = []; | ||
// eslint-disable-next-line no-restricted-syntax | ||
for (const element of elementsFromPoint) { | ||
const el = element === document.documentElement ? document.body : element; | ||
if (isScrollable(el)) { | ||
elements.push(el); | ||
} | ||
if (el === document.body) break; | ||
} | ||
return elements; | ||
}; | ||
const getScrollOffset = el => { | ||
@@ -82,3 +71,2 @@ if (el === document.body) { | ||
} | ||
return { | ||
@@ -89,3 +77,2 @@ scrollLeft: el.scrollLeft, | ||
}; | ||
const useAutoScroll = (props = {}) => { | ||
@@ -97,17 +84,21 @@ const cursorPosition = useCursorPosition(); | ||
const frameRef = useRef(); | ||
const timeoutRef = useRef(); // Update the ref to the cursor position if it changes | ||
const timeoutRef = useRef(); | ||
// Update the ref to the cursor position if it changes | ||
useEffect(() => { | ||
cursorPositionRef.current = cursorPosition; | ||
}, [cursorPosition]); // Update the props if it changes | ||
}, [cursorPosition]); | ||
// Update the props if it changes | ||
useEffect(() => { | ||
propsRef.current = getProps(props); | ||
}, [props]); // Cancel the animation frame request and clear the timeout if the component was unmounted | ||
}, [props]); | ||
// Cancel the animation frame request and clear the timeout if the component was unmounted | ||
useEffect(() => () => { | ||
if (frameRef.current) window.cancelAnimationFrame(frameRef.current); | ||
if (timeoutRef.current) clearTimeout(timeoutRef.current); | ||
}, []); // Returns the max distance from the border of the specified element at which auto scrolling is enabled (in px) | ||
}, []); | ||
// Returns the max distance from the border of the specified element at which auto scrolling is enabled (in px) | ||
const getMaxDist = useCallback((el, axis) => { | ||
@@ -123,4 +114,5 @@ const { | ||
return Math.round(size * distPercent / 100); | ||
}, []); // Returns the distance by which the scroll position should be changed | ||
}, []); | ||
// Returns the distance by which the scroll position should be changed | ||
const getScrollStep = useCallback((dist, maxDist) => { | ||
@@ -133,4 +125,5 @@ if (dist < 0 || dist > maxDist) return 0; | ||
return Math.round(Math.exp((maxDist - dist) / divisor)); | ||
}, []); // Scrolls the element to the specified position | ||
}, []); | ||
// Scrolls the element to the specified position | ||
const scrollTo = useCallback((element, options) => { | ||
@@ -151,3 +144,2 @@ frameRef.current = window.requestAnimationFrame(() => { | ||
const scrollableElements = getScrollableElements(x, y).reverse(); | ||
if (!enabled) { | ||
@@ -157,5 +149,5 @@ isScrollingRef.current = false; | ||
} | ||
isScrollingRef.current = true; | ||
isScrollingRef.current = true; // eslint-disable-next-line no-restricted-syntax | ||
// eslint-disable-next-line no-restricted-syntax | ||
for (const el of scrollableElements) { | ||
@@ -182,3 +174,2 @@ const rect = getRect(el); | ||
let left = scrollLeft; | ||
if (canScrollLeft && leftScrollStep > 0) { | ||
@@ -189,5 +180,3 @@ left = Math.max(scrollLeft - leftScrollStep, 0); | ||
} | ||
let top = scrollTop; | ||
if (canScrollTop && topScrollStep > 0) { | ||
@@ -198,3 +187,2 @@ top = Math.max(scrollTop - topScrollStep, 0); | ||
} | ||
if (left !== scrollLeft || top !== scrollTop) { | ||
@@ -209,6 +197,6 @@ scrollTo(el, { | ||
} | ||
isScrollingRef.current = false; | ||
}, [getMaxDist, getScrollStep, scrollTo]); // Start auto scrolling when the cursor position changes only if it is not already running | ||
}, [getMaxDist, getScrollStep, scrollTo]); | ||
// Start auto scrolling when the cursor position changes only if it is not already running | ||
useEffect(() => { | ||
@@ -218,4 +206,3 @@ if (!isScrollingRef.current && props.enabled) scroll(); | ||
}; | ||
export default useAutoScroll; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@os-design/use-auto-scroll", | ||
"version": "1.0.7", | ||
"version": "1.0.8", | ||
"license": "UNLICENSED", | ||
@@ -32,3 +32,3 @@ "repository": "git@gitlab.com:os-team/libs/os-design.git", | ||
"dependencies": { | ||
"@os-design/use-cursor-position": "^1.0.6" | ||
"@os-design/use-cursor-position": "^1.0.7" | ||
}, | ||
@@ -38,3 +38,3 @@ "peerDependencies": { | ||
}, | ||
"gitHead": "8d32820f40f43f64be2bf85f60973d358be83c1d" | ||
"gitHead": "8cb28f6719d699c014fbce91d832a9ff06abe515" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
396
46230