@wix/design-system
Version:
@wix/design-system
99 lines (98 loc) • 3.09 kB
JavaScript
;
exports.__esModule = true;
exports.useDragLayerAutoScroll = exports.default = void 0;
var _react = require("react");
var _reactDnd = require("react-dnd");
var SCROLL_ZONE_SIZE = 20;
var SCROLL_SPEED = 10;
var useDragLayerAutoScroll = containerRef => {
var {
isDragging,
currentOffset
} = (0, _reactDnd.useDragLayer)(monitor => ({
isDragging: monitor.isDragging(),
currentOffset: monitor.getClientOffset()
}));
var animationFrame = (0, _react.useRef)(null);
var getScrollContainer = (0, _react.useCallback)(() => {
if (!containerRef || !containerRef.current) {
return window;
}
// Find scrollable parent
var node = containerRef.current.parentElement;
while (node && node !== document.body) {
var overflowY = window.getComputedStyle(node).overflowY;
var isScrollable = overflowY === 'auto' || overflowY === 'scroll';
if (isScrollable && node.scrollHeight > node.clientHeight) {
return node;
}
node = node.parentElement;
}
return window;
}, [containerRef]);
var scroll = (0, _react.useCallback)(() => {
if (!isDragging || !currentOffset) {
animationFrame.current = requestAnimationFrame(scroll);
return;
}
var container = getScrollContainer();
if (!container) {
animationFrame.current = requestAnimationFrame(scroll);
return;
}
var {
y
} = currentOffset;
var scrollChange = 0;
if (container === window) {
var viewportHeight = window.innerHeight;
if (y < SCROLL_ZONE_SIZE) {
scrollChange = -SCROLL_SPEED;
} else if (y > viewportHeight - SCROLL_ZONE_SIZE) {
scrollChange = SCROLL_SPEED;
}
if (scrollChange !== 0) {
window.scrollBy(0, scrollChange);
}
animationFrame.current = requestAnimationFrame(scroll);
} else if (container instanceof HTMLElement) {
var rect = container.getBoundingClientRect();
if (y < rect.top + SCROLL_ZONE_SIZE) {
scrollChange = -SCROLL_SPEED;
} else if (y > rect.bottom - SCROLL_ZONE_SIZE) {
scrollChange = SCROLL_SPEED;
}
if (scrollChange !== 0) {
container.scrollTop += scrollChange;
}
animationFrame.current = requestAnimationFrame(scroll);
}
}, [isDragging, currentOffset, getScrollContainer]);
(0, _react.useEffect)(() => {
if (isDragging) {
animationFrame.current = requestAnimationFrame(scroll);
} else {
if (animationFrame.current) {
cancelAnimationFrame(animationFrame.current);
animationFrame.current = null;
}
}
return () => {
if (animationFrame.current) {
cancelAnimationFrame(animationFrame.current);
animationFrame.current = null;
}
};
}, [isDragging, scroll]);
return null;
};
exports.useDragLayerAutoScroll = useDragLayerAutoScroll;
var AutoScroller = _ref => {
var {
containerRef
} = _ref;
useDragLayerAutoScroll(containerRef);
return null;
};
var _default = exports.default = AutoScroller;
//# sourceMappingURL=AutoScroller.js.map