code/ui/sheet/next.md
The Sheet + ScrollView gesture coordination on native iOS has limitations because Tamagui uses React Native's built-in PanResponder, while iOS's UIScrollView gesture recognizers fire BEFORE the RN responder system can claim the gesture.
This causes:
Both gorhom/bottom-sheet and react-native-actions-sheet solve this by using react-native-gesture-handler which provides:
simultaneousHandlers - allows coordinating multiple gesture recognizersGestureDetector with worklets - can check conditions and decide who handles gesture before it startsimport { setupGestureHandler } from '@tamagui/sheet'
import { GestureHandlerRootView } from 'react-native-gesture-handler'
// Call once at app startup (optional - falls back to PanResponder)
setupGestureHandler({
// Pass the gesture handler module so we don't add it as a hard dependency
GestureDetector: require('react-native-gesture-handler').GestureDetector,
Gesture: require('react-native-gesture-handler').Gesture,
})
// Then wrap app
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<YourApp />
</GestureHandlerRootView>
)
}
If setupGestureHandler() is called:
GestureDetector with Gesture.Pan() instead of PanRespondersimultaneousHandlers to coordinate with ScrollView's gestureblockPan flag pattern from actions-sheet for smooth handoffIf not called:
PanResponder implementationblockPan flag pattern with gesture handlerSheetImplementationCustom.tsx - Replace PanResponder with GestureDetectorSheetScrollView.tsx - Use useScrollHandlers() pattern from actions-sheetsetupGestureHandler.ts for optional gesture handler registrationThere's a test case at code/kitchen-sink/src/usecases/SheetScrollableDrag.tsx that demonstrates the bug and can be used to verify fixes. It's not exported in the main navigation but can be accessed directly for testing.
Native scroll enable/disable based on pane position - Tried disabling scroll when sheet is not at top position, but this completely broke scrolling because the initial pane position values aren't set correctly on mount.
PaneY change listeners - Added onPaneYChange/setPaneY to ScrollBridge to notify ScrollView of position changes during drag, but the fundamental issue remains that iOS UIScrollView gesture recognizers fire before RN's responder system.
The core issue is architectural: React Native's PanResponder cannot coordinate with iOS's native UIScrollView gesture recognizers at the right level. The only real solution is react-native-gesture-handler integration.