@base-ui/react
Version:
Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.
36 lines (34 loc) • 1.93 kB
JavaScript
;
'use client';
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useAnchoredPopupScrollLock = useAnchoredPopupScrollLock;
var React = _interopRequireWildcard(require("react"));
var _owner = require("@base-ui/utils/owner");
var _useScrollLock = require("@base-ui/utils/useScrollLock");
var _useIsoLayoutEffect = require("@base-ui/utils/useIsoLayoutEffect");
// Touch-opened popups normally avoid scroll locking so users can still swipe outside to dismiss.
// This hook re-enables scroll lock only when the popup is effectively full-width.
// Treat popups with up to 20px of total horizontal gutter as full-width so common ~10px side
// padding still locks scroll, since that leaves too little outside space for a reliable swipe.
const VIEWPORT_WIDTH_TOLERANCE_PX = 20;
/**
* Manages scroll lock for anchored popups. For non-touch opens, scroll lock is applied when
* enabled. For touch opens, scroll lock is applied only when the positioner width is effectively
* viewport-sized.
*/
function useAnchoredPopupScrollLock(enabled, touchOpen, positionerElement, referenceElement) {
const [touchOpenShouldLockScroll, setTouchOpenShouldLockScroll] = React.useState(false);
(0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => {
if (!enabled || !touchOpen || positionerElement == null) {
setTouchOpenShouldLockScroll(false);
return;
}
const viewportWidth = (0, _owner.ownerDocument)(positionerElement).documentElement.clientWidth;
const popupWidth = positionerElement.offsetWidth;
setTouchOpenShouldLockScroll(viewportWidth > 0 && popupWidth > 0 && popupWidth >= viewportWidth - VIEWPORT_WIDTH_TOLERANCE_PX);
}, [enabled, touchOpen, positionerElement]);
(0, _useScrollLock.useScrollLock)(enabled && (!touchOpen || touchOpenShouldLockScroll), referenceElement);
}