Fix composer horizontal swipe triggering browser back/forward

Two-finger horizontal trackpad swipes over the composer were escaping to
the page's history-nav gesture, especially obvious when a quote post was
attached. Mirror the carousel fix: `overscroll-behavior-x: contain` on
the composer's ScrollView for Chrome/Firefox, plus a wheel listener that
preventDefaults horizontal-dominant wheels for Safari (which ignores
overscroll-behavior).
This commit is contained in:
vineyardbovines
2026-06-09 09:39:38 -04:00
parent 2cb225dddd
commit cdada2986b
+31 -1
View File
@@ -134,7 +134,14 @@ import * as Prompt from '#/components/Prompt'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_ANDROID, IS_IOS, IS_LIQUID_GLASS, IS_NATIVE, IS_WEB} from '#/env'
import {
IS_ANDROID,
IS_IOS,
IS_LIQUID_GLASS,
IS_NATIVE,
IS_WEB,
IS_WEB_SAFARI,
} from '#/env'
import {type Gif} from '#/features/gifPicker/types'
import {BottomSheetPortalProvider} from '../../../../modules/bottom-sheet'
import {
@@ -1219,6 +1226,24 @@ export const ComposePost = ({
}
}, [composerState])
useEffect(() => {
// Safari ignores `overscroll-behavior`, so horizontal trackpad swipes over
// the composer (e.g. on a quote post) can still trigger the browser's
// back/forward navigation gesture. Suppress predominantly-horizontal wheel
// events so the history-nav gesture never fires. Chrome and Firefox are
// covered by the `overscrollBehaviorX: 'contain'` style on the ScrollView.
if (!IS_WEB_SAFARI) return
const el =
scrollViewRef.current?.getScrollableNode() as unknown as HTMLElement | null
if (!el) return
const onWheel = (e: WheelEvent) => {
if (Math.abs(e.deltaX) <= Math.abs(e.deltaY)) return
e.preventDefault()
}
el.addEventListener('wheel', onWheel, {passive: false})
return () => el.removeEventListener('wheel', onWheel)
}, [scrollViewRef])
const isLastThreadedPost = thread.posts.length > 1 && nextPost === undefined
const {
scrollHandler,
@@ -1324,6 +1349,11 @@ export const ComposePost = ({
web({
scrollbarGutter: 'stable',
scrollbarColor: `${t.palette.contrast_200} transparent`,
// Prevent horizontal trackpad swipes from triggering the
// browser's back/forward overscroll-navigation gesture.
// Handles Chrome and Firefox; Safari is handled separately
// via a wheel listener since it ignores overscroll-behavior.
overscrollBehaviorX: 'contain',
}),
]}
keyboardShouldPersistTaps="always"