UNPKG

@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
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; }