@enact/sandstone
Version:
Large-screen/TV support library for Enact, containing a variety of UI components.
105 lines (96 loc) • 4.71 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useOverscrollEffect = exports["default"] = void 0;
var _util = require("@enact/core/util");
var _resolution = _interopRequireDefault(require("@enact/ui/resolution"));
var _useScroll = require("@enact/ui/useScroll");
var _react = require("react");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var overscrollTypeDone = _useScroll.constants.overscrollTypeDone,
overscrollTypeHold = _useScroll.constants.overscrollTypeHold,
overscrollTypeNone = _useScroll.constants.overscrollTypeNone,
overscrollTypeOnce = _useScroll.constants.overscrollTypeOnce,
overscrollTransitionPrefix = '--scroll-overscroll-transition-',
overscrollTranslatePrefix = '--scroll-overscroll-translate-',
overscrollTransitionStart = 'transform 300ms cubic-bezier(0.5, 1, 0.89, 1)',
overscrollTransitionEnd = 'transform 500ms cubic-bezier(0.34, 1.56, 0.64, 1)',
overscrollMaxTranslate = _resolution["default"].scale(180),
overscrollTimeout = 220;
var useOverscrollEffect = exports.useOverscrollEffect = function useOverscrollEffect(props, instances) {
var scrollContainerHandle = instances.scrollContainerHandle,
scrollContentRef = instances.scrollContentRef;
// Mutable value
var mutableRef = (0, _react.useRef)({
overscrollJobs: {
horizontal: {
before: null,
after: null
},
vertical: {
before: null,
after: null
}
}
});
// Hooks
var applyOverscrollEffect = (0, _react.useCallback)(function (orientation, edge, type, ratio) {
var isHorizontal = orientation === 'horizontal';
if (type !== overscrollTypeHold && scrollContentRef.current) {
var effectSize = ratio * (edge === 'before' ? 1 : -1) * (isHorizontal && scrollContainerHandle.current.rtl ? -1 : 1) * overscrollMaxTranslate,
translate = "translate".concat(isHorizontal ? 'X' : 'Y', "(").concat(effectSize, "px)"),
transition = ratio !== 0 ? overscrollTransitionStart : overscrollTransitionEnd;
scrollContentRef.current.style.setProperty(overscrollTranslatePrefix + orientation, translate);
scrollContentRef.current.style.setProperty(overscrollTransitionPrefix + orientation, transition);
if (type === overscrollTypeOnce) {
mutableRef.current.overscrollJobs[orientation][edge].start(orientation, edge, overscrollTypeDone, 0);
}
}
}, [scrollContainerHandle, scrollContentRef]);
(0, _react.useEffect)(function () {
function createOverscrollJob(orientation, edge) {
if (!mutableRef.current.overscrollJobs[orientation][edge]) {
mutableRef.current.overscrollJobs[orientation][edge] = new _util.Job(applyOverscrollEffect, overscrollTimeout);
}
}
function stopOverscrollJob(orientation, edge) {
var job = mutableRef.current.overscrollJobs[orientation][edge];
if (job) {
job.stop();
}
}
createOverscrollJob('horizontal', 'before');
createOverscrollJob('horizontal', 'after');
createOverscrollJob('vertical', 'before');
createOverscrollJob('vertical', 'after');
return function () {
stopOverscrollJob('horizontal', 'before');
stopOverscrollJob('horizontal', 'after');
stopOverscrollJob('vertical', 'before');
stopOverscrollJob('vertical', 'after');
};
}, [applyOverscrollEffect]);
// Functions
function clearOverscrollEffect(orientation, edge) {
mutableRef.current.overscrollJobs[orientation][edge].startAfter(overscrollTimeout, orientation, edge, overscrollTypeNone, 0);
scrollContainerHandle.current.setOverscrollStatus(orientation, edge, overscrollTypeNone, 0);
}
function checkAndApplyOverscrollEffectByDirection(direction) {
var orientation = direction === 'up' || direction === 'down' ? 'vertical' : 'horizontal',
bounds = scrollContainerHandle.current.getScrollBounds(),
scrollability = orientation === 'vertical' ? scrollContainerHandle.current.canScrollVertically(bounds) : scrollContainerHandle.current.canScrollHorizontally(bounds);
if (scrollability) {
var isRtl = scrollContainerHandle.current.rtl,
edge = direction === 'up' || !isRtl && direction === 'left' || isRtl && direction === 'right' ? 'before' : 'after';
scrollContainerHandle.current.checkAndApplyOverscrollEffect(orientation, edge, overscrollTypeOnce);
}
}
// Return
return {
applyOverscrollEffect: applyOverscrollEffect,
checkAndApplyOverscrollEffectByDirection: checkAndApplyOverscrollEffectByDirection,
clearOverscrollEffect: clearOverscrollEffect
};
};
var _default = exports["default"] = useOverscrollEffect;