react-native-screen-transitions 3.6.0-alpha.2 → 3.6.0-alpha.3

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 (119) hide show
  1. package/lib/commonjs/shared/components/screen-container/layers/content.js +11 -1
  2. package/lib/commonjs/shared/components/screen-container/layers/content.js.map +1 -1
  3. package/lib/commonjs/shared/constants.js +3 -5
  4. package/lib/commonjs/shared/constants.js.map +1 -1
  5. package/lib/commonjs/shared/providers/screen/animation/helpers/build-screen-transition-options.js +1 -0
  6. package/lib/commonjs/shared/providers/screen/animation/helpers/build-screen-transition-options.js.map +1 -1
  7. package/lib/commonjs/shared/providers/screen/animation/helpers/hydrate-transition-state/index.js +25 -2
  8. package/lib/commonjs/shared/providers/screen/animation/helpers/hydrate-transition-state/index.js.map +1 -1
  9. package/lib/commonjs/shared/providers/screen/animation/helpers/pipeline.js +1 -2
  10. package/lib/commonjs/shared/providers/screen/animation/helpers/pipeline.js.map +1 -1
  11. package/lib/commonjs/shared/providers/screen/animation/helpers/selected-interpolator-options.js +1 -1
  12. package/lib/commonjs/shared/providers/screen/animation/helpers/selected-interpolator-options.js.map +1 -1
  13. package/lib/commonjs/shared/providers/screen/animation/helpers/use-build-transition-state.js +3 -4
  14. package/lib/commonjs/shared/providers/screen/animation/helpers/use-build-transition-state.js.map +1 -1
  15. package/lib/commonjs/shared/providers/screen/options/helpers.js +3 -1
  16. package/lib/commonjs/shared/providers/screen/options/helpers.js.map +1 -1
  17. package/lib/commonjs/shared/utils/bounds/index.js +3 -2
  18. package/lib/commonjs/shared/utils/bounds/index.js.map +1 -1
  19. package/lib/commonjs/shared/utils/bounds/navigation/reveal/build.js +38 -15
  20. package/lib/commonjs/shared/utils/bounds/navigation/reveal/build.js.map +1 -1
  21. package/lib/commonjs/shared/utils/bounds/navigation/reveal/math.js +24 -4
  22. package/lib/commonjs/shared/utils/bounds/navigation/reveal/math.js.map +1 -1
  23. package/lib/commonjs/shared/utils/bounds/navigation/zoom/build.js +2 -2
  24. package/lib/commonjs/shared/utils/bounds/navigation/zoom/build.js.map +1 -1
  25. package/lib/module/shared/components/screen-container/layers/content.js +13 -3
  26. package/lib/module/shared/components/screen-container/layers/content.js.map +1 -1
  27. package/lib/module/shared/constants.js +3 -5
  28. package/lib/module/shared/constants.js.map +1 -1
  29. package/lib/module/shared/providers/screen/animation/helpers/build-screen-transition-options.js +1 -0
  30. package/lib/module/shared/providers/screen/animation/helpers/build-screen-transition-options.js.map +1 -1
  31. package/lib/module/shared/providers/screen/animation/helpers/hydrate-transition-state/index.js +25 -2
  32. package/lib/module/shared/providers/screen/animation/helpers/hydrate-transition-state/index.js.map +1 -1
  33. package/lib/module/shared/providers/screen/animation/helpers/pipeline.js +1 -2
  34. package/lib/module/shared/providers/screen/animation/helpers/pipeline.js.map +1 -1
  35. package/lib/module/shared/providers/screen/animation/helpers/selected-interpolator-options.js +1 -1
  36. package/lib/module/shared/providers/screen/animation/helpers/selected-interpolator-options.js.map +1 -1
  37. package/lib/module/shared/providers/screen/animation/helpers/use-build-transition-state.js +3 -4
  38. package/lib/module/shared/providers/screen/animation/helpers/use-build-transition-state.js.map +1 -1
  39. package/lib/module/shared/providers/screen/options/helpers.js +3 -1
  40. package/lib/module/shared/providers/screen/options/helpers.js.map +1 -1
  41. package/lib/module/shared/providers/stack/direct.provider.js.map +1 -1
  42. package/lib/module/shared/providers/stack/managed.provider.js.map +1 -1
  43. package/lib/module/shared/types/animation.types.js.map +1 -1
  44. package/lib/module/shared/types/bounds.types.js.map +1 -1
  45. package/lib/module/shared/utils/bounds/index.js +3 -2
  46. package/lib/module/shared/utils/bounds/index.js.map +1 -1
  47. package/lib/module/shared/utils/bounds/navigation/reveal/build.js +40 -17
  48. package/lib/module/shared/utils/bounds/navigation/reveal/build.js.map +1 -1
  49. package/lib/module/shared/utils/bounds/navigation/reveal/math.js +24 -5
  50. package/lib/module/shared/utils/bounds/navigation/reveal/math.js.map +1 -1
  51. package/lib/module/shared/utils/bounds/navigation/zoom/build.js +2 -2
  52. package/lib/module/shared/utils/bounds/navigation/zoom/build.js.map +1 -1
  53. package/lib/typescript/shared/components/create-boundary-component/components/boundary-target.d.ts +4 -207
  54. package/lib/typescript/shared/components/create-boundary-component/components/boundary-target.d.ts.map +1 -1
  55. package/lib/typescript/shared/components/create-boundary-component/index.d.ts +2 -2
  56. package/lib/typescript/shared/components/overlay/variations/overlay-host.d.ts +1 -1
  57. package/lib/typescript/shared/components/overlay/variations/overlay-host.d.ts.map +1 -1
  58. package/lib/typescript/shared/components/scene-view.d.ts +1 -1
  59. package/lib/typescript/shared/components/scene-view.d.ts.map +1 -1
  60. package/lib/typescript/shared/components/screen-container/layers/backdrop.d.ts +2 -2
  61. package/lib/typescript/shared/components/screen-container/layers/backdrop.d.ts.map +1 -1
  62. package/lib/typescript/shared/components/screen-container/layers/content.d.ts.map +1 -1
  63. package/lib/typescript/shared/constants.d.ts +1 -1
  64. package/lib/typescript/shared/constants.d.ts.map +1 -1
  65. package/lib/typescript/shared/index.d.ts +2 -2
  66. package/lib/typescript/shared/providers/screen/animation/helpers/build-screen-transition-options.d.ts.map +1 -1
  67. package/lib/typescript/shared/providers/screen/animation/helpers/hydrate-transition-state/index.d.ts +1 -1
  68. package/lib/typescript/shared/providers/screen/animation/helpers/hydrate-transition-state/index.d.ts.map +1 -1
  69. package/lib/typescript/shared/providers/screen/animation/helpers/hydrate-transition-state/types.d.ts +1 -1
  70. package/lib/typescript/shared/providers/screen/animation/helpers/hydrate-transition-state/types.d.ts.map +1 -1
  71. package/lib/typescript/shared/providers/screen/animation/helpers/selected-interpolator-options.d.ts.map +1 -1
  72. package/lib/typescript/shared/providers/screen/animation/helpers/use-build-transition-state.d.ts +1 -1
  73. package/lib/typescript/shared/providers/screen/animation/helpers/use-build-transition-state.d.ts.map +1 -1
  74. package/lib/typescript/shared/providers/screen/options/helpers.d.ts.map +1 -1
  75. package/lib/typescript/shared/providers/screen/options/types.d.ts +1 -0
  76. package/lib/typescript/shared/providers/screen/options/types.d.ts.map +1 -1
  77. package/lib/typescript/shared/providers/screen/styles/components/maybe-floating-container.d.ts +1 -1
  78. package/lib/typescript/shared/providers/screen/styles/components/maybe-floating-container.d.ts.map +1 -1
  79. package/lib/typescript/shared/providers/stack/direct.provider.d.ts +1 -1
  80. package/lib/typescript/shared/providers/stack/direct.provider.d.ts.map +1 -1
  81. package/lib/typescript/shared/providers/stack/managed.provider.d.ts +1 -1
  82. package/lib/typescript/shared/providers/stack/managed.provider.d.ts.map +1 -1
  83. package/lib/typescript/shared/types/animation.types.d.ts +4 -1
  84. package/lib/typescript/shared/types/animation.types.d.ts.map +1 -1
  85. package/lib/typescript/shared/types/bounds.types.d.ts +69 -1
  86. package/lib/typescript/shared/types/bounds.types.d.ts.map +1 -1
  87. package/lib/typescript/shared/types/index.d.ts +1 -1
  88. package/lib/typescript/shared/types/index.d.ts.map +1 -1
  89. package/lib/typescript/shared/types/screen.types.d.ts +4 -14
  90. package/lib/typescript/shared/types/screen.types.d.ts.map +1 -1
  91. package/lib/typescript/shared/utils/bounds/index.d.ts.map +1 -1
  92. package/lib/typescript/shared/utils/bounds/navigation/reveal/build.d.ts +1 -1
  93. package/lib/typescript/shared/utils/bounds/navigation/reveal/build.d.ts.map +1 -1
  94. package/lib/typescript/shared/utils/bounds/navigation/reveal/math.d.ts +12 -2
  95. package/lib/typescript/shared/utils/bounds/navigation/reveal/math.d.ts.map +1 -1
  96. package/lib/typescript/shared/utils/bounds/navigation/reveal/types.d.ts +2 -1
  97. package/lib/typescript/shared/utils/bounds/navigation/reveal/types.d.ts.map +1 -1
  98. package/package.json +4 -3
  99. package/src/shared/components/screen-container/layers/content.tsx +21 -2
  100. package/src/shared/constants.ts +0 -3
  101. package/src/shared/providers/screen/animation/helpers/build-screen-transition-options.ts +1 -0
  102. package/src/shared/providers/screen/animation/helpers/hydrate-transition-state/index.ts +48 -2
  103. package/src/shared/providers/screen/animation/helpers/hydrate-transition-state/types.ts +1 -1
  104. package/src/shared/providers/screen/animation/helpers/pipeline.ts +1 -1
  105. package/src/shared/providers/screen/animation/helpers/selected-interpolator-options.ts +1 -0
  106. package/src/shared/providers/screen/animation/helpers/use-build-transition-state.ts +3 -12
  107. package/src/shared/providers/screen/options/helpers.ts +9 -0
  108. package/src/shared/providers/screen/options/types.ts +1 -0
  109. package/src/shared/providers/stack/direct.provider.tsx +1 -1
  110. package/src/shared/providers/stack/managed.provider.tsx +1 -1
  111. package/src/shared/types/animation.types.ts +4 -0
  112. package/src/shared/types/bounds.types.ts +72 -1
  113. package/src/shared/types/index.ts +1 -0
  114. package/src/shared/types/screen.types.ts +4 -14
  115. package/src/shared/utils/bounds/index.ts +3 -1
  116. package/src/shared/utils/bounds/navigation/reveal/build.ts +58 -24
  117. package/src/shared/utils/bounds/navigation/reveal/math.ts +34 -4
  118. package/src/shared/utils/bounds/navigation/reveal/types.ts +2 -0
  119. package/src/shared/utils/bounds/navigation/zoom/build.ts +2 -2
