@atlaskit/drawer
Version:
A drawer is a panel that slides in from the left side of the screen.
62 lines (60 loc) • 2.46 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = usePreventProgrammaticScroll;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = require("react");
var _bindEventListener = require("bind-event-listener");
var _fg = require("@atlaskit/platform-feature-flags/fg");
/**
* Returns how far the body is scrolled from the top of the viewport.
*
* ⚠️ This is copied from `packages/design-system/modal-dialog/src/internal/hooks/use-prevent-programmatic-scroll.tsx`
*
* ____
* ||____|| <-- overflow
* | | <-- viewport
* |____|
*
* Scroll distance is the height of overflow outside the viewport.
*/
function getScrollDistance() {
var _document$documentEle, _document$body;
return window.pageYOffset || ((_document$documentEle = document.documentElement) === null || _document$documentEle === void 0 ? void 0 : _document$documentEle.scrollTop) || ((_document$body = document.body) === null || _document$body === void 0 ? void 0 : _document$body.scrollTop) || 0;
}
/**
* Prevents programmatic scrolling of the viewport with `scrollIntoView`.
* Should be used in conjunction with a scroll lock to prevent a user from scrolling.
*
* ⚠️ This is copied from `packages/design-system/modal-dialog/src/internal/hooks/use-prevent-programmatic-scroll.tsx`
*
* @returns scroll top offset of the viewport
*/
function usePreventProgrammaticScroll() {
var _useState = (0, _react.useState)(0),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
scrollTopOffset = _useState2[0],
setScrollTopOffset = _useState2[1];
(0, _react.useLayoutEffect)(function () {
setScrollTopOffset(getScrollDistance());
}, []);
var onWindowScroll = (0, _react.useCallback)(function () {
if (getScrollDistance() !== scrollTopOffset) {
window.scrollTo(window.pageXOffset, scrollTopOffset);
}
}, [scrollTopOffset]);
(0, _react.useEffect)(function () {
// The top-layer drawer relies on native modality + `DialogScrollLock`; the
// programmatic-scroll guard is intentionally dropped under the flag.
if ((0, _fg.fg)('platform-dst-top-layer')) {
return;
}
return (0, _bindEventListener.bind)(window, {
type: 'scroll',
listener: onWindowScroll
});
}, [onWindowScroll]);
return scrollTopOffset;
}