diff --git a/packages/@headlessui-react/CHANGELOG.md b/packages/@headlessui-react/CHANGELOG.md index 09ff39562..fb7a7dd84 100644 --- a/packages/@headlessui-react/CHANGELOG.md +++ b/packages/@headlessui-react/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ensure sibling `Dialog` components are scrollable on mobile ([#3796](https://github.com/tailwindlabs/headlessui/pull/3796)) - Infer `Combobox` type based on `onChange` handler ([#3798](https://github.com/tailwindlabs/headlessui/pull/3798)) - Allow home/end key default behavior inside `ComboboxInput` when `Combobox` is closed ([#3798](https://github.com/tailwindlabs/headlessui/pull/3798)) +- Ensure interacting with a `Dialog` on iOS works after interacting with a disallowed area ([#3801](https://github.com/tailwindlabs/headlessui/pull/3801)) ## [2.2.8] - 2025-09-12 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 b7e0d3327..e91ab5ce4 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 @@ -76,23 +76,27 @@ export function handleIOSLocking(): ScrollLockStep { ) // Rely on overscrollBehavior to prevent scrolling outside of the Dialog. - d.addEventListener(doc, 'touchstart', (e) => { - if (DOM.isHTMLorSVGElement(e.target) && DOM.hasInlineStyle(e.target)) { - if (inAllowedContainer(e.target)) { - // Find the root of the allowed containers - let rootContainer = e.target - while ( - rootContainer.parentElement && - inAllowedContainer(rootContainer.parentElement) - ) { - rootContainer = rootContainer.parentElement! - } + d.group((_d) => { + d.addEventListener(doc, 'touchstart', (e) => { + _d.dispose() + + if (DOM.isHTMLorSVGElement(e.target) && DOM.hasInlineStyle(e.target)) { + if (inAllowedContainer(e.target)) { + // Find the root of the allowed containers + let rootContainer = e.target + while ( + rootContainer.parentElement && + inAllowedContainer(rootContainer.parentElement) + ) { + rootContainer = rootContainer.parentElement! + } - d.style(rootContainer, 'overscrollBehavior', 'contain') - } else { - d.style(e.target, 'touchAction', 'none') + _d.style(rootContainer, 'overscrollBehavior', 'contain') + } else { + _d.style(e.target, 'touchAction', 'none') + } } - } + }) }) d.addEventListener(