react-native-screen-transitions 3.2.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,48 +22,57 @@ function ScreenStylesProvider({
22
22
  currentInterpolator
23
23
  } = (0, _useScreenAnimation2._useScreenAnimation)();
24
24
 
25
- // Track when a gesture is triggered while another screen is closing
26
- const hasTriggeredGestureWhileInFlight = (0, _reactNativeReanimated.useSharedValue)(false);
25
+ /**
26
+ * Tracks when user starts a gesture while another screen is still closing.
27
+ * This persists until both the gesture ends AND the closing animation completes.
28
+ */
29
+ const isGesturingDuringCloseAnimation = (0, _reactNativeReanimated.useSharedValue)(false);
27
30
  const stylesMap = (0, _reactNativeReanimated.useDerivedValue)(() => {
28
31
  "worklet";
29
32
 
30
33
  const props = screenInterpolatorProps.value;
31
- const bounds = (0, _bounds.createBounds)(props);
32
-
33
- // Detect when user starts gesture on current screen while next screen is closing
34
- if (props.current.gesture.isDragging && props.next?.closing) {
35
- hasTriggeredGestureWhileInFlight.value = true;
34
+ const {
35
+ current,
36
+ next,
37
+ progress,
38
+ stackProgress
39
+ } = props;
40
+ const isDragging = current.gesture.isDragging;
41
+ const isNextClosing = !!next?.closing;
42
+ if (isDragging && isNextClosing) {
43
+ isGesturingDuringCloseAnimation.value = true;
36
44
  }
37
-
38
- // Reset the flag when no longer dragging and next screen is done closing
39
- if (!props.current.gesture.isDragging && !props.next?.closing && hasTriggeredGestureWhileInFlight.value) {
40
- hasTriggeredGestureWhileInFlight.value = false;
45
+ if (!isDragging && !isNextClosing) {
46
+ isGesturingDuringCloseAnimation.value = false;
41
47
  }
48
+ const isInGestureMode = isDragging || isGesturingDuringCloseAnimation.value;
49
+ const hasPushedScreenWhileClosing = !isInGestureMode && isNextClosing && stackProgress > progress;
42
50
 
43
- // Use current interpolator when gesture triggered while in-flight,
44
- // otherwise use next interpolator if available (normal case)
45
- const shouldUseCurrentInterpolator = props.current.gesture.isDragging || hasTriggeredGestureWhileInFlight.value;
46
- const interpolator = shouldUseCurrentInterpolator ? currentInterpolator : nextInterpolator ?? currentInterpolator;
51
+ // Select interpolator
52
+ // - If in gesture mode, use current screen's interpolator since we're driving
53
+ // the animation from this screen (dragging back to dismiss next).
54
+ const interpolator = isInGestureMode ? currentInterpolator : nextInterpolator ?? currentInterpolator;
55
+ if (!interpolator) return _constants.NO_STYLES;
47
56
 
48
- /**
49
- * Maintainer Note:
50
- * To avoid unnecessary jumps in off directions, we have to snap back to the currents progress.
51
- * While this still introduces a 'snap back' animation, it's still very rare that a user would encounter this unless
52
- * they're spamming things out. Not ideal, but this is the best way to go about dealing with fast rapid gestures.
53
- *
54
- * The alternative was preventing users from actually being able to drag back while animation was still in flight. But there was a significant delay
55
- * when waiting for gestures to register again.
56
- */
57
- const effectiveProps = shouldUseCurrentInterpolator ? {
58
- ...props,
59
- progress: props.current.progress,
60
- next: undefined
61
- } : props;
57
+ // Build effective props with corrected progress
58
+ // - Gesture mode: use current.progress only (avoids jumps during drag)
59
+ // - Pushed while closing: use stackProgress (includes new screen)
60
+ // - Normal: use derived progress as-is
61
+
62
+ let effectiveProgress = progress;
63
+ let effectiveNext = next;
64
+ if (isInGestureMode) {
65
+ effectiveProgress = current.progress;
66
+ effectiveNext = undefined;
67
+ } else if (hasPushedScreenWhileClosing) {
68
+ effectiveProgress = stackProgress;
69
+ }
62
70
  try {
63
- if (!interpolator) return _constants.NO_STYLES;
64
71
  return interpolator({
65
- ...effectiveProps,
66
- bounds
72
+ ...props,
73
+ progress: effectiveProgress,
74
+ next: effectiveNext,
75
+ bounds: (0, _bounds.createBounds)(props)
67
76
  });
68
77
  } catch (err) {
69
78
  if (__DEV__) {
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_reactNativeReanimated","_constants","_useScreenAnimation2","_bounds","_jsxRuntime","ScreenStylesContext","createContext","ScreenStylesProvider","children","parentCtx","useContext","screenInterpolatorProps","nextInterpolator","currentInterpolator","_useScreenAnimation","hasTriggeredGestureWhileInFlight","useSharedValue","stylesMap","useDerivedValue","props","value","bounds","createBounds","current","gesture","isDragging","next","closing","shouldUseCurrentInterpolator","interpolator","effectiveProps","progress","undefined","NO_STYLES","err","__DEV__","console","warn","useMemo","ancestorStylesMaps","jsx","Provider","useScreenStyles","ctx","Error"],"sourceRoot":"../../../../../src","sources":["shared/providers/screen/styles.provider.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_reactNativeReanimated","_constants","_useScreenAnimation2","_bounds","_jsxRuntime","ScreenStylesContext","createContext","ScreenStylesProvider","children","parentCtx","useContext","screenInterpolatorProps","nextInterpolator","currentInterpolator","_useScreenAnimation","isGesturingDuringCloseAnimation","useSharedValue","stylesMap","useDerivedValue","props","value","current","next","progress","stackProgress","isDragging","gesture","isNextClosing","closing","isInGestureMode","hasPushedScreenWhileClosing","interpolator","NO_STYLES","effectiveProgress","effectiveNext","undefined","bounds","createBounds","err","__DEV__","console","warn","useMemo","ancestorStylesMaps","jsx","Provider","useScreenStyles","ctx","Error"],"sourceRoot":"../../../../../src","sources":["shared/providers/screen/styles.provider.tsx"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,sBAAA,GAAAD,OAAA;AAKA,IAAAE,UAAA,GAAAF,OAAA;AACA,IAAAG,oBAAA,GAAAH,OAAA;AAEA,IAAAI,OAAA,GAAAJ,OAAA;AAAkD,IAAAK,WAAA,GAAAL,OAAA;AAWlD,MAAMM,mBAAmB,gBAAG,IAAAC,oBAAa,EACxC,IACD,CAAC;AAEM,SAASC,oBAAoBA,CAAC;EAAEC;AAAgB,CAAC,EAAE;EACzD,MAAMC,SAAS,GAAG,IAAAC,iBAAU,EAACL,mBAAmB,CAAC;EAEjD,MAAM;IAAEM,uBAAuB;IAAEC,gBAAgB;IAAEC;EAAoB,CAAC,GACvE,IAAAC,wCAAmB,EAAC,CAAC;;EAEtB;AACD;AACA;AACA;EACC,MAAMC,+BAA+B,GAAG,IAAAC,qCAAc,EAAC,KAAK,CAAC;EAE7D,MAAMC,SAAS,GAAG,IAAAC,sCAAe,EAA8B,MAAM;IACpE,SAAS;;IACT,MAAMC,KAAK,GAAGR,uBAAuB,CAACS,KAAK;IAC3C,MAAM;MAAEC,OAAO;MAAEC,IAAI;MAAEC,QAAQ;MAAEC;IAAc,CAAC,GAAGL,KAAK;IACxD,MAAMM,UAAU,GAAGJ,OAAO,CAACK,OAAO,CAACD,UAAU;IAC7C,MAAME,aAAa,GAAG,CAAC,CAACL,IAAI,EAAEM,OAAO;IAErC,IAAIH,UAAU,IAAIE,aAAa,EAAE;MAChCZ,+BAA+B,CAACK,KAAK,GAAG,IAAI;IAC7C;IAEA,IAAI,CAACK,UAAU,IAAI,CAACE,aAAa,EAAE;MAClCZ,+BAA+B,CAACK,KAAK,GAAG,KAAK;IAC9C;IAEA,MAAMS,eAAe,GAAGJ,UAAU,IAAIV,+BAA+B,CAACK,KAAK;IAE3E,MAAMU,2BAA2B,GAChC,CAACD,eAAe,IAAIF,aAAa,IAAIH,aAAa,GAAGD,QAAQ;;IAE9D;IACA;IACA;IACA,MAAMQ,YAAY,GAAGF,eAAe,GACjChB,mBAAmB,GAClBD,gBAAgB,IAAIC,mBAAoB;IAE5C,IAAI,CAACkB,YAAY,EAAE,OAAOC,oBAAS;;IAEnC;IACA;IACA;IACA;;IAEA,IAAIC,iBAAiB,GAAGV,QAAQ;IAChC,IAAIW,aAAa,GAAGZ,IAAI;IAExB,IAAIO,eAAe,EAAE;MACpBI,iBAAiB,GAAGZ,OAAO,CAACE,QAAQ;MACpCW,aAAa,GAAGC,SAAS;IAC1B,CAAC,MAAM,IAAIL,2BAA2B,EAAE;MACvCG,iBAAiB,GAAGT,aAAa;IAClC;IAEA,IAAI;MACH,OAAOO,YAAY,CAAC;QACnB,GAAGZ,KAAK;QACRI,QAAQ,EAAEU,iBAAiB;QAC3BX,IAAI,EAAEY,aAAa;QACnBE,MAAM,EAAE,IAAAC,oBAAY,EAAClB,KAAK;MAC3B,CAAC,CAAC;IACH,CAAC,CAAC,OAAOmB,GAAG,EAAE;MACb,IAAIC,OAAO,EAAE;QACZC,OAAO,CAACC,IAAI,CACX,6EAA6E,EAC7EH,GACD,CAAC;MACF;MACA,OAAON,oBAAS;IACjB;EACD,CAAC,CAAC;EAEF,MAAMZ,KAAK,GAAG,IAAAsB,cAAO,EAAC,MAAM;IAC3B;IACA,MAAMC,kBAAkB,GAAGlC,SAAS,GACjC,CAACA,SAAS,CAACQ,SAAS,EAAE,GAAGR,SAAS,CAACkC,kBAAkB,CAAC,GACtD,EAAE;IAEL,OAAO;MACN1B,SAAS;MACT0B;IACD,CAAC;EACF,CAAC,EAAE,CAAC1B,SAAS,EAAER,SAAS,CAAC,CAAC;EAE1B,oBACC,IAAAL,WAAA,CAAAwC,GAAA,EAACvC,mBAAmB,CAACwC,QAAQ;IAACzB,KAAK,EAAEA,KAAM;IAAAZ,QAAA,EACzCA;EAAQ,CACoB,CAAC;AAEjC;AAEO,SAASsC,eAAeA,CAAA,EAAG;EACjC,MAAMC,GAAG,GAAG,IAAArC,iBAAU,EAACL,mBAAmB,CAAC;EAC3C,IAAI,CAAC0C,GAAG,EAAE;IACT,MAAM,IAAIC,KAAK,CACd,4DACD,CAAC;EACF;EACA,OAAOD,GAAG;AACX","ignoreList":[]}
@@ -17,48 +17,57 @@ export function ScreenStylesProvider({
17
17
  currentInterpolator
18
18
  } = _useScreenAnimation();
19
19
 
20
- // Track when a gesture is triggered while another screen is closing
21
- const hasTriggeredGestureWhileInFlight = useSharedValue(false);
20
+ /**
21
+ * Tracks when user starts a gesture while another screen is still closing.
22
+ * This persists until both the gesture ends AND the closing animation completes.
23
+ */
24
+ const isGesturingDuringCloseAnimation = useSharedValue(false);
22
25
  const stylesMap = useDerivedValue(() => {
23
26
  "worklet";
24
27
 
25
28
  const props = screenInterpolatorProps.value;
26
- const bounds = createBounds(props);
27
-
28
- // Detect when user starts gesture on current screen while next screen is closing
29
- if (props.current.gesture.isDragging && props.next?.closing) {
30
- hasTriggeredGestureWhileInFlight.value = true;
29
+ const {
30
+ current,
31
+ next,
32
+ progress,
33
+ stackProgress
34
+ } = props;
35
+ const isDragging = current.gesture.isDragging;
36
+ const isNextClosing = !!next?.closing;
37
+ if (isDragging && isNextClosing) {
38
+ isGesturingDuringCloseAnimation.value = true;
31
39
  }
32
-
33
- // Reset the flag when no longer dragging and next screen is done closing
34
- if (!props.current.gesture.isDragging && !props.next?.closing && hasTriggeredGestureWhileInFlight.value) {
35
- hasTriggeredGestureWhileInFlight.value = false;
40
+ if (!isDragging && !isNextClosing) {
41
+ isGesturingDuringCloseAnimation.value = false;
36
42
  }
43
+ const isInGestureMode = isDragging || isGesturingDuringCloseAnimation.value;
44
+ const hasPushedScreenWhileClosing = !isInGestureMode && isNextClosing && stackProgress > progress;
37
45
 
38
- // Use current interpolator when gesture triggered while in-flight,
39
- // otherwise use next interpolator if available (normal case)
40
- const shouldUseCurrentInterpolator = props.current.gesture.isDragging || hasTriggeredGestureWhileInFlight.value;
41
- const interpolator = shouldUseCurrentInterpolator ? currentInterpolator : nextInterpolator ?? currentInterpolator;
46
+ // Select interpolator
47
+ // - If in gesture mode, use current screen's interpolator since we're driving
48
+ // the animation from this screen (dragging back to dismiss next).
49
+ const interpolator = isInGestureMode ? currentInterpolator : nextInterpolator ?? currentInterpolator;
50
+ if (!interpolator) return NO_STYLES;
42
51
 
43
- /**
44
- * Maintainer Note:
45
- * To avoid unnecessary jumps in off directions, we have to snap back to the currents progress.
46
- * While this still introduces a 'snap back' animation, it's still very rare that a user would encounter this unless
47
- * they're spamming things out. Not ideal, but this is the best way to go about dealing with fast rapid gestures.
48
- *
49
- * The alternative was preventing users from actually being able to drag back while animation was still in flight. But there was a significant delay
50
- * when waiting for gestures to register again.
51
- */
52
- const effectiveProps = shouldUseCurrentInterpolator ? {
53
- ...props,
54
- progress: props.current.progress,
55
- next: undefined
56
- } : props;
52
+ // Build effective props with corrected progress
53
+ // - Gesture mode: use current.progress only (avoids jumps during drag)
54
+ // - Pushed while closing: use stackProgress (includes new screen)
55
+ // - Normal: use derived progress as-is
56
+
57
+ let effectiveProgress = progress;
58
+ let effectiveNext = next;
59
+ if (isInGestureMode) {
60
+ effectiveProgress = current.progress;
61
+ effectiveNext = undefined;
62
+ } else if (hasPushedScreenWhileClosing) {
63
+ effectiveProgress = stackProgress;
64
+ }
57
65
  try {
58
- if (!interpolator) return NO_STYLES;
59
66
  return interpolator({
60
- ...effectiveProps,
61
- bounds
67
+ ...props,
68
+ progress: effectiveProgress,
69
+ next: effectiveNext,
70
+ bounds: createBounds(props)
62
71
  });
63
72
  } catch (err) {
64
73
  if (__DEV__) {
@@ -1 +1 @@
1
- {"version":3,"names":["createContext","useContext","useMemo","useDerivedValue","useSharedValue","NO_STYLES","_useScreenAnimation","createBounds","jsx","_jsx","ScreenStylesContext","ScreenStylesProvider","children","parentCtx","screenInterpolatorProps","nextInterpolator","currentInterpolator","hasTriggeredGestureWhileInFlight","stylesMap","props","value","bounds","current","gesture","isDragging","next","closing","shouldUseCurrentInterpolator","interpolator","effectiveProps","progress","undefined","err","__DEV__","console","warn","ancestorStylesMaps","Provider","useScreenStyles","ctx","Error"],"sourceRoot":"../../../../../src","sources":["shared/providers/screen/styles.provider.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["createContext","useContext","useMemo","useDerivedValue","useSharedValue","NO_STYLES","_useScreenAnimation","createBounds","jsx","_jsx","ScreenStylesContext","ScreenStylesProvider","children","parentCtx","screenInterpolatorProps","nextInterpolator","currentInterpolator","isGesturingDuringCloseAnimation","stylesMap","props","value","current","next","progress","stackProgress","isDragging","gesture","isNextClosing","closing","isInGestureMode","hasPushedScreenWhileClosing","interpolator","effectiveProgress","effectiveNext","undefined","bounds","err","__DEV__","console","warn","ancestorStylesMaps","Provider","useScreenStyles","ctx","Error"],"sourceRoot":"../../../../../src","sources":["shared/providers/screen/styles.provider.tsx"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.provider.d.ts","sourceRoot":"","sources":["../../../../../src/shared/providers/screen/styles.provider.tsx"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,WAAW,EAGhB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAG/E,KAAK,KAAK,GAAG;IACZ,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC/B,SAAS,EAAE,WAAW,CAAC,2BAA2B,CAAC,CAAC;IACpD,kBAAkB,EAAE,WAAW,CAAC,2BAA2B,CAAC,EAAE,CAAC;CAC/D,CAAC;AAMF,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAqFvD;AAED,wBAAgB,eAAe,6BAQ9B"}
1
+ {"version":3,"file":"styles.provider.d.ts","sourceRoot":"","sources":["../../../../../src/shared/providers/screen/styles.provider.tsx"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,WAAW,EAGhB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAG/E,KAAK,KAAK,GAAG;IACZ,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC/B,SAAS,EAAE,WAAW,CAAC,2BAA2B,CAAC,CAAC;IACpD,kBAAkB,EAAE,WAAW,CAAC,2BAA2B,CAAC,EAAE,CAAC;CAC/D,CAAC;AAMF,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,2CA2FvD;AAED,wBAAgB,eAAe,6BAQ9B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-screen-transitions",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "Easy screen transitions for React Native and Expo",
5
5
  "author": "Ed",
6
6
  "license": "MIT",
@@ -43,7 +43,8 @@
43
43
  "build": "bob build",
44
44
  "lint": "biome check ./src",
45
45
  "typecheck": "tsc --noEmit",
46
- "prepublishOnly": "bun run build"
46
+ "prepublishOnly": "bun run build",
47
+ "release": "release-it"
47
48
  },
48
49
  "keywords": [
49
50
  "react-native",
@@ -73,8 +74,10 @@
73
74
  "react-native-screens": ">=4.4.0"
74
75
  },
75
76
  "devDependencies": {
77
+ "@release-it/conventional-changelog": "^10.0.1",
76
78
  "@types/react": "~19.1.10",
77
79
  "react-native-builder-bob": "0.39.0",
80
+ "release-it": "^19.0.4",
78
81
  "typescript": "catalog:"
79
82
  },
80
83
  "react-native-builder-bob": {
@@ -91,5 +94,28 @@
91
94
  ]
92
95
  ]
93
96
  },
97
+ "release-it": {
98
+ "git": {
99
+ "commitMessage": "chore: release ${version}",
100
+ "tagName": "v${version}",
101
+ "commitArgs": [
102
+ "-n"
103
+ ]
104
+ },
105
+ "npm": {
106
+ "publish": true
107
+ },
108
+ "github": {
109
+ "release": true
110
+ },
111
+ "plugins": {
112
+ "@release-it/conventional-changelog": {
113
+ "preset": {
114
+ "name": "angular"
115
+ },
116
+ "path": "."
117
+ }
118
+ }
119
+ },
94
120
  "gitHead": "888d4df9936ec0e3b8221bea7cd81115e6301693"
95
121
  }
@@ -28,56 +28,62 @@ export function ScreenStylesProvider({ children }: Props) {
28
28
  const { screenInterpolatorProps, nextInterpolator, currentInterpolator } =
29
29
  _useScreenAnimation();
30
30
 
31
- // Track when a gesture is triggered while another screen is closing
32
- const hasTriggeredGestureWhileInFlight = useSharedValue(false);
31
+ /**
32
+ * Tracks when user starts a gesture while another screen is still closing.
33
+ * This persists until both the gesture ends AND the closing animation completes.
34
+ */
35
+ const isGesturingDuringCloseAnimation = useSharedValue(false);
33
36
 
34
37
  const stylesMap = useDerivedValue<TransitionInterpolatedStyle>(() => {
35
38
  "worklet";
36
39
  const props = screenInterpolatorProps.value;
37
- const bounds = createBounds(props);
40
+ const { current, next, progress, stackProgress } = props;
41
+ const isDragging = current.gesture.isDragging;
42
+ const isNextClosing = !!next?.closing;
38
43
 
39
- // Detect when user starts gesture on current screen while next screen is closing
40
- if (props.current.gesture.isDragging && props.next?.closing) {
41
- hasTriggeredGestureWhileInFlight.value = true;
44
+ if (isDragging && isNextClosing) {
45
+ isGesturingDuringCloseAnimation.value = true;
42
46
  }
43
47
 
44
- // Reset the flag when no longer dragging and next screen is done closing
45
- if (
46
- !props.current.gesture.isDragging &&
47
- !props.next?.closing &&
48
- hasTriggeredGestureWhileInFlight.value
49
- ) {
50
- hasTriggeredGestureWhileInFlight.value = false;
48
+ if (!isDragging && !isNextClosing) {
49
+ isGesturingDuringCloseAnimation.value = false;
51
50
  }
52
51
 
53
- // Use current interpolator when gesture triggered while in-flight,
54
- // otherwise use next interpolator if available (normal case)
55
- const shouldUseCurrentInterpolator =
56
- props.current.gesture.isDragging ||
57
- hasTriggeredGestureWhileInFlight.value;
52
+ const isInGestureMode = isDragging || isGesturingDuringCloseAnimation.value;
58
53
 
59
- const interpolator = shouldUseCurrentInterpolator
54
+ const hasPushedScreenWhileClosing =
55
+ !isInGestureMode && isNextClosing && stackProgress > progress;
56
+
57
+ // Select interpolator
58
+ // - If in gesture mode, use current screen's interpolator since we're driving
59
+ // the animation from this screen (dragging back to dismiss next).
60
+ const interpolator = isInGestureMode
60
61
  ? currentInterpolator
61
62
  : (nextInterpolator ?? currentInterpolator);
62
63
 
63
- /**
64
- * Maintainer Note:
65
- * To avoid unnecessary jumps in off directions, we have to snap back to the currents progress.
66
- * While this still introduces a 'snap back' animation, it's still very rare that a user would encounter this unless
67
- * they're spamming things out. Not ideal, but this is the best way to go about dealing with fast rapid gestures.
68
- *
69
- * The alternative was preventing users from actually being able to drag back while animation was still in flight. But there was a significant delay
70
- * when waiting for gestures to register again.
71
- */
72
- const effectiveProps = shouldUseCurrentInterpolator
73
- ? { ...props, progress: props.current.progress, next: undefined }
74
- : props;
64
+ if (!interpolator) return NO_STYLES;
65
+
66
+ // Build effective props with corrected progress
67
+ // - Gesture mode: use current.progress only (avoids jumps during drag)
68
+ // - Pushed while closing: use stackProgress (includes new screen)
69
+ // - Normal: use derived progress as-is
70
+
71
+ let effectiveProgress = progress;
72
+ let effectiveNext = next;
73
+
74
+ if (isInGestureMode) {
75
+ effectiveProgress = current.progress;
76
+ effectiveNext = undefined;
77
+ } else if (hasPushedScreenWhileClosing) {
78
+ effectiveProgress = stackProgress;
79
+ }
75
80
 
76
81
  try {
77
- if (!interpolator) return NO_STYLES;
78
82
  return interpolator({
79
- ...effectiveProps,
80
- bounds,
83
+ ...props,
84
+ progress: effectiveProgress,
85
+ next: effectiveNext,
86
+ bounds: createBounds(props),
81
87
  });
82
88
  } catch (err) {
83
89
  if (__DEV__) {