Where Gesture Config Lives
TSX
Supported Directions
gestureDirection accepts pan and pinch directions:
"horizontal""horizontal-inverted""vertical""vertical-inverted""bidirectional""pinch-in""pinch-out"- an array of pan and pinch directions
- structured entries such as
{ gesture: "vertical", area: "edge" }
For non-snap screens, each direction in the array can activate dismissal. For screens with snapPoints, the array defines which pan axes and pinch direction can drive the same snap state. The first direction on a pan axis controls that axis's collapse polarity, and the first pinch direction controls whether pinch-in or pinch-out collapses.
Pan entries can include an activation area:
TSX
area accepts "screen", "edge", or a numeric edge distance in points. Pinch entries ignore area.
Rotation is not a gestureDirection value. When a screen enables pinch-in or pinch-out, rotation runs alongside pinch and publishes gesture.rotation.
Gesture Options
gestureEnabled
Enables swipe-to-dismiss. For screens with snapPoints, snapping between non-dismiss detents can still work when this is false.
| type | default | required |
|---|---|---|
boolean | undefined | No |
gestureDirection
Dismiss direction, pan axis, pinch direction, or ordered direction list.
| type | default | required |
|---|---|---|
GestureDirectionEntry | GestureDirectionEntry[] | "horizontal" | No |
gestureTracking
Controls whether the screen tracks live gesture values.
| type | default | required |
|---|---|---|
"auto" | "never" | "always" | "auto" | No |
gestureActivationArea
Deprecated. Use gestureDirection entries with per-direction area instead.
| type | default | required |
|---|---|---|
GestureActivationArea | "screen" | No |
gestureResponseDistance
Deprecated. Use a numeric area on gestureDirection entries instead.
| type | default | required |
|---|---|---|
number | undefined | No |
gestureSensitivity
Multiplies live gesture movement before it drives progress and non-raw gesture values.
| type | default | required |
|---|---|---|
number | 1 | No |
gestureVelocityImpact
Release velocity influence on dismiss decisions.
| type | default | required |
|---|---|---|
number | 0.3 | No |
gestureProgressMode
Deprecated. Gesture movement now always contributes to progress. Use transitionProgress when an interpolator needs transition progress without live gesture movement.
| type | default | required |
|---|---|---|
"progress-driven" | "freeform" | "progress-driven" | No |
gestureSnapVelocityImpact
Release velocity influence on snap-target selection.
| type | default | required |
|---|---|---|
number | 0.1 | No |
gestureSnapLocked
Locks gesture-driven snap movement to the current detent.
| type | default | required |
|---|---|---|
boolean | false | No |
gestureReleaseVelocityScale
Multiplies normalized release velocity before the spring runs.
| type | default | required |
|---|---|---|
number | 1 | No |
sheetScrollGestureBehavior
Scroll-boundary handoff mode for snap sheets.
| type | default | required |
|---|---|---|
"expand-and-collapse" | "collapse-only" | "expand-and-collapse" | No |
backdropBehavior
Controls how taps on the backdrop are handled.
| type | default | required |
|---|---|---|
"block" | "passthrough" | "dismiss" | "collapse" | stack default | No |
backdropComponent
Custom backdrop component type. Pass a stable component such as BlurView, or pass a function component that renders { styles, props, pointerEvents }.
| type | default | required |
|---|---|---|
React.ComponentType<any> | ScreenBackdropComponent | undefined | No |
contentComponent
Custom renderer for the screen content layer. Use it when a screen needs a custom shell that receives the content slot's animated styles, animated props, pointer events, and children.
| type | default | required |
|---|---|---|
React.ComponentType<any> | ScreenContentComponent | undefined | No |
surfaceComponent
Deprecated custom surface wrapper. It still works for compatibility, but new custom shells should use contentComponent.
| type | default | required |
|---|---|---|
React.ComponentType<any> | undefined | No |
Per-Direction Activation Area
TSX
Configure each active pan direction independently:
TSX
"edge" uses the default edge hit area. A number uses that many points from the edge.
gestureActivationArea still works for compatibility, but new code should use gestureDirection entries with area.
Gesture Response Distance
TSX
gestureResponseDistance is deprecated. Use a numeric area on the pan direction that needs a custom edge-start distance.
Despite the name, the old option controls how far from the edge a gesture may start when a direction uses "edge" activation. It does not change how far the pointer must move before pan activates; that movement threshold is internal.
Release Tuning
These options control how release velocity affects the outcome and the spring feel:
TSX
- use
gestureVelocityImpactto change whether a fling dismisses - use
gestureSnapVelocityImpactto change which snap point a sheet settles to - use
gestureReleaseVelocityScaleto change the release energy used by gesture reset and handoff values
Pinch Gestures
Use pinch-in or pinch-out when two-finger scale should drive dismissal:
TSX
active.gesture.scale, active.gesture.normScale, active.gesture.focalX, and active.gesture.focalY are available inside the interpolator. Use active.gesture.raw.normScale when computing dynamic gestureSensitivity, so the sensitivity calculation does not feed back into itself.
Pan, pinch, and rotation run as a simultaneous gesture composition when the screen config allows them. The gesture that is currently active owns navigation release, while the other gestures can still update live values for animation.
Rotation Values
Screens with pinch-in or pinch-out also track two-finger rotation.
TSX
Use current.gesture.raw.rotation when you need the physical rotation before gestureSensitivity is applied.
Progress During Gestures
progress always includes live gesture movement. This is the value you want when the screen should follow the user's finger.
Use current.transitionProgress when animation logic needs transition or snap progress without the active gesture:
TSX
gestureProgressMode and gestureDrivesProgress remain as deprecated compatibility options. New code should choose between progress and transitionProgress inside the interpolator instead of configuring a screen-level progress mode.
Dynamic Gesture Options
React-side option changes can be applied while the screen stays mounted:
TSX
For per-frame changes from a worklet, return runtime options from the interpolator:
TSX
active.options exposes the resolved option state back to the interpolator, so animation logic can react to values changed by navigation.setOptions() or by previous runtime overrides.
Gesture Tracking
Use gestureTracking when a screen needs explicit control over live gesture values:
TSX
"auto" tracks gestures when dismissal is enabled, or when snap points can move without dismissal. "always" keeps tracking while gestureEnabled is false, which is useful for resistance or shadowing effects where the screen should visually respond to a gesture but must not dismiss. "never" disables tracking for the screen, including snap gestures.
Snap Sheets
Snap sheets are regular screens with snapPoints:
TSX
Two behaviors matter here:
gestureEnabled: falsedisables dismiss at the minimum detent, but the screen can still snap between non-dismiss detentsgestureSnapLockedlocks gesture-driven snap movement to the current detent, while programmatic changes such asnavigation.setOptions()orsnapTo()can still change behavior
If you want to toggle snap locking at runtime:
TSX
Scroll Handoff for Snap Sheets
When a snap sheet contains scroll content, use the transition-aware scrollables:
TSX
sheetScrollGestureBehavior controls what happens when that scroll view reaches its boundary:
expand-and-collapse
At the sheet boundary:
- dragging toward expand can expand the sheet
- dragging toward collapse can collapse or dismiss the sheet
This is the Apple Maps-style behavior.
collapse-only
At the sheet boundary:
- dragging toward collapse can collapse or dismiss the sheet
- dragging from the scrollable content does not expand the sheet
Expansion must start from dead space outside the scrollable content. This is the Instagram-style behavior.
TSX
Scroll Metadata
Transition-aware scrollables publish scroll state through current.layouts.scroll:
TSX
For nested same-axis scrollables, the outermost scrollable owns that axis. Cross-axis nested scrollables can each publish their own axis.
Backdrop Interaction
The supported values are:
"block""passthrough""dismiss""collapse"
Use backdropBehavior: "dismiss" when tapping the backdrop should close the screen, or backdropBehavior: "collapse" when a snap sheet should step down to the next lower detent first.
For a custom backdrop renderer, pass a component type:
TSX
The library wraps the backdrop component with Animated.createAnimatedComponent internally and drives it from the backdrop slot.
Reading Gesture State
Gesture values are exposed inside the interpolator on current.gesture:
TSX
Useful values include:
x,ynormX,normYscale,normScalefocalX,focalYpinchOriginX,pinchOriginYrotationvelocityrawhandoffdraggingdismissingsettlingactivedirection(deprecated pan-only alias)
Live gesture values reset after release. If a dismiss animation needs the last release-time values while the live fields reset, read current.gesture.handoff.
focalX and focalY are live screen coordinates and can move with the fingers. pinchOriginX and pinchOriginY capture the screen-coordinate focal point at activation, which is usually the correct pivot for stable pinch-and-rotate transforms.
Hook Targeting
TSX
useScreenGesture() returns a navigator pan-gesture ref for Gesture Handler relations:
TSX
useScreenGesture() supports depth: 0 for the current screen and negative depths for ancestors. useScreenAnimation() also supports positive depths for descendant transition scopes. Ancestor targeting stops at isolation boundaries. In an independent nested stack, negative depths can resolve to null when the lookup reaches that isolated tree edge.