@atlaskit/modal-dialog
Version:
A modal dialog displays content that requires user interaction, in a layer above the page.
46 lines (44 loc) • 1.65 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import { useCallback, useEffect, useLayoutEffect, useState } from 'react';
import { bind } from 'bind-event-listener';
/**
* Returns how far the body is scrolled from the top of the viewport.
*
* ____
* ||____|| <-- 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 programatic scrolling of the viewport with `scrollIntoView`.
* Should be used in conjunction with a scroll lock to prevent a user from scrolling.
*
* @returns scroll top offset of the viewport
*/
export default function usePreventProgrammaticScroll() {
var _useState = useState(0),
_useState2 = _slicedToArray(_useState, 2),
scrollTopOffset = _useState2[0],
setScrollTopOffset = _useState2[1];
useLayoutEffect(function () {
setScrollTopOffset(getScrollDistance());
}, []);
var onWindowScroll = useCallback(function () {
if (getScrollDistance() !== scrollTopOffset) {
window.scrollTo(window.pageXOffset, scrollTopOffset);
}
}, [scrollTopOffset]);
useEffect(function () {
return bind(window, {
type: 'scroll',
listener: onWindowScroll
});
}, [onWindowScroll]);
return scrollTopOffset;
}