react-native-screen-transitions 2.4.0 → 2.4.2

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.
Files changed (82) hide show
  1. package/lib/commonjs/constants.js.map +1 -1
  2. package/lib/commonjs/hooks/animation/use-screen-animation.js +9 -5
  3. package/lib/commonjs/hooks/animation/use-screen-animation.js.map +1 -1
  4. package/lib/commonjs/providers/transition-styles.js +18 -4
  5. package/lib/commonjs/providers/transition-styles.js.map +1 -1
  6. package/lib/commonjs/utils/animation/derivations.js +1 -14
  7. package/lib/commonjs/utils/animation/derivations.js.map +1 -1
  8. package/lib/commonjs/utils/bounds/_utils/styles.js.map +1 -1
  9. package/lib/commonjs/utils/bounds/constants.js.map +1 -1
  10. package/lib/commonjs/utils/bounds/index.js +23 -90
  11. package/lib/commonjs/utils/bounds/index.js.map +1 -1
  12. package/lib/commonjs/utils/gesture/apply-offset-rules.js.map +1 -1
  13. package/lib/commonjs/utils/gesture/check-gesture-activation.js.map +1 -1
  14. package/lib/commonjs/utils/gesture/reset-gesture-values.js.map +1 -1
  15. package/lib/commonjs/utils/gesture/velocity.js +2 -2
  16. package/lib/commonjs/utils/gesture/velocity.js.map +1 -1
  17. package/lib/module/constants.js.map +1 -1
  18. package/lib/module/hooks/animation/use-screen-animation.js +9 -5
  19. package/lib/module/hooks/animation/use-screen-animation.js.map +1 -1
  20. package/lib/module/providers/transition-styles.js +19 -5
  21. package/lib/module/providers/transition-styles.js.map +1 -1
  22. package/lib/module/utils/animation/derivations.js +1 -14
  23. package/lib/module/utils/animation/derivations.js.map +1 -1
  24. package/lib/module/utils/bounds/_utils/styles.js.map +1 -1
  25. package/lib/module/utils/bounds/constants.js.map +1 -1
  26. package/lib/module/utils/bounds/index.js +24 -91
  27. package/lib/module/utils/bounds/index.js.map +1 -1
  28. package/lib/module/utils/gesture/apply-offset-rules.js.map +1 -1
  29. package/lib/module/utils/gesture/check-gesture-activation.js.map +1 -1
  30. package/lib/module/utils/gesture/reset-gesture-values.js.map +1 -1
  31. package/lib/module/utils/gesture/velocity.js +2 -2
  32. package/lib/module/utils/gesture/velocity.js.map +1 -1
  33. package/lib/typescript/constants.d.ts +2 -2
  34. package/lib/typescript/constants.d.ts.map +1 -1
  35. package/lib/typescript/hooks/animation/use-screen-animation.d.ts +1 -1
  36. package/lib/typescript/hooks/animation/use-screen-animation.d.ts.map +1 -1
  37. package/lib/typescript/index.d.ts +8 -8
  38. package/lib/typescript/providers/transition-styles.d.ts.map +1 -1
  39. package/lib/typescript/types/animation.d.ts +2 -4
  40. package/lib/typescript/types/animation.d.ts.map +1 -1
  41. package/lib/typescript/types/bounds.d.ts +0 -57
  42. package/lib/typescript/types/bounds.d.ts.map +1 -1
  43. package/lib/typescript/types/navigator.d.ts +4 -0
  44. package/lib/typescript/types/navigator.d.ts.map +1 -1
  45. package/lib/typescript/types/utils.d.ts.map +1 -1
  46. package/lib/typescript/utils/animation/derivations.d.ts +1 -4
  47. package/lib/typescript/utils/animation/derivations.d.ts.map +1 -1
  48. package/lib/typescript/utils/bounds/_types/builder.d.ts +2 -2
  49. package/lib/typescript/utils/bounds/_types/builder.d.ts.map +1 -1
  50. package/lib/typescript/utils/bounds/_utils/geometry.d.ts +2 -2
  51. package/lib/typescript/utils/bounds/_utils/geometry.d.ts.map +1 -1
  52. package/lib/typescript/utils/bounds/_utils/styles.d.ts +2 -1
  53. package/lib/typescript/utils/bounds/_utils/styles.d.ts.map +1 -1
  54. package/lib/typescript/utils/bounds/constants.d.ts +2 -2
  55. package/lib/typescript/utils/bounds/constants.d.ts.map +1 -1
  56. package/lib/typescript/utils/bounds/index.d.ts +4 -4
  57. package/lib/typescript/utils/bounds/index.d.ts.map +1 -1
  58. package/lib/typescript/utils/gesture/apply-offset-rules.d.ts +2 -2
  59. package/lib/typescript/utils/gesture/apply-offset-rules.d.ts.map +1 -1
  60. package/lib/typescript/utils/gesture/check-gesture-activation.d.ts +2 -2
  61. package/lib/typescript/utils/gesture/check-gesture-activation.d.ts.map +1 -1
  62. package/lib/typescript/utils/gesture/reset-gesture-values.d.ts.map +1 -1
  63. package/lib/typescript/utils/gesture/velocity.d.ts +1 -1
  64. package/lib/typescript/utils/gesture/velocity.d.ts.map +1 -1
  65. package/package.json +1 -1
  66. package/src/constants.ts +2 -2
  67. package/src/hooks/animation/use-screen-animation.tsx +51 -46
  68. package/src/providers/transition-styles.tsx +24 -11
  69. package/src/types/animation.ts +2 -4
  70. package/src/types/bounds.ts +0 -64
  71. package/src/types/navigator.ts +5 -0
  72. package/src/types/utils.ts +1 -0
  73. package/src/utils/animation/derivations.ts +3 -20
  74. package/src/utils/bounds/_types/builder.ts +2 -2
  75. package/src/utils/bounds/_utils/geometry.ts +2 -2
  76. package/src/utils/bounds/_utils/styles.ts +2 -1
  77. package/src/utils/bounds/constants.ts +2 -2
  78. package/src/utils/bounds/index.ts +35 -105
  79. package/src/utils/gesture/apply-offset-rules.ts +3 -3
  80. package/src/utils/gesture/check-gesture-activation.ts +3 -3
  81. package/src/utils/gesture/reset-gesture-values.ts +1 -0
  82. package/src/utils/gesture/velocity.ts +1 -2
