UNPKG

@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
"use strict"; '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); }