jobiqo-cl
Version:
[](https://circleci.com/gh/jobiqo/jobiqo-cl)
161 lines (158 loc) • 7.27 kB
JavaScript
import { useRef, useState, useEffect, useCallback, createElement, Fragment } from 'react';
import '../../../react-remove-scroll-bar/dist/es2015/constants.js';
import '../../../react-style-singleton/dist/es2015/singleton.js';
import '../../../react-style-singleton/dist/es2015/hook.js';
import { styleSingleton } from '../../../react-style-singleton/dist/es2015/component.js';
import '../../../react-remove-scroll-bar/dist/es2015/utils.js';
import { RemoveScrollBar } from '../../../react-remove-scroll-bar/dist/es2015/component.js';
import { locationCouldBeScrolled, handleScroll } from './handleScroll.js';
import { nonPassive } from './aggresiveCapture.js';
var getTouchXY = function (event) {
return 'changedTouches' in event
? [event.changedTouches[0].clientX, event.changedTouches[0].clientY]
: [0, 0];
};
var getDeltaXY = function (event) { return [event.deltaX, event.deltaY]; };
var extractRef = function (ref) {
return ref && 'current' in ref ? ref.current : ref;
};
var deltaCompare = function (x, y) {
return x[0] === y[0] && x[1] === y[1];
};
var generateStyle = function (id) { return "\n .block-interactivity-" + id + " {pointer-events: none;}\n .allow-interactivity-" + id + " {pointer-events: all;}\n"; };
var idCounter = 0;
var lockStack = [];
function RemoveScrollSideCar(props) {
var shouldPreventQueue = useRef([]);
var touchStartRef = useRef([0, 0]);
var activeAxis = useRef();
var id = useState(idCounter++)[0];
var Style = useState(function () { return styleSingleton(); })[0];
var lastProps = useRef(props);
useEffect(function () {
lastProps.current = props;
}, [props]);
useEffect(function () {
if (props.inert) {
document.body.classList.add("block-interactivity-" + id);
var allow_1 = [
props.lockRef.current
].concat((props.shards || []).map(extractRef)).filter(Boolean);
allow_1.forEach(function (el) { return el.classList.add("allow-interactivity-" + id); });
return function () {
document.body.classList.remove("block-interactivity-" + id);
allow_1.forEach(function (el) {
return el.classList.remove("allow-interactivity-" + id);
});
};
}
return;
}, [props.inert, props.lockRef.current, props.shards]);
var shouldCancelEvent = useCallback(function (event, parent) {
if ('touches' in event && event.touches.length === 2) {
return !lastProps.current.allowPinchZoom;
}
var touch = getTouchXY(event);
var touchStart = touchStartRef.current;
var deltaX = 'deltaX' in event ? event.deltaX : touchStart[0] - touch[0];
var deltaY = 'deltaY' in event ? event.deltaY : touchStart[1] - touch[1];
var currentAxis;
var target = event.target;
var moveDirection = Math.abs(deltaX) > Math.abs(deltaY) ? 'h' : 'v';
var canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target);
if (!canBeScrolledInMainDirection) {
return true;
}
if (canBeScrolledInMainDirection) {
currentAxis = moveDirection;
}
else {
currentAxis = moveDirection === 'v' ? 'h' : 'v';
canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target);
// other axis might be not scrollable
}
if (!canBeScrolledInMainDirection) {
return false;
}
if (!activeAxis.current &&
'changedTouches' in event &&
(deltaX || deltaY)) {
activeAxis.current = currentAxis;
}
if (!currentAxis) {
return true;
}
var cancelingAxis = activeAxis.current || currentAxis;
return handleScroll(cancelingAxis, parent, event, cancelingAxis == 'h' ? deltaX : deltaY, true);
}, []);
var shouldPrevent = useCallback(function (_event) {
var event = _event;
if (!lockStack.length || lockStack[lockStack.length - 1] !== Style) {
// not the last active
return;
}
var delta = 'deltaY' in event ? getDeltaXY(event) : getTouchXY(event);
var sourceEvent = shouldPreventQueue.current.filter(function (e) {
return e.name === event.type &&
e.target === event.target &&
deltaCompare(e.delta, delta);
})[0];
// self event, and should be canceled
if (sourceEvent && sourceEvent.should) {
event.preventDefault();
return;
}
// outside or shard event
if (!sourceEvent) {
var shardNodes = (lastProps.current.shards || [])
.map(extractRef)
.filter(Boolean)
.filter(function (node) { return node.contains(event.target); });
var shouldStop = shardNodes.length > 0
? shouldCancelEvent(event, shardNodes[0])
: !lastProps.current.noIsolation;
if (shouldStop) {
event.preventDefault();
}
}
}, []);
var shouldCancel = useCallback(function (name, delta, target, should) {
var event = { name: name, delta: delta, target: target, should: should };
shouldPreventQueue.current.push(event);
setTimeout(function () {
shouldPreventQueue.current = shouldPreventQueue.current.filter(function (e) { return e !== event; });
}, 1);
}, []);
var scrollTouchStart = useCallback(function (event) {
touchStartRef.current = getTouchXY(event);
activeAxis.current = undefined;
}, []);
var scrollWheel = useCallback(function (event) {
shouldCancel(event.type, getDeltaXY(event), event.target, shouldCancelEvent(event, props.lockRef.current));
}, []);
var scrollTouchMove = useCallback(function (event) {
shouldCancel(event.type, getTouchXY(event), event.target, shouldCancelEvent(event, props.lockRef.current));
}, []);
useEffect(function () {
lockStack.push(Style);
props.setCallbacks({
onScrollCapture: scrollWheel,
onWheelCapture: scrollWheel,
onTouchMoveCapture: scrollTouchMove
});
document.addEventListener('wheel', shouldPrevent, nonPassive);
document.addEventListener('touchmove', shouldPrevent, nonPassive);
document.addEventListener('touchstart', scrollTouchStart, nonPassive);
return function () {
lockStack = lockStack.filter(function (inst) { return inst !== Style; });
document.removeEventListener('wheel', shouldPrevent, nonPassive);
document.removeEventListener('touchmove', shouldPrevent, nonPassive);
document.removeEventListener('touchstart', scrollTouchStart, nonPassive);
};
}, []);
var removeScrollBar = props.removeScrollBar, inert = props.inert;
return (createElement(Fragment, null,
inert ? createElement(Style, { styles: generateStyle(id) }) : null,
removeScrollBar ? createElement(RemoveScrollBar, { gapMode: "margin" }) : null));
}
export { RemoveScrollSideCar, getDeltaXY, getTouchXY };