From 7a1940e0b226536b1d351ef5cc7f4bdb8c7949e1 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 20 Dec 2023 23:55:41 +0100 Subject: [PATCH] allow horizontal scrolling when scroll locking (#2889) --- packages/@headlessui-react/CHANGELOG.md | 4 +++- .../document-overflow/handle-ios-locking.ts | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/@headlessui-react/CHANGELOG.md b/packages/@headlessui-react/CHANGELOG.md index f86e132305..f61b449615 100644 --- a/packages/@headlessui-react/CHANGELOG.md +++ b/packages/@headlessui-react/CHANGELOG.md @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet! +### Fixed + +- Allow horizontal scrolling when scroll locking ([bdf4f8e](https://github.com/tailwindlabs/headlessui/commit/bdf4f8e32358485dd9c437c0d631309250ee5624)) ## [2.0.0-alpha.1] - 2023-12-20 diff --git a/packages/@headlessui-react/src/hooks/document-overflow/handle-ios-locking.ts b/packages/@headlessui-react/src/hooks/document-overflow/handle-ios-locking.ts index fc53caa733..24b4f177aa 100644 --- a/packages/@headlessui-react/src/hooks/document-overflow/handle-ios-locking.ts +++ b/packages/@headlessui-react/src/hooks/document-overflow/handle-ios-locking.ts @@ -97,7 +97,6 @@ export function handleIOSLocking(): ScrollLockStep { if (inAllowedContainer(e.target as HTMLElement)) { // We are in an allowed container, however on iOS the page can still scroll in // certain scenarios... - let rootContainer = e.target while ( rootContainer.parentElement && @@ -113,20 +112,32 @@ export function handleIOSLocking(): ScrollLockStep { // portal, its over. scrollableParent.dataset.headlessuiPortal !== '' ) { - if (scrollableParent.scrollHeight > scrollableParent.clientHeight) { + // Verify that we are in a scrollable container (which may or may not overflow yet) + let css = window.getComputedStyle(scrollableParent) + if (/(auto|scroll)/.test(css.overflow + css.overflowY + css.overflowX)) { + break + } + + // Check if the scrollable container is already overflowing + if ( + scrollableParent.scrollHeight > scrollableParent.clientHeight || + scrollableParent.scrollWidth > scrollableParent.clientWidth + ) { break } scrollableParent = scrollableParent.parentElement } - // We crawled up the tree until the beginnging of the Portal, let's prevent the event. + // We crawled up the tree until the beginnging of the Portal, let's prevent the + // event if this is the case. If not, then we are in a container where we are + // allowed to scroll so we don't have to prevent the event. if (scrollableParent.dataset.headlessuiPortal === '') { e.preventDefault() } } - // We are not in an allowed contains, so let's prevent the event. + // We are not in an allowed container, so let's prevent the event. else { e.preventDefault() }