use-smooth-scroll
Version:
React hook which gives a smooth scrolling function.
77 lines (68 loc) • 2.95 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var easing = require('@popmotion/easing');
var popcorn = require('@popmotion/popcorn');
var arePassiveEventsSupported = _interopDefault(require('are-passive-events-supported'));
var durationProgress = _interopDefault(require('callbag-duration-progress'));
var flatten = _interopDefault(require('callbag-flatten'));
var fromEvent = _interopDefault(require('callbag-from-event'));
var map = _interopDefault(require('callbag-map'));
var merge = _interopDefault(require('callbag-merge'));
var of = _interopDefault(require('callbag-of'));
var subject = _interopDefault(require('callbag-subject'));
var subscribe = _interopDefault(require('callbag-subscribe'));
var takeUntil = _interopDefault(require('callbag-take-until'));
var react = require('react');
var useConstant = _interopDefault(require('use-constant'));
var ONCE = [];
var PASSIVE =
/*#__PURE__*/
arePassiveEventsSupported() ? {
passive: true
} : undefined;
function useSmoothScroll(axis, ref) {
var command$ = useConstant(subject);
var argumentsRef = react.useRef();
react.useEffect(function () {
argumentsRef.current = [axis === 'x' ? 'scrollLeft' : 'scrollTop', ref.current];
});
var scrollTo = react.useCallback(function (target, _temp) {
var _ref = _temp === void 0 ? {} : _temp,
_ref$duration = _ref.duration,
duration = _ref$duration === void 0 ? 300 : _ref$duration,
_ref$easing = _ref.easing,
easing$1 = _ref$easing === void 0 ? easing.easeOut : _ref$easing;
var _argumentsRef$current = argumentsRef.current,
scrollProperty = _argumentsRef$current[0],
node = _argumentsRef$current[1];
command$(1, [scrollProperty, node, target, duration, easing$1]);
}, ONCE);
react.useEffect(function () {
return subscribe(function (_ref2) {
var node = _ref2[0],
scrollProperty = _ref2[1],
v = _ref2[2];
node[scrollProperty] = v;
})(flatten(map(function (_ref3) {
var scrollProperty = _ref3[0],
node = _ref3[1],
target = _ref3[2],
duration = _ref3[3],
easing = _ref3[4];
var recyclable = [node, scrollProperty, 0];
var start = node[scrollProperty];
var resolvedDuration = Math.max(0, typeof duration === 'function' ? duration(Math.abs(target - start)) : duration);
if (resolvedDuration === 0) {
recyclable[2] = target;
return of(recyclable);
}
return takeUntil(merge(fromEvent(node, 'wheel', PASSIVE), fromEvent(node, 'touchstart', PASSIVE)))(map(function (p) {
recyclable[2] = popcorn.mix(start, target, easing(p));
return recyclable;
})(durationProgress(resolvedDuration)));
})(command$)));
}, ONCE);
return scrollTo;
}
exports.default = useSmoothScroll;