From c486bad2ddc6cd5492cf76fd5a4a31026e5a810c Mon Sep 17 00:00:00 2001 From: Dotta Date: Thu, 5 Mar 2026 17:04:25 -0600 Subject: [PATCH] fix(ui): restore mobile touch scroll in popover dropdowns inside dialogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Radix Dialog's modal DismissableLayer calls preventDefault() on pointerdown events originating outside the Dialog DOM tree. Popover portals render at the body level (outside the Dialog), so touch events on popover content were treated as 'outside' — killing scroll gesture recognition on mobile. Fix: add onPointerDownOutside to NewIssueDialog's DialogContent that detects events from Radix popper wrappers and calls event.preventDefault() on the Radix event (not the native event), which skips the Dialog's native preventDefault and restores touch scrolling. Also cleans up previous CSS-only workarounds (-webkit-overflow-scrolling, touch-pan-y on individual buttons) that couldn't override JS preventDefault. --- ui/src/components/InlineEntitySelector.tsx | 7 ++----- ui/src/components/NewIssueDialog.tsx | 12 ++++++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ui/src/components/InlineEntitySelector.tsx b/ui/src/components/InlineEntitySelector.tsx index 6897f881..ca2c5402 100644 --- a/ui/src/components/InlineEntitySelector.tsx +++ b/ui/src/components/InlineEntitySelector.tsx @@ -158,10 +158,7 @@ export const InlineEntitySelector = forwardRef -
+
{filteredOptions.length === 0 ? (

{emptyMessage}

) : ( @@ -173,7 +170,7 @@ export const InlineEntitySelector = forwardRef setHighlightedIndex(index)} diff --git a/ui/src/components/NewIssueDialog.tsx b/ui/src/components/NewIssueDialog.tsx index 6b872c28..7e16559f 100644 --- a/ui/src/components/NewIssueDialog.tsx +++ b/ui/src/components/NewIssueDialog.tsx @@ -522,6 +522,18 @@ export function NewIssueDialog() { : "sm:max-w-lg" )} onKeyDown={handleKeyDown} + onPointerDownOutside={(event) => { + // Radix Dialog's modal DismissableLayer calls preventDefault() on + // pointerdown events that originate outside the Dialog DOM tree. + // Popover portals render at the body level (outside the Dialog), so + // touch events on popover content get their default prevented — which + // kills scroll gesture recognition on mobile. Telling Radix "this + // event is handled" skips that preventDefault, restoring touch scroll. + const target = event.detail.originalEvent.target as HTMLElement | null; + if (target?.closest("[data-radix-popper-content-wrapper]")) { + event.preventDefault(); + } + }} > {/* Header bar */}