Gesture Progress Mode
v3.6 added gestureProgressMode to describe whether gestures should drive screen progress.
In v3.8, gestureProgressMode is deprecated. Current code should use progress for visual progress and transitionProgress when an animation needs transition progress without live gesture movement.
TSX
Use "progress-driven" when drag movement should directly move screen progress. Use "freeform" when gesture values should drive custom visuals while transition progress stays controlled by navigation or release.
This deprecated gestureDrivesProgress in favor of a more descriptive option name. The older gestureDrivesProgress: false form still maps to "freeform" for compatibility.
Gesture Tracking
v3.6 adds gestureTracking for screens that need explicit control over whether gestures produce live gesture values.
TSX
Use "auto" for the default behavior: gestures track when dismissal is enabled, or when snap points can move without dismissal. Use "always" when a disabled gesture should still drive custom visuals without allowing dismiss. Use "never" when a screen should not track gestures at all, including snap gestures.
gestureTracking: "always" replaces the earlier experimental disabled-gesture tracking option.
Unified Gesture State
Gesture state now covers pan and pinch through the same active.gesture object:
TSX
Use active.gesture.raw when calculating dynamic gestureSensitivity so sensitivity does not feed back into itself.
Runtime Options in Interpolators
Interpolators can now return an options bucket for values that need to change on the UI thread:
TSX
Screen states also expose resolved options through current.options, active.options, and next?.options, so animation logic can react to base screen options, navigation.setOptions() changes, and runtime overrides.
Dismiss Gesture Persistence
v3.6 changes gesture reset behavior on release. When the gesture resolves to dismissal, the runtime keeps the release gesture values available during the dismiss animation. When the gesture does not dismiss, the runtime resets the gesture values as it settles back.
This lets dismissed screens keep using the release drag and velocity for fling-style animations, while cancelled gestures cleanly return to their resting visual state.
Snap State
Snap state is split into live and target values:
current.animatedSnapIndexfollows live gesture and animation movement, including fractional values between detentscurrent.snapIndexfollows the selected target detent after mount,snapTo(), or gesture release
TSX
For snap release targeting, use gestureSnapVelocityImpact:
TSX
Reveal Navigation
v3.6 adds bounds({ id }).navigation.reveal() for masked source-to-container navigation transitions.
Reveal requires a source boundary, a matching destination boundary, and the static navigationMaskEnabled screen option. The helper exposes tuning options such as borderRadius, borderContinuous, maxSensitivity, velocityDepth, disablePointerEventsTillElementTransition, and maskSizingMode.
Read the full setup in Reveal.
Bounds Runtime
Scoped bounds results expose helper methods directly:
TSX
Bounds also gained more stable grouped-link measurement, source/destination snapshot handling, and transition-pair resolution. These are mostly internal, but they make grouped shared boundaries and navigation helpers less likely to flicker, blank, or retarget against stale measurements.
Internally, bounds links are now keyed by screen pair instead of a single global id. A pair owns its links, group active id, initial source, and initial destination, which keeps the same bound id from leaking between unrelated route pairs and makes retargeted grouped transitions deterministic.
Use offset when adding live x/y movement to bounds:
TSX
Hook Targets
Transition and gesture hooks now prefer depth targets:
TSX
useScreenGesture() resolves the current screen and ancestors only. useScreenAnimation() still accepts legacy string targets such as "parent" and "root", but new code should use { depth }.
Migration Checklist
- For v3.6 projects, replace new
gestureDrivesProgressusage withgestureProgressMode. In v3.8 and later, useprogressortransitionProgressinstead. - Use
gestureTracking: "always"when disabled gestures should keep producing live gesture values for custom visuals. - Prefer
active.gesture.activeover the older pan-onlyactive.gesture.direction. - Use
active.gesture.rawwhen deriving dynamicgestureSensitivity. - Return
optionsfromscreenStyleInterpolatorfor UI-thread option changes, and read resolved values fromactive.optionswhen animation logic depends on them. - Use
gestureSnapVelocityImpactinstead ofsnapVelocityImpactfor snap release targeting. - Use
current.animatedSnapIndexfor live snap visuals andcurrent.snapIndexfor selected target logic. - For v3.6 projects, use
current.logicallySettled,active.logicallySettled, ornext?.logicallySettledinstead of the deprecated top-levellogicallySettledalias. In v3.8 and later, usesettled. - Use scoped bounds helpers such as
bounds({ id }).getMeasured()andbounds({ id }).getLink(). - Use
offsetinstead of the oldergesturesbounds option. - Use
getMeasured()instead of the deprecatedgetSnapshot()alias. - Use layer slots such as
content,backdrop,surface, and style id keys instead of legacy flat interpolator keys such ascontentStyle,backdropStyle, andoverlayStyle.
Compatibility Notes
gestureDrivesProgressstill maps togestureProgressMode, and both are deprecated in v3.8.gestureTrackingis static and is not supported inside interpolator-returned runtimeoptions.expandViaScrollViewstill maps tosheetScrollGestureBehavior.getSnapshot()still exists as a deprecated alias forgetMeasured().active.gesture.directionstill exists as a deprecated pan-only alias foractive.gesture.active.gestureReleaseVelocityMaxremains in the static screen option type as deprecated compatibility surface, but it is not read by runtime transition options.