@@ -14,76 +14,12 @@ import type { ScreenPhase } from "./core";
14
14
  */
15
15
  export type BoundsMethod = "transform" | "size" | "content";
16
16
 
17
- export type BoundsBuilder = {
18
- /**
19
- * Include gesture offsets (x/y) in the computed transform for all methods.
20
- * This syncs the focused screen’s gesture deltas with the previous screen’s bound
21
- * to give the shared look while interacting.
22
- */
23
- gestures: (options?: { x?: number; y?: number }) => BoundsBuilder;
24
-
25
- /**
26
- * Animate to the full screen bounds as the destination.
27
- * Useful when the next screen does not define a bound for the same id.
28
- */
29
- toFullscreen: () => BoundsBuilder;
30
-
31
- /**
32
- * Compute using absolute window coordinates (pageX/pageY).
33
- * No relative delta math—good when elements are unconstrained by parent layout.
34
- */
35
- absolute: () => BoundsBuilder;
36
-
37
- /**
38
- * Compute using relative deltas between start/end bounds (dx/dy, scale).
39
- * This makes the math bound-relative; great when elements are within layout constraints.
40
- */
41
- relative: () => BoundsBuilder;
42
-
43
- /**
44
- * Select transform method: translate + scaleX/scaleY (no width/height size).
45
- * Note: x/y translation is applied for all methods when applicable.
46
- */
47
- transform: () => BoundsBuilder;
48
-
49
- /**
50
- * Select size method: translate + width/height interpolation (no scaleX/scaleY).
51
- */
52
- size: () => BoundsBuilder;
53
-
54
- /**
55
- * Select content method: screen-level transform to align destination content
56
- * so its bound matches the source at progress start. This modifies where the
57
- * bound sits within the screen rather than the bound’s own local transform.
58
- */
59
- content: () => BoundsBuilder;
60
-
61
- /**
62
- * Select content scale mode: "aspectFill" (fill), "aspectFit" (fit), or "auto" (default).
63
- */
64
- contentFill: () => BoundsBuilder;
65
-
66
- /**
67
- * Select content scale mode: "aspectFill" (fill), "aspectFit" (fit), or "auto" (default).
68
- */
69
- contentFit: () => BoundsBuilder;
70
-
71
- /**
72
- * Build the final animated style.
73
- * If a method is not explicitly selected via transform/resize/content,
74
- * the provided argument will be used; defaults to "transform".
75
- */
76
- build: (method?: BoundsMethod) => StyleProps;
77
- };
78
-
79
17
  export type BoundEntry = {
80
18
  bounds: MeasuredDimensions;
81
19
  styles: StyleProps;
82
20
  };