@@ -59,6 +59,7 @@ const areInterpolatorOptionsEqual = (
59
59
  if (!left || !right) return false;
60
60
 
61
61
  return (
62
+ left.navigationMaskEnabled === right.navigationMaskEnabled &&
62
63
  left.gestureEnabled === right.gestureEnabled &&
63
64
  left.experimental_allowDisabledGestureTracking ===
64
65
  right.experimental_allowDisabledGestureTracking &&
@@ -27,7 +27,7 @@ type BuiltState = {
27
27
  route: BaseStackRoute;
28
28
  meta?: Record<string, unknown>;
29
29
  options: ScreenTransitionOptions;
30
- navigationMaskEnabled: boolean;
30
+ optionsSlot: ScreenTransitionOptions;
31
31
  targetProgress: SharedValue<number>;
32
32
  logicalSettleFrameCount: SharedValue<number>;
33
33
  resolvedAutoSnapPoint: SharedValue<number>;
@@ -44,7 +44,6 @@ export const useBuildTransitionState = (
44
44
  const key = descriptor?.route?.key;
45
45
  const meta = descriptor?.options?.meta;
46
46
  const route = descriptor?.route;
47
- const navigationMaskEnabled = !!descriptor?.options?.navigationMaskEnabled;
48
47
  const snapPoints = descriptor?.options?.snapPoints;
49
48
 
50
49
  return useMemo(() => {
@@ -81,20 +80,12 @@ export const useBuildTransitionState = (
81
80
  route: plainRoute,
82
81
  meta: plainMeta,
83
82
  options: transitionOptions,
84
- navigationMaskEnabled,
83
+ optionsSlot: {},
85
84
  unwrapped: createScreenTransitionState(
86
85
  plainRoute,
87
86
  plainMeta,
88
- navigationMaskEnabled,
89
87
  transitionOptions,
90
88
  ),
91
89
  };
92
- }, [
93
- key,
94
- meta,
95
- route,
96
- snapPoints,
97
- navigationMaskEnabled,
98
- descriptor?.options,
99
- ]);
90
+ }, [key, meta, route, snapPoints, descriptor?.options]);
100
91
  };
@@ -206,6 +206,7 @@ const areScreenOptionsEqual = (
206
206
  ) => {
207
207
  "worklet";
208
208
  return (
209
+ left.navigationMaskEnabled === right.navigationMaskEnabled &&
209
210
  left.gestureEnabled === right.gestureEnabled &&
210
211
  left.experimental_allowDisabledGestureTracking ===
211
212
  right.experimental_allowDisabledGestureTracking &&
@@ -238,6 +239,10 @@ export const resolveBaseScreenOptions = (
238
239
  );
239
240
 
240
241
  return {
242
+ navigationMaskEnabled: resolveBooleanOption(
243
+ options.navigationMaskEnabled,
244
+ undefined,
245
+ ),
241
246
  gestureEnabled: resolveBooleanOption(options.gestureEnabled, undefined),
242
247
  experimental_allowDisabledGestureTracking: resolveBooleanOption(
243
248
  options.experimental_allowDisabledGestureTracking,
@@ -322,6 +327,10 @@ export const syncScreenOptionsOverrides = (
322
327
  );
323
328
 
324
329
  const next: ScreenOptionsState = {
330
+ navigationMaskEnabled: resolveBooleanOption(
331
+ options?.navigationMaskEnabled,
332
+ base.navigationMaskEnabled,
333
+ ),
325
334
  gestureEnabled: resolveBooleanOption(
326
335
  options?.gestureEnabled,
327
336
  base.gestureEnabled,
@@ -9,6 +9,7 @@ export type OptionalScreenOption<K extends keyof ScreenTransitionOptions> =
9
9
  ScreenTransitionOptions[K];
10
10
 
11
11
  export type ScreenOptionsSnapshot = {
12
+ navigationMaskEnabled: OptionalScreenOption<"navigationMaskEnabled">;
12
13
  gestureEnabled: OptionalScreenOption<"gestureEnabled">;
13
14
  experimental_allowDisabledGestureTracking: RequiredScreenOption<"experimental_allowDisabledGestureTracking">;
14
15
  gestureDirection: RequiredScreenOption<"gestureDirection">;
@@ -142,5 +142,5 @@ function withDirectStack<TProps extends DirectStackProps>(
142
142
  };
143
143
  }
144
144
 
145
- export { withDirectStack };
146
145
  export type { DirectStackContextValue, DirectStackProps, DirectStackScene };
146
+ export { withDirectStack };
@@ -138,9 +138,9 @@ function withManagedStack<
138
138
  };
139
139
  }
140
140
 
141
- export { useManagedStackContext, withManagedStack };
142
141
  export type {
143
142
  ManagedStackContextValue,
144
143
  ManagedStackProps,
145
144
  ManagedStackRenderProps,
146
145
  };
146
+ export { useManagedStackContext, withManagedStack };
@@ -23,6 +23,7 @@ import type { BaseStackRoute } from "./stack.types";
23
23
  */
24
24
  export type ScreenTransitionOptions = Pick<
25
25
  ScreenTransitionConfig,
26
+ | "navigationMaskEnabled"
26
27
  | "gestureEnabled"
27
28
  | "experimental_allowDisabledGestureTracking"
28
29
  | "gestureDirection"
@@ -227,6 +228,9 @@ export interface ScreenInterpolationProps {
227
228
  /**
228
229
  * Whether the active transition is visually close enough to its target to be
229
230
  * treated as complete, even if the animation is still physically settling.
231
+ *
232
+ * @deprecated Use `active.logicallySettled` instead. Screen settlement state
233
+ * belongs on the screen state object.
230
234
  */
231
235
  logicallySettled: number;
232
236
 
@@ -14,6 +14,7 @@ import type {
14
14
  TransitionInterpolatedStyle,
15
15
  TransitionSlotStyle,
16
16
  } from "./animation.types";
17
+ import type { GestureProgressMode } from "./gesture.types";
17
18
 
18
19
  /**
19
20
  * Target style computation.
@@ -161,11 +162,81 @@ export type BoundsNavigationZoomStyle = TransitionInterpolatedStyle & {
161
162
  [NAVIGATION_MASK_ELEMENT_STYLE_ID]?: TransitionSlotStyle;
162
163
  };
163
164
 
165
+ export type BoundsNavigationRevealOptions = {
166
+ /**
167
+ * Destination mask border radius.
168
+ *
169
+ * Reveal interpolates from the measured source border radius to this value.
170
+ *
171
+ * @default Platform-specific reveal radius
172
+ */
173
+ borderRadius?: number;
174
+ /**
175
+ * Whether the reveal mask should use React Native's continuous border curve.
176
+ *
177
+ * @default true
178
+ */
179
+ borderContinuous?: boolean;
180
+ /**
181
+ * Maximum dynamic gesture sensitivity applied by reveal.
182
+ *
183
+ * Reveal lowers gesture sensitivity as the drag gets deeper so the masked
184
+ * container can keep its source-to-destination handoff stable. This value
185
+ * controls the starting/highest sensitivity in that curve.
186
+ *
187
+ * @default 0.8
188
+ */
189
+ maxSensitivity?: number;
190
+ /**
191
+ * Velocity-driven depth applied to the dismiss scale handoff.
192
+ *
193
+ * Higher values make fast releases orbit farther around the final source
194
+ * scale. Set to `0` to remove the velocity depth effect.
195
+ *
196
+ * @default 0.5
197
+ */
198
+ velocityDepth?: number;
199
+ /**
200
+ * Whether gesture displacement should drive transition progress or remain as
201
+ * freeform gesture values. Reveal defaults to `"freeform"` so drag can move
202
+ * the masked container without owning the whole screen progress.
203
+ *
204
+ * @default "freeform"
205
+ */
206
+ gestureProgressMode?: GestureProgressMode;
207
+ /**
208
+ * Temporarily blocks pointer-event pass-through on the inactive content until
209
+ * the source element transition handoff reaches progress `0.25`.
210
+ *
211
+ * This is intentional and most users cannot react fast enough to swipe during
212
+ * that brief handoff. If it becomes an issue, set this to `false` to disable
213
+ * the guard and keep the default behavior that allows pointer events to pass
214
+ * through.
215
+ *
216
+ * @default true
217
+ */
218
+ disablePointerEventsTillElementTransition?: boolean;
219
+ /**
220
+ * How reveal should resize the navigation mask element.
221
+ *
222
+ * `"auto"` uses the platform default. Android defaults to transform-based
223
+ * resizing to avoid masked-size animation cost, while other platforms animate
224
+ * width and height. Transform-based resizing can make large border radii look
225
+ * less natural on Android; use `"size"` to force width/height animation when
226
+ * radius quality is more important than that optimization.
227
+ *
228
+ * @default "auto"
229
+ */
230
+ maskSizingMode?: "auto" | "transform" | "size";
231
+ };
232
+
164
233
  export type BoundsNavigationRevealStyle = BoundsNavigationZoomStyle;
165
234
 
166
235
  export type BoundsNavigationAccessor = {
167
236
  zoom: (options?: BoundsNavigationZoomOptions) => BoundsNavigationZoomStyle;
168
- reveal: () => BoundsNavigationRevealStyle;
237
+ reveal: (
238
+ options?: BoundsNavigationRevealOptions,
239
+ ) => BoundsNavigationRevealStyle;
169
240
  };
170
241
 
171
242
  type BoundsBoundNavigationAccessor = {
@@ -15,6 +15,7 @@ export type {
15
15
  BoundsAccessor,
16
16
  BoundsMethod,
17
17
  BoundsNavigationAccessor,
18
+ BoundsNavigationRevealOptions,
18
19
  BoundsNavigationRevealStyle,
19
20
  BoundsNavigationZoomOpacityRange,
20
21
  BoundsNavigationZoomOpacityRanges,
@@ -27,13 +27,6 @@ export type ScreenLayouts = {
27
27
  * auto snap-point sizing. It is undefined until a real measurement exists.
28
28
  */
29
29
  content?: Layout;
30
- /**
31
- * Whether navigation bounds masking is enabled for this screen.
32
- *
33
- * When enabled, navigation zoom helpers target the masked container path
34
- * instead of the plain content slot.
35
- */
36
- navigationMaskEnabled: boolean;
37
30
  };
38
31
 
39
32
  export type ScreenKey = string;
@@ -206,15 +199,12 @@ export type ScreenTransitionConfig = {
206
199
  gestureReleaseVelocityScale?: number;
207
200
 
208
201
  /**
209
- * Caps the absolute post-scale release velocity used by spring animations.
202
+ * Deprecated compatibility option.
210
203
  *
211
- * This does NOT affect dismissal threshold decisions (`gestureVelocityImpact`)
212
- * or snap target selection (`snapVelocityImpact`). It only bounds release
213
- * animation intensity after `gestureReleaseVelocityScale` is applied.
204
+ * This option is no longer read by the runtime transition options. Use
205
+ * `gestureReleaseVelocityScale` to tune post-release spring energy.
214
206
  *
215
- * @deprecated v3 compatibility only. This option is removed in the next
216
- * gesture runtime.
217
- * @default 3.2
207
+ * @deprecated v3 compatibility only.
218
208
  */
219
209
  gestureReleaseVelocityMax?: number;
220
210
 
@@ -1,6 +1,7 @@
1
1
  import type {
2
2
  BoundsAccessor,
3
3
  BoundsInterpolationProps,
4
+ BoundsNavigationRevealOptions,
4
5
  BoundsNavigationZoomOptions,
5
6
  } from "../../types/bounds.types";
6
7
  import { createBoundsAccessorCore } from "./helpers/create-bounds-accessor-core";
@@ -26,11 +27,12 @@ export const createBoundsAccessor = (
26
27
  zoomOptions,
27
28
  });
28
29
  },
29
- reveal: () => {
30
+ reveal: (revealOptions?: BoundsNavigationRevealOptions) => {
30
31
  "worklet";
31
32
  return buildRevealStyles({
32
33
  props,
33
34
  tag,
35
+ revealOptions,
34
36
  });
35
37
  },
36
38
  },
@@ -9,6 +9,7 @@ import {
9
9
  CONTENT_ENTERING_OPACITY_OUTPUT,
10
10
  CONTENT_ENTERING_OPACITY_RANGE,
11
11
  CONTENT_SHADOW_OPACITY_OUTPUT,
12
+ DISMISS_SCALE_ORBIT_DEPTH,
12
13
  DRAG_MASK_HEIGHT_COLLAPSE_END,
13
14
  HORIZONTAL_DRAG_MASK_COLLAPSE_SCALE,
14
15
  IDENTITY_DRAG_SCALE_OUTPUT,
@@ -21,6 +22,7 @@ import {
21
22
  import {
22
23
  interpolateClamped,
23
24
  mixUnit,
25
+ resolveAspectRatioMaskHeight,
24
26
  resolveDismissScaleHandoff,
25
27
  resolveRevealContentBaseTransform,
26
28
  resolveRevealDirectionalDragScale,
@@ -39,6 +41,7 @@ import type { BuildRevealStylesParams, RevealInterpolatedStyle } from "./types";
39
41
  export function buildRevealStyles({
40
42
  tag,
41
43
  props,
44
+ revealOptions,
42
45
  }: BuildRevealStylesParams): RevealInterpolatedStyle {
43
46
  "worklet";
44
47
 
@@ -53,6 +56,19 @@ export function buildRevealStyles({
53
56
  progress,
54
57
  layouts: { screen: screenLayout },
55
58
  } = props;
59
+ const borderRadius = revealOptions?.borderRadius ?? REVEAL_BORDER_RADIUS;
60
+ const borderContinuous = revealOptions?.borderContinuous ?? true;
61
+ const maxSensitivity = revealOptions?.maxSensitivity ?? 0.8;
62
+ const velocityDepth =
63
+ revealOptions?.velocityDepth ?? DISMISS_SCALE_ORBIT_DEPTH;
64
+ const gestureProgressMode = revealOptions?.gestureProgressMode ?? "freeform";
65
+ const disablePointerEventsTillElementTransition =
66
+ revealOptions?.disablePointerEventsTillElementTransition ?? true;
67
+ const maskSizingMode = revealOptions?.maskSizingMode ?? "auto";
68
+ const usesTransformMask =
69
+ maskSizingMode === "auto"
70
+ ? REVEAL_USES_TRANSFORM_MASK
71
+ : maskSizingMode === "transform";
56
72
 
57
73
  const boundsAccessor = createLinkAccessor(() => props);
58
74
  const link = boundsAccessor.getLink(tag);
@@ -79,15 +95,15 @@ export function buildRevealStyles({
79
95
  ? Math.abs(props.active.gesture.raw.normY)
80
96
  : 0;
81
97
 
82
- const dragX =
83
- props.active.gesture.x === 0
84
- ? 0
85
- : resolveUnitDragTranslation(props.active.gesture.x, screenLayout.width);
98
+ const dragX = resolveUnitDragTranslation(
99
+ props.active.gesture.x,
100
+ screenLayout.width,
101
+ );
86
102
 
87
- const dragY =
88
- props.active.gesture.y === 0
89
- ? 0
90
- : resolveUnitDragTranslation(props.active.gesture.y, screenLayout.height);
103
+ const dragY = resolveUnitDragTranslation(
104
+ props.active.gesture.y,
105
+ screenLayout.height,
106
+ );
91
107
 
92
108
  const dragXScale = isHorizontalDismiss
93
109
  ? resolveRevealDirectionalDragScale(
@@ -130,9 +146,12 @@ export function buildRevealStyles({
130
146
 
131
147
  const maskBorderRadius = mixUnit(
132
148
  sourceBorderRadius,
133
- REVEAL_BORDER_RADIUS,
149
+ borderRadius,
134
150
  progress,
135
151
  );
152
+ const maskBorderCurve = borderContinuous
153
+ ? ("continuous" as const)
154
+ : undefined;
136
155
 
137
156
  const maskSizeMultiplier = props.active.closing
138
157
  ? mixUnit(0.9, 1, props.active.progress)
@@ -148,19 +167,23 @@ export function buildRevealStyles({
148
167
  if (props.active.gesture.dismissing) {
149
168
  const contentTargetBounds =
150
169
  initialDestinationTarget ?? link.destination.bounds;
170
+
151
171
  const sourceContentScale = resolveUniformScale({
152
172
  sourceWidth: link.source.bounds.width,
153
173
  sourceHeight: link.source.bounds.height,
154
174
  destinationWidth: contentTargetBounds.width,
155
175
  destinationHeight: contentTargetBounds.height,
156
176
  });
177
+
157
178
  contentScale = resolveDismissScaleHandoff({
158
179
  progress: props.active.progress,
159
180
  releaseScale: dragScale,
160
181
  targetScale: sourceContentScale,
161
182
  velocity: props.active.gesture.velocity,
183
+ velocityDepth,
162
184
  });
163
185
  }
186
+
164
187
  const contentTranslateX = contentRaw.translateX + dragX;
165
188
  const contentTranslateY = contentRaw.translateY + dragY;
166
189
 
@@ -190,10 +213,13 @@ export function buildRevealStyles({
190
213
  )
191
214
  : 0;
192
215
 
193
- const minMaskHeight = Math.min(
216
+ const maskAspectBounds = link.initialSource?.bounds ?? link.source.bounds;
217
+ const minMaskHeight = resolveAspectRatioMaskHeight({
218
+ maskWidth,
194
219
  maskHeight,
195
- Math.max(maskWidth, link.source.bounds.height),
196
- );
220
+ targetWidth: maskAspectBounds.width,
221
+ targetHeight: maskAspectBounds.height,
222
+ });
197
223
 
198
224
  const renderedMaskHeight = interpolateClamped(
199
225
  maskHeightCollapseDrag,
@@ -242,12 +268,12 @@ export function buildRevealStyles({
242
268
  compensatedMaskTranslateX + (maskWidth - maskBaseWidth) / 2;
243
269
  const transformMaskTranslateY =
244
270
  compensatedMaskTranslateY + (renderedMaskHeight - maskBaseHeight) / 2;
245
- const maskElementStyle = REVEAL_USES_TRANSFORM_MASK
271
+ const maskElementStyle = usesTransformMask
246
272
  ? {
247
273
  width: maskBaseWidth,
248
274
  height: maskBaseHeight,
249
275
  borderRadius: props.active.settled ? 0 : maskBorderRadius,
250
- borderCurve: "continuous" as const,
276
+ borderCurve: maskBorderCurve,
251
277
  transform: [
252
278
  { translateX: transformMaskTranslateX },
253
279
  { translateY: transformMaskTranslateY },
@@ -259,7 +285,7 @@ export function buildRevealStyles({
259
285
  width: maskWidth,
260
286
  height: renderedMaskHeight,
261
287
  borderRadius: props.active.settled ? 0 : maskBorderRadius,
262
- borderCurve: "continuous" as const,
288
+ borderCurve: maskBorderCurve,
263
289
  transform: [
264
290
  { translateX: compensatedMaskTranslateX },
265
291
  { translateY: compensatedMaskTranslateY },
@@ -295,11 +321,15 @@ export function buildRevealStyles({
295
321
  : 0;
296
322
 
297
323
  const { gestureSensitivity, gestureReleaseVelocityScale } =
298
- resolveRevealGestureHandoff(rawDrag);
324
+ resolveRevealGestureHandoff({
325
+ rawDrag,
326
+ maxSensitivity,
327
+ });
299
328
 
300
329
  return {
301
330
  options: {
302
- gestureProgressMode: "freeform",
331
+ navigationMaskEnabled: true,
332
+ gestureProgressMode,
303
333
  gestureSensitivity,
304
334
  gestureReleaseVelocityScale,
305
335
  },
@@ -374,6 +404,7 @@ export function buildRevealStyles({
374
404
  releaseScale: dragScale,
375
405
  targetScale: trackingTargetScale,
376
406
  velocity: props.active.gesture.velocity,
407
+ velocityDepth,
377
408
  });
378
409
  }
379
410
  const trackingContentTranslateX =
@@ -393,18 +424,21 @@ export function buildRevealStyles({
393
424
 
394
425
  return {
395
426
  options: {
396
- gestureProgressMode: "freeform",
427
+ navigationMaskEnabled: true,
428
+ gestureProgressMode,
397
429
  },
398
430
  content: {
399
431
  style: {
400
432
  transform: [{ scale: unfocusedContentScale }],
401
433
  },
402
- props: {
403
- pointerEvents:
404
- props.active.progress <= CLOSE_SOURCE_HANDOFF_PROGRESS
405
- ? "auto"
406
- : "none",
407
- },
434
+ props: disablePointerEventsTillElementTransition
435
+ ? {
436
+ pointerEvents:
437
+ props.active.progress <= CLOSE_SOURCE_HANDOFF_PROGRESS
438
+ ? "auto"
439
+ : "none",
440
+ }
441
+ : undefined,
408
442
  },
409
443
  [link.id]: {
410
444
  style: {
@@ -3,7 +3,6 @@ import { EPSILON } from "../../../../constants";
3
3
  import type { Layout } from "../../../../types/screen.types";
4
4
  import { computeContentTransformGeometry } from "../../helpers/geometry";
5
5
  import {
6
- DISMISS_SCALE_ORBIT_DEPTH,
7
6
  DRAG_DIRECTIONAL_SCALE_EXPONENT,
8
7
  DRAG_DIRECTIONAL_SCALE_MAX,
9
8
  DRAG_DIRECTIONAL_SCALE_MIN,
@@ -98,11 +97,17 @@ export function resolveUniformScale({
98
97
  return aspectDifference < 0.1 ? Math.max(sx, sy) : Math.min(sx, sy);
99
98
  }
100
99
 
101
- export function resolveRevealGestureHandoff(rawDrag: number) {
100
+ export function resolveRevealGestureHandoff({
101
+ rawDrag,
102
+ maxSensitivity,
103
+ }: {
104
+ rawDrag: number;
105
+ maxSensitivity: number;
106
+ }) {
102
107
  "worklet";
103
108
 
104
109
  const clampedRawDrag = clampUnit(rawDrag);
105
- const gestureSensitivity = mixUnit(0.8, 0.1, clampedRawDrag);
110
+ const gestureSensitivity = mixUnit(maxSensitivity, 0.1, clampedRawDrag);
106
111
 
107
112
  const releaseBoost = mixUnit(1, 1.1, clampedRawDrag);
108
113
 
@@ -125,11 +130,13 @@ export function resolveDismissScaleHandoff({
125
130
  releaseScale,
126
131
  targetScale,
127
132
  velocity,
133
+ velocityDepth,
128
134
  }: {
129
135
  progress: number;
130
136
  releaseScale: number;
131
137
  targetScale: number;
132
138
  velocity: number;
139
+ velocityDepth: number;
133
140
  }) {
134
141
  "worklet";
135
142
 
@@ -137,12 +144,35 @@ export function resolveDismissScaleHandoff({
137
144
  const scaleProgress = Math.sin((Math.PI / 2) * closeProgress);
138
145
  const baseScale = releaseScale + (targetScale - releaseScale) * scaleProgress;
139
146
 
140
- const orbitDepth = DISMISS_SCALE_ORBIT_DEPTH * velocity;
147
+ const orbitDepth = velocityDepth * velocity;
141
148
  const orbitScale = 1 - orbitDepth * Math.sin(Math.PI * closeProgress);
142
149
 
143
150
  return baseScale * orbitScale;
144
151
  }
145
152
 
153
+ export function resolveAspectRatioMaskHeight({
154
+ maskWidth,
155
+ maskHeight,
156
+ targetWidth,
157
+ targetHeight,
158
+ }: {
159
+ maskWidth: number;
160
+ maskHeight: number;
161
+ targetWidth: number;
162
+ targetHeight: number;
163
+ }) {
164
+ "worklet";
165
+
166
+ const safeMaskWidth = Math.max(1, Math.abs(maskWidth));
167
+ const safeMaskHeight = Math.max(1, Math.abs(maskHeight));
168
+ const safeTargetWidth = Math.max(Math.abs(targetWidth), EPSILON);
169
+ const safeTargetHeight = Math.max(Math.abs(targetHeight), EPSILON);
170
+ const targetAspectHeight =
171
+ safeMaskWidth * (safeTargetHeight / safeTargetWidth);
172
+
173
+ return Math.min(safeMaskHeight, Math.max(1, targetAspectHeight));
174
+ }
175
+
146
176
  function getBoundsCenterX(bounds: MeasuredDimensions) {
147
177
  "worklet";
148
178
  return bounds.pageX + bounds.width / 2;
@@ -4,6 +4,7 @@ import {
4
4
  } from "../../../../constants";
5
5
  import type {
6
6
  BoundsInterpolationProps,
7
+ BoundsNavigationRevealOptions,
7
8
  BoundsNavigationRevealStyle,
8
9
  } from "../../../../types/bounds.types";
9
10
 
@@ -15,4 +16,5 @@ export type RevealInterpolatedStyle = BoundsNavigationRevealStyle & {
15
16
  export type BuildRevealStylesParams = {
16
17
  tag?: string;
17
18
  props: BoundsInterpolationProps;
19
+ revealOptions?: BoundsNavigationRevealOptions;
18
20
  };
@@ -168,7 +168,7 @@ export function buildZoomStyles({
168
168
  style: VISIBLE_STYLE,
169
169
  },
170
170
  } satisfies TransitionInterpolatedStyle;
171
- const focusedContentSlot = props.current.layouts.navigationMaskEnabled
171
+ const focusedContentSlot = props.current.options.navigationMaskEnabled
172
172
  ? NAVIGATION_MASK_CONTAINER_STYLE_ID
173
173
  : "content";
174
174
 
@@ -325,7 +325,7 @@ export function buildZoomStyles({
325
325
  ...sourceVisibilityStyle,
326
326
  };
327
327
 
328
- if (props.current.layouts.navigationMaskEnabled) {
328
+ if (props.current.options.navigationMaskEnabled) {
329
329
  focusedStyles[NAVIGATION_MASK_ELEMENT_STYLE_ID] = {
330
330
  style: {
331
331
  width: maskWidth,