83
21
 
84
22
  export type BoundsAccessor = {
85
- (id: string): BoundsBuilder;
86
- (): BoundsBuilder;
87
23
  <T extends BoundsBuilderOptions>(options: T): BoundsReturnType<T>;
88
24
  get: (id?: string, phase?: ScreenPhase) => BoundEntry;
89
25
  };
@@ -25,6 +25,11 @@ import type {
25
25
  import type { ScreenStyleInterpolator, TransitionSpec } from "./animation";
26
26
  import type { GestureActivationArea, GestureDirection } from "./gesture";
27
27
 
28
+ export type Layout = {
29
+ width: number;
30
+ height: number;
31
+ };
32
+
28
33
  export type NativeStackNavigationEventMap = {
29
34
  /**
30
35
  * Event which fires when a transition animation starts.
@@ -1,3 +1,4 @@
1
+ // biome-ignore lint/suspicious/noExplicitAny: <>
1
2
  export type Any = any;
2
3
 
3
4
  export type Complete<T> = { [K in keyof T]-?: Exclude<T[K], undefined> };
@@ -1,25 +1,18 @@
1
- import type { ScaledSize } from "react-native";
2
1
  import { Bounds } from "../../stores/bounds";
3
2
  import type { ScreenTransitionState } from "../../types/animation";
4
- import { createBounds } from "../bounds";
5
3
 
6
4
  interface DerivationsParams {
7
5
  current: ScreenTransitionState;
8
6
  next?: ScreenTransitionState;
9
7
  previous?: ScreenTransitionState;
10
- dimensions: ScaledSize;
11
8
  }
12
9
 
13
10
  /**
14
11
  * Additional values to help make defining animations easier.
15
12
  */
16
- export const derivations = ({
17
- current,
18
- next,
19
- previous,
20
- dimensions,
21
- }: DerivationsParams) => {
13
+ export const derivations = ({ current, next, previous }: DerivationsParams) => {
22
14
  "worklet";
15
+
23
16
  // The combined progress
24
17
  const progress = current.progress + (next?.progress ?? 0);
25
18
 
@@ -30,26 +23,16 @@ export const derivations = ({
30
23
  const isActiveTransitioning = !!(
31
24
  active.gesture.isDragging || active.animating
32
25
  );
26
+
33
27
  const isDismissing = !!(active.gesture.isDismissing || active.closing);
34
28
 
35
29
  // The active bound id
36
30
  const activeBoundId = Bounds.getActiveBound(current, next, previous);
37
31
 
38
- // bounds api
39
- const bounds = createBounds({
40
- activeBoundId,
41
- current,
42
- previous,
43
- next,
44
- progress,
45
- dimensions,
46
- });
47
-
48
32
  return {
49
33
  progress,
50
34
  focused,
51
35
  activeBoundId,
52
- bounds,
53
36
  active,
54
37
  isActiveTransitioning,
55
38
  isDismissing,
@@ -1,7 +1,7 @@
1
- import type { ScaledSize } from "react-native";
2
1
  import type { MeasuredDimensions, StyleProps } from "react-native-reanimated";
3
2
  import type { ScreenTransitionState } from "../../../types/animation";
4
3
  import type { BoundsMethod } from "../../../types/bounds";
4
+ import type { Layout } from "../../../types/navigator";
5
5
 
6
6
  /**
7
7
  * Params passed to the builder initializer. No method required here.
@@ -12,7 +12,7 @@ export type BoundsBuilderInitParams = {
12
12
  current: ScreenTransitionState;
13
13
  next?: ScreenTransitionState;
14
14
  progress: number;
15
- dimensions: ScaledSize;
15
+ dimensions: Layout;
16
16
  };
17
17
 
18
18
  export type BoundsAnchor =
@@ -1,5 +1,5 @@
1
- import type { ScaledSize } from "react-native";
2
1
  import type { MeasuredDimensions } from "react-native-reanimated";
2
+ import type { Layout } from "../../../types/navigator";
3
3
  import type { BoundsAnchor, BoundsScaleMode } from "../_types/builder";
4
4
  import type {
5
5
  ContentTransformGeometry,
@@ -109,7 +109,7 @@ export function computeContentTransformGeometry({
109
109
  start: MeasuredDimensions;
110
110
  end: MeasuredDimensions;
111
111
  entering: boolean;
112
- dimensions: ScaledSize;
112
+ dimensions: Layout;
113
113
  anchor?: BoundsAnchor;
114
114
  scaleMode?: BoundsScaleMode;
115
115
  }): ContentTransformGeometry {
@@ -1,9 +1,10 @@
1
1
  import type { ImageStyle, StyleProp, TextStyle, ViewStyle } from "react-native";
2
2
  import { isSharedValue } from "react-native-reanimated";
3
+ import type { Any } from "../../../types/utils";
3
4
 
4
5
  type AnyStyle = ViewStyle | TextStyle | ImageStyle;
5
6
  type StyleValue = StyleProp<AnyStyle>;
6
- type PlainStyleObject = Record<string, any>;
7
+ type PlainStyleObject = Record<string, Any>;
7
8
 
8
9
  function mergeStyleArrays<T extends StyleValue>(style: T): T {
9
10
  "worklet";
@@ -1,10 +1,10 @@
1
- import type { ScaledSize } from "react-native";
2
1
  import type { MeasuredDimensions } from "react-native-reanimated";
3
2
  import type { Complete } from "../../types/utils";
4
3
  import type { BoundsBuilderOptions } from "./_types/builder";
4
+ import type { Layout } from "../ ../../../types/navigator";
5
5
 
6
6
  export const FULLSCREEN_DIMENSIONS = (
7
- dimensions: ScaledSize,
7
+ dimensions: Layout,
8
8
  ): MeasuredDimensions => {
9
9
  "worklet";
10
10
  return {
@@ -1,16 +1,18 @@
1
- import type { ScaledSize } from "react-native";
2
1
  import type { MeasuredDimensions } from "react-native-reanimated";
3
2
  import {
4
- DEFAULT_BUILDER_OPTIONS,
5
3
  EMPTY_BOUND_HELPER_RESULT,
6
4
  EMPTY_BOUND_HELPER_RESULT_RAW,
7
5
  ENTER_RANGE,
8
6
  EXIT_RANGE,
9
7
  FULLSCREEN_DIMENSIONS,
10
8
  } from "../../constants";
11
- import type { ScreenTransitionState } from "../../types/animation";
12
- import type { BoundsAccessor, BoundsBuilder } from "../../types/bounds";
9
+ import type {
10
+ ScreenInterpolationProps,
11
+ ScreenTransitionState,
12
+ } from "../../types/animation";
13
+ import type { BoundsAccessor } from "../../types/bounds";
13
14
  import type { ScreenPhase } from "../../types/core";
15
+ import type { Layout } from "../../types/navigator";
14
16
  import type {
15
17
  BoundsBuilderInitParams,
16
18
  BoundsBuilderOptions,
@@ -35,7 +37,7 @@ export interface BuildBoundsAccessorParams {
35
37
  previous?: ScreenTransitionState;
36
38
  next?: ScreenTransitionState;
37
39
  progress: number;
38
- dimensions: ScaledSize;
40
+ dimensions: Layout;
39
41
  }
40
42
 
41
43
  const resolveBounds = (props: {
@@ -44,7 +46,7 @@ const resolveBounds = (props: {
44
46
  current?: ScreenTransitionState;
45
47
  next?: ScreenTransitionState;
46
48
  toRect?: Partial<MeasuredDimensions>;
47
- dimensions: ScaledSize;
49
+ dimensions: Layout;
48
50
  computeOptions: BoundsBuilderOptions;
49
51
  }) => {
50
52
  "worklet";
@@ -180,110 +182,38 @@ const computeBoundStyles = (
180
182
  : composeTransformRelative(common);
181
183
  };
182
184
 
183
- /**
184
- * @deprecated Use `createBounds` instead. We'll avoid using the builder pattern for this type of function.
185
- */
186
- const buildBoundStyles = (params: BoundsBuilderInitParams): BoundsBuilder => {
185
+ export const createBounds = (
186
+ props: Omit<ScreenInterpolationProps, "bounds">,
187
+ ): BoundsAccessor => {
187
188
  "worklet";
188
189
 
189
- const cfg: { options: BoundsBuilderOptions } = {
190
- options: { ...DEFAULT_BUILDER_OPTIONS },
190
+ const boundsFunction = (params?: BoundsBuilderOptions) => {
191
+ "worklet";
192
+ const id = params?.id ?? props.activeBoundId;
193
+
194
+ return computeBoundStyles(
195
+ {
196
+ id,
197
+ current: props.current,
198
+ previous: props.previous,
199
+ next: props.next,
200
+ progress: props.progress,
201
+ dimensions: props.layouts.screen,
202
+ },
203
+ params,
204
+ );
191
205
  };
192
206
 
193
- const builder = (): BoundsBuilder => ({
194
- gestures: (options) => {
195
- cfg.options.gestures = options;
196
- return builder();
197
- },
198
- toFullscreen: () => {
199
- cfg.options.toFullscreen = true;
200
- return builder();
201
- },
202
- absolute: () => {
203
- cfg.options.absolute = true;
204
- cfg.options.relative = false;
205
- return builder();
206
- },
207
- relative: () => {
208
- cfg.options.relative = true;
209
- cfg.options.absolute = false;
210
- return builder();
211
- },
212
- transform: () => {
213
- cfg.options.method = "transform";
214
- return builder();
215
- },
216
- size: () => {
217
- cfg.options.method = "size";
218
- return builder();
219
- },
220
- content: () => {
221
- cfg.options.method = "content";
222
- return builder();
223
- },
224
- contentFill: () => {
225
- cfg.options.contentScaleMode = "aspectFill";
226
- return builder();
227
- },
228
- contentFit: () => {
229
- cfg.options.contentScaleMode = "aspectFit";
230
- return builder();
231
- },
232
-
233
- build: () => {
234
- return computeBoundStyles(params, cfg.options);
235
- },
236
- });
237
-
238
- return builder();
239
- };
240
-
241
- export const createBounds = ({
242
- activeBoundId,
243
- current,
244
- previous,
245
- next,
246
- progress,
247
- dimensions,
248
- }: BuildBoundsAccessorParams): BoundsAccessor => {
249
- "worklet";
250
-
251
- const bounds: BoundsAccessor = ((params?: string | BoundsBuilderOptions) => {
252
- if (typeof params === "object") {
253
- const id = params.id ?? activeBoundId;
254
-
255
- return computeBoundStyles(
256
- {
257
- id,
258
- current,
259
- previous,
260
- next,
261
- progress,
262
- dimensions,
263
- },
264
- params,
265
- );
266
- }
267
-
268
- const id = typeof params === "string" ? params : activeBoundId;
269
- return buildBoundStyles({
270
- id,
271
- current,
272
- previous,
273
- next,
274
- progress,
275
- dimensions,
276
- });
277
- }) as BoundsAccessor;
278
-
279
- bounds.get = (id?: string, phase?: ScreenPhase) =>
280
- getBounds({
281
- id: id ?? activeBoundId,
207
+ const get = (id?: string, phase?: ScreenPhase) => {
208
+ "worklet";
209
+ return getBounds({
210
+ id: id ?? props.activeBoundId,
282
211
  phase,
283
- current,
284
- previous,
285
- next,
212
+ current: props.current,
213
+ previous: props.previous,
214
+ next: props.next,
286
215
  });
216
+ };
287
217
 
288
- return bounds;
218
+ return Object.assign(boundsFunction, { get }) as BoundsAccessor;
289
219
  };
@@ -1,4 +1,3 @@
1
- import type { ScaledSize } from "react-native";
2
1
  import type { GestureStateManagerType } from "react-native-gesture-handler/lib/typescript/handlers/gestures/gestureStateManager";
3
2
  import type { SharedValue } from "react-native-reanimated";
4
3
  import {
@@ -16,6 +15,7 @@ import {
16
15
  GestureOffsetState,
17
16
  type SideActivation,
18
17
  } from "../../types/gesture";
18
+ import type { Layout } from "../../types/navigator";
19
19
 
20
20
  type Directions = {
21
21
  vertical: boolean;
@@ -31,7 +31,7 @@ interface CheckGestureActivationProps {
31
31
  manager?: GestureStateManagerType;
32
32
  gestureOffsetState: SharedValue<GestureOffsetState>;
33
33
  activationArea?: GestureActivationArea;
34
- dimensions: ScaledSize;
34
+ dimensions: Layout;
35
35
  responseDistance?: number;
36
36
  }
37
37
 
@@ -88,7 +88,7 @@ function normalizeSides(area?: GestureActivationArea): NormalizedSides {
88
88
 
89
89
  function computeEdgeConstraints(
90
90
  initialTouch: { x: number; y: number },
91
- dimensions: ScaledSize,
91
+ dimensions: Layout,
92
92
  sides: NormalizedSides,
93
93
  responseDistance?: number,
94
94
  ) {
@@ -1,4 +1,3 @@
1
- import type { ScaledSize } from "react-native";
2
1
  import type { GestureStateManagerType } from "react-native-gesture-handler/lib/typescript/handlers/gestures/gestureStateManager";
3
2
  import type { SharedValue } from "react-native-reanimated";
4
3
  import {
@@ -7,6 +6,7 @@ import {
7
6
  GestureOffsetState,
8
7
  type SideActivation,
9
8
  } from "../../types/gesture";
9
+ import type { Layout } from "../../types/navigator";
10
10
 
11
11
  type Directions = {
12
12
  vertical: boolean;
@@ -22,7 +22,7 @@ interface CheckGestureActivationProps {
22
22
  manager?: GestureStateManagerType;
23
23
  gestureOffsetState: SharedValue<GestureOffsetState>;
24
24
  activationArea?: GestureActivationArea;
25
- dimensions: ScaledSize;
25
+ dimensions: Layout;
26
26
  responseDistance?: number;
27
27
  }
28
28
 
@@ -90,7 +90,7 @@ function normalizeSides(area?: GestureActivationArea): NormalizedSides {
90
90
 
91
91
  function computeEdgeConstraints(
92
92
  initialTouch: { x: number; y: number },
93
- dimensions: ScaledSize,
93
+ dimensions: Layout,
94
94
  sides: NormalizedSides,
95
95
  responseDistance?: number,
96
96
  ) {
@@ -31,6 +31,7 @@ export const resetGestureValues = ({
31
31
  const nx =
32
32
  gestures.normalizedX.value ||
33
33
  event.translationX / Math.max(1, dimensions.width);
34
+
34
35
  const ny =
35
36
  gestures.normalizedY.value ||
36
37
  event.translationY / Math.max(1, dimensions.height);
@@ -41,11 +41,10 @@ const normalize = (velocityPixelsPerSecond: number, screenSize: number) => {
41
41
  const calculateRestoreVelocity = (
42
42
  currentValueNormalized: number,
43
43
  baseVelocityNormalized: number,
44
- threshold: number = NEAR_ZERO_THRESHOLD,
45
44
  ) => {
46
45
  "worklet";
47
46
 
48
- if (Math.abs(currentValueNormalized) < threshold) return 0;
47
+ if (Math.abs(currentValueNormalized) < NEAR_ZERO_THRESHOLD) return 0;
49
48
 
50
49
  const directionTowardZero = Math.sign(currentValueNormalized) || 1;
51
50
  const clampedVelocity = Math.min(Math.abs(baseVelocityNormalized), 1);