react-native-screen-transitions 3.8.0-alpha.0 → 3.8.0-beta.0

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 (101) hide show
  1. package/lib/commonjs/shared/components/create-boundary-component/hooks/use-measurer.js +1 -1
  2. package/lib/commonjs/shared/components/create-boundary-component/hooks/use-measurer.js.map +1 -1
  3. package/lib/commonjs/shared/components/create-transition-aware-component.js +7 -5
  4. package/lib/commonjs/shared/components/create-transition-aware-component.js.map +1 -1
  5. package/lib/commonjs/shared/providers/screen/animation/helpers/hydrate-transition-state/index.js +1 -0
  6. package/lib/commonjs/shared/providers/screen/animation/helpers/hydrate-transition-state/index.js.map +1 -1
  7. package/lib/commonjs/shared/providers/screen/animation/helpers/use-build-transition-state.js +2 -0
  8. package/lib/commonjs/shared/providers/screen/animation/helpers/use-build-transition-state.js.map +1 -1
  9. package/lib/commonjs/shared/providers/screen/gestures/gestures.provider.js +1 -1
  10. package/lib/commonjs/shared/providers/screen/gestures/gestures.provider.js.map +1 -1
  11. package/lib/commonjs/shared/providers/screen/gestures/pan/activation/pan-activation-decision.js +7 -1
  12. package/lib/commonjs/shared/providers/screen/gestures/pan/activation/pan-activation-decision.js.map +1 -1
  13. package/lib/commonjs/shared/providers/screen/gestures/scroll-coordination/index.js +7 -0
  14. package/lib/commonjs/shared/providers/screen/gestures/scroll-coordination/index.js.map +1 -1
  15. package/lib/commonjs/shared/providers/screen/gestures/scroll-coordination/scroll-metadata-owner.js +40 -0
  16. package/lib/commonjs/shared/providers/screen/gestures/scroll-coordination/scroll-metadata-owner.js.map +1 -0
  17. package/lib/commonjs/shared/providers/screen/gestures/scroll-coordination/update-scroll-gesture-state.js +51 -13
  18. package/lib/commonjs/shared/providers/screen/gestures/scroll-coordination/update-scroll-gesture-state.js.map +1 -1
  19. package/lib/commonjs/shared/providers/screen/gestures/scroll-coordination/use-scroll-gesture-coordination.js +74 -6
  20. package/lib/commonjs/shared/providers/screen/gestures/scroll-coordination/use-scroll-gesture-coordination.js.map +1 -1
  21. package/lib/commonjs/shared/providers/screen/gestures/types.js.map +1 -1
  22. package/lib/commonjs/shared/stores/scroll.store.js +49 -5
  23. package/lib/commonjs/shared/stores/scroll.store.js.map +1 -1
  24. package/lib/commonjs/shared/types/gesture.types.js +12 -0
  25. package/lib/commonjs/shared/types/gesture.types.js.map +1 -1
  26. package/lib/commonjs/shared/utils/animation/spring/spring.js +7 -3
  27. package/lib/commonjs/shared/utils/animation/spring/spring.js.map +1 -1
  28. package/lib/module/shared/components/create-boundary-component/hooks/use-measurer.js +1 -1
  29. package/lib/module/shared/components/create-boundary-component/hooks/use-measurer.js.map +1 -1
  30. package/lib/module/shared/components/create-transition-aware-component.js +8 -6
  31. package/lib/module/shared/components/create-transition-aware-component.js.map +1 -1
  32. package/lib/module/shared/providers/screen/animation/helpers/hydrate-transition-state/index.js +1 -0
  33. package/lib/module/shared/providers/screen/animation/helpers/hydrate-transition-state/index.js.map +1 -1
  34. package/lib/module/shared/providers/screen/animation/helpers/use-build-transition-state.js +2 -0
  35. package/lib/module/shared/providers/screen/animation/helpers/use-build-transition-state.js.map +1 -1
  36. package/lib/module/shared/providers/screen/gestures/gestures.provider.js +1 -1
  37. package/lib/module/shared/providers/screen/gestures/gestures.provider.js.map +1 -1
  38. package/lib/module/shared/providers/screen/gestures/pan/activation/pan-activation-decision.js +7 -1
  39. package/lib/module/shared/providers/screen/gestures/pan/activation/pan-activation-decision.js.map +1 -1
  40. package/lib/module/shared/providers/screen/gestures/scroll-coordination/index.js +1 -0
  41. package/lib/module/shared/providers/screen/gestures/scroll-coordination/index.js.map +1 -1
  42. package/lib/module/shared/providers/screen/gestures/scroll-coordination/scroll-metadata-owner.js +33 -0
  43. package/lib/module/shared/providers/screen/gestures/scroll-coordination/scroll-metadata-owner.js.map +1 -0
  44. package/lib/module/shared/providers/screen/gestures/scroll-coordination/update-scroll-gesture-state.js +48 -12
  45. package/lib/module/shared/providers/screen/gestures/scroll-coordination/update-scroll-gesture-state.js.map +1 -1
  46. package/lib/module/shared/providers/screen/gestures/scroll-coordination/use-scroll-gesture-coordination.js +76 -8
  47. package/lib/module/shared/providers/screen/gestures/scroll-coordination/use-scroll-gesture-coordination.js.map +1 -1
  48. package/lib/module/shared/providers/screen/gestures/types.js.map +1 -1
  49. package/lib/module/shared/stores/scroll.store.js +49 -5
  50. package/lib/module/shared/stores/scroll.store.js.map +1 -1
  51. package/lib/module/shared/types/gesture.types.js +16 -0
  52. package/lib/module/shared/types/gesture.types.js.map +1 -1
  53. package/lib/module/shared/utils/animation/spring/spring.js +7 -3
  54. package/lib/module/shared/utils/animation/spring/spring.js.map +1 -1
  55. package/lib/typescript/shared/components/create-transition-aware-component.d.ts.map +1 -1
  56. package/lib/typescript/shared/index.d.ts +1 -1
  57. package/lib/typescript/shared/index.d.ts.map +1 -1
  58. package/lib/typescript/shared/providers/screen/animation/helpers/hydrate-transition-state/index.d.ts.map +1 -1
  59. package/lib/typescript/shared/providers/screen/animation/helpers/hydrate-transition-state/types.d.ts +2 -0
  60. package/lib/typescript/shared/providers/screen/animation/helpers/hydrate-transition-state/types.d.ts.map +1 -1
  61. package/lib/typescript/shared/providers/screen/animation/helpers/use-build-transition-state.d.ts +2 -1
  62. package/lib/typescript/shared/providers/screen/animation/helpers/use-build-transition-state.d.ts.map +1 -1
  63. package/lib/typescript/shared/providers/screen/gestures/pan/activation/pan-activation-decision.d.ts.map +1 -1
  64. package/lib/typescript/shared/providers/screen/gestures/scroll-coordination/index.d.ts +1 -0
  65. package/lib/typescript/shared/providers/screen/gestures/scroll-coordination/index.d.ts.map +1 -1
  66. package/lib/typescript/shared/providers/screen/gestures/scroll-coordination/scroll-metadata-owner.d.ts +12 -0
  67. package/lib/typescript/shared/providers/screen/gestures/scroll-coordination/scroll-metadata-owner.d.ts.map +1 -0
  68. package/lib/typescript/shared/providers/screen/gestures/scroll-coordination/update-scroll-gesture-state.d.ts +5 -1
  69. package/lib/typescript/shared/providers/screen/gestures/scroll-coordination/update-scroll-gesture-state.d.ts.map +1 -1
  70. package/lib/typescript/shared/providers/screen/gestures/scroll-coordination/use-scroll-gesture-coordination.d.ts +4 -0
  71. package/lib/typescript/shared/providers/screen/gestures/scroll-coordination/use-scroll-gesture-coordination.d.ts.map +1 -1
  72. package/lib/typescript/shared/providers/screen/gestures/types.d.ts +2 -2
  73. package/lib/typescript/shared/providers/screen/gestures/types.d.ts.map +1 -1
  74. package/lib/typescript/shared/stores/scroll.store.d.ts +15 -8
  75. package/lib/typescript/shared/stores/scroll.store.d.ts.map +1 -1
  76. package/lib/typescript/shared/types/gesture.types.d.ts +17 -1
  77. package/lib/typescript/shared/types/gesture.types.d.ts.map +1 -1
  78. package/lib/typescript/shared/types/index.d.ts +1 -1
  79. package/lib/typescript/shared/types/index.d.ts.map +1 -1
  80. package/lib/typescript/shared/types/screen.types.d.ts +8 -1
  81. package/lib/typescript/shared/types/screen.types.d.ts.map +1 -1
  82. package/lib/typescript/shared/utils/animation/spring/spring.d.ts.map +1 -1
  83. package/package.json +1 -1
  84. package/src/shared/components/create-boundary-component/hooks/use-measurer.ts +1 -1
  85. package/src/shared/components/create-transition-aware-component.tsx +14 -6
  86. package/src/shared/index.ts +4 -0
  87. package/src/shared/providers/screen/animation/helpers/hydrate-transition-state/index.ts +2 -0
  88. package/src/shared/providers/screen/animation/helpers/hydrate-transition-state/types.ts +2 -0
  89. package/src/shared/providers/screen/animation/helpers/use-build-transition-state.ts +4 -0
  90. package/src/shared/providers/screen/gestures/gestures.provider.tsx +1 -1
  91. package/src/shared/providers/screen/gestures/pan/activation/pan-activation-decision.ts +10 -1
  92. package/src/shared/providers/screen/gestures/scroll-coordination/index.ts +1 -0
  93. package/src/shared/providers/screen/gestures/scroll-coordination/scroll-metadata-owner.tsx +43 -0
  94. package/src/shared/providers/screen/gestures/scroll-coordination/update-scroll-gesture-state.ts +59 -4
  95. package/src/shared/providers/screen/gestures/scroll-coordination/use-scroll-gesture-coordination.ts +130 -8
  96. package/src/shared/providers/screen/gestures/types.ts +2 -0
  97. package/src/shared/stores/scroll.store.ts +80 -7
  98. package/src/shared/types/gesture.types.ts +18 -1
  99. package/src/shared/types/index.ts +4 -0
  100. package/src/shared/types/screen.types.ts +8 -0
  101. package/src/shared/utils/animation/spring/spring.ts +7 -3
@@ -1,4 +1,4 @@
1
- import { useMemo } from "react";
1
+ import { useLayoutEffect, useMemo, useState } from "react";
2
2
  import type { LayoutChangeEvent } from "react-native";
3
3
  import { Gesture, type GestureType } from "react-native-gesture-handler";
4
4
  import {
@@ -9,13 +9,23 @@ import {
9
9
  import { useSharedValueState } from "../../../../hooks/reanimated/use-shared-value-state";
10
10
  import useStableCallback from "../../../../hooks/use-stable-callback";
11
11
  import { AnimationStore } from "../../../../stores/animation.store";
12
+ import { ScrollStore } from "../../../../stores/scroll.store";
12
13
  import { useGestureContext } from "../gestures.provider";
13
14
  import type {
14
15
  ScrollGestureAxis,
15
16
  ScrollGestureAxisState,
16
17
  ScrollGestureState,
18
+ ScrollMetadataState,
17
19
  } from "../types";
18
- import { updateScrollGestureAxisState } from "./update-scroll-gesture-state";
20
+ import {
21
+ useScrollMetadataOwnerContext,
22
+ useScrollMetadataOwnerProviderValue,
23
+ } from "./scroll-metadata-owner";
24
+ import {
25
+ clearScrollMetadataAxisState,
26
+ updateScrollGestureAxisState,
27
+ updateScrollMetadataAxisState,
28
+ } from "./update-scroll-gesture-state";
19
29
  import { walkUpScrollGestureCoordination } from "./walk-up-scroll-gesture-coordination";
20
30
 
21
31
  interface ScrollGestureCoordinationProps {
@@ -41,6 +51,31 @@ const modifyScrollGestureAxisState = (
41
51
  });
42
52
  };
43
53
 
54
+ const modifyScrollMetadataAxisState = (
55
+ scrollState: SharedValue<ScrollMetadataState | null>,
56
+ axis: ScrollGestureAxis,
57
+ patch: ScrollGesturePatch,
58
+ ) => {
59
+ "worklet";
60
+
61
+ scrollState.modify(<T extends ScrollMetadataState | null>(state: T): T => {
62
+ "worklet";
63
+ return updateScrollMetadataAxisState(state, axis, patch) as T;
64
+ });
65
+ };
66
+
67
+ const clearScrollMetadataAxis = (
68
+ scrollState: SharedValue<ScrollMetadataState | null>,
69
+ axis: ScrollGestureAxis,
70
+ ) => {
71
+ "worklet";
72
+
73
+ scrollState.modify(<T extends ScrollMetadataState | null>(state: T): T => {
74
+ "worklet";
75
+ return clearScrollMetadataAxisState(state, axis) as T;
76
+ });
77
+ };
78
+
44
79
  /**
45
80
  * Returns scroll handlers and a native gesture for ScrollView coordination.
46
81
  *
@@ -56,11 +91,63 @@ export const useScrollGestureCoordination = (
56
91
  const context = useGestureContext();
57
92
  const scrollDirection = props.direction ?? "vertical";
58
93
 
94
+ const metadataOwnerContext = useScrollMetadataOwnerContext();
95
+ const metadataOwnerProviderValue =
96
+ useScrollMetadataOwnerProviderValue(scrollDirection);
97
+ const isFirstMetadataWriterInTree = !metadataOwnerContext[scrollDirection];
98
+ const [metadataWriterId] = useState(() =>
99
+ ScrollStore.createMetadataWriterId(),
100
+ );
101
+ const [writesMetadata, setWritesMetadata] = useState(false);
102
+
59
103
  const { scrollStates, panGestures, pinchGestures, ownerRouteKeys } = useMemo(
60
104
  () => walkUpScrollGestureCoordination(context, scrollDirection),
61
105
  [context, scrollDirection],
62
106
  );
63
107
 
108
+ const routeKey = context?.routeKey;
109
+ const metadataState = useMemo(
110
+ () => (routeKey ? ScrollStore.getValue(routeKey, "metadata") : null),
111
+ [routeKey],
112
+ );
113
+
114
+ useLayoutEffect(() => {
115
+ if (!routeKey || !isFirstMetadataWriterInTree) {
116
+ setWritesMetadata(false);
117
+ return;
118
+ }
119
+
120
+ const claimed = ScrollStore.claimMetadataWriter(
121
+ routeKey,
122
+ scrollDirection,
123
+ metadataWriterId,
124
+ );
125
+ setWritesMetadata(claimed);
126
+
127
+ return () => {
128
+ const released = ScrollStore.releaseMetadataWriter(
129
+ routeKey,
130
+ scrollDirection,
131
+ metadataWriterId,
132
+ );
133
+
134
+ if (!released || !metadataState) return;
135
+
136
+ if (!ScrollStore.hasMetadataWriters(routeKey)) {
137
+ metadataState.set(null);
138
+ return;
139
+ }
140
+
141
+ clearScrollMetadataAxis(metadataState, scrollDirection);
142
+ };
143
+ }, [
144
+ routeKey,
145
+ scrollDirection,
146
+ isFirstMetadataWriterInTree,
147
+ metadataState,
148
+ metadataWriterId,
149
+ ]);
150
+
64
151
  const ownerClosingValues = useMemo(
65
152
  () =>
66
153
  ownerRouteKeys.map((routeKey) =>
@@ -92,6 +179,12 @@ export const useScrollGestureCoordination = (
92
179
  isTouched: true,
93
180
  });
94
181
  }
182
+
183
+ if (writesMetadata && metadataState) {
184
+ modifyScrollMetadataAxisState(metadataState, scrollDirection, {
185
+ isTouched: true,
186
+ });
187
+ }
95
188
  };
96
189
 
97
190
  const clearIsTouched = () => {
@@ -101,6 +194,12 @@ export const useScrollGestureCoordination = (
101
194
  isTouched: false,
102
195
  });
103
196
  }
197
+
198
+ if (writesMetadata && metadataState) {
199
+ modifyScrollMetadataAxisState(metadataState, scrollDirection, {
200
+ isTouched: false,
201
+ });
202
+ }
104
203
  };
105
204
 
106
205
  let gesture = Gesture.Native()
@@ -121,12 +220,17 @@ export const useScrollGestureCoordination = (
121
220
  }
122
221
 
123
222
  return gesture;
124
- }, [panGestures, pinchGestures, scrollStates, scrollDirection]);
223
+ }, [
224
+ panGestures,
225
+ pinchGestures,
226
+ scrollStates,
227
+ scrollDirection,
228
+ writesMetadata,
229
+ metadataState,
230
+ ]);
125
231
 
126
232
  const scrollHandler = useAnimatedScrollHandler({
127
233
  onScroll: (event) => {
128
- if (scrollStates.length === 0) return;
129
-
130
234
  const offset =
131
235
  scrollDirection === "horizontal"
132
236
  ? event.contentOffset.x
@@ -135,7 +239,14 @@ export const useScrollGestureCoordination = (
135
239
  for (const scrollState of scrollStates) {
136
240
  modifyScrollGestureAxisState(scrollState, scrollDirection, {
137
241
  offset,
138
- isTouched: scrollState.get()?.isTouched ?? true,
242
+ isTouched: scrollState.get()?.[scrollDirection].isTouched ?? true,
243
+ });
244
+ }
245
+
246
+ if (writesMetadata && metadataState) {
247
+ modifyScrollMetadataAxisState(metadataState, scrollDirection, {
248
+ offset,
249
+ isTouched: metadataState.get()?.[scrollDirection]?.isTouched ?? true,
139
250
  });
140
251
  }
141
252
  },
@@ -144,7 +255,6 @@ export const useScrollGestureCoordination = (
144
255
  const onContentSizeChange = useStableCallback(
145
256
  (width: number, height: number) => {
146
257
  props.onContentSizeChange?.(width, height);
147
- if (scrollStates.length === 0) return;
148
258
 
149
259
  const contentSize = scrollDirection === "horizontal" ? width : height;
150
260
 
@@ -153,12 +263,17 @@ export const useScrollGestureCoordination = (
153
263
  contentSize,
154
264
  });
155
265
  }
266
+
267
+ if (writesMetadata && metadataState) {
268
+ modifyScrollMetadataAxisState(metadataState, scrollDirection, {
269
+ contentSize,
270
+ });
271
+ }
156
272
  },
157
273
  );
158
274
 
159
275
  const onLayout = useStableCallback((event: LayoutChangeEvent) => {
160
276
  props.onLayout?.(event);
161
- if (scrollStates.length === 0) return;
162
277
 
163
278
  const { width, height } = event.nativeEvent.layout;
164
279
  const layoutSize = scrollDirection === "horizontal" ? width : height;
@@ -168,6 +283,12 @@ export const useScrollGestureCoordination = (
168
283
  layoutSize,
169
284
  });
170
285
  }
286
+
287
+ if (writesMetadata && metadataState) {
288
+ modifyScrollMetadataAxisState(metadataState, scrollDirection, {
289
+ layoutSize,
290
+ });
291
+ }
171
292
  });
172
293
 
173
294
  return {
@@ -176,5 +297,6 @@ export const useScrollGestureCoordination = (
176
297
  onContentSizeChange,
177
298
  onLayout,
178
299
  nativeGesture,
300
+ metadataOwnerProviderValue,
179
301
  };
180
302
  };
@@ -21,6 +21,7 @@ import type {
21
21
  ScrollGestureAxis,
22
22
  ScrollGestureAxisState,
23
23
  ScrollGestureState,
24
+ ScrollMetadataState,
24
25
  SnapPanDirectionConfig,
25
26
  SnapPinchDirectionConfig,
26
27
  } from "../../../types/gesture.types";
@@ -56,6 +57,7 @@ export type {
56
57
  ScrollGestureAxis,
57
58
  ScrollGestureAxisState,
58
59
  ScrollGestureState,
60
+ ScrollMetadataState,
59
61
  };
60
62
 
61
63
  export type DirectionClaim = {
@@ -3,23 +3,96 @@ import {
3
3
  makeMutable,
4
4
  type SharedValue,
5
5
  } from "react-native-reanimated";
6
- import type { ScrollGestureState } from "../types/gesture.types";
6
+ import type {
7
+ ScrollGestureAxis,
8
+ ScrollGestureState,
9
+ ScrollMetadataState,
10
+ } from "../types/gesture.types";
11
+ import type { ScreenKey } from "../types/screen.types";
7
12
  import { createStore } from "../utils/create-store";
8
13
 
9
14
  export type ScrollStoreMap = {
10
- state: SharedValue<ScrollGestureState | null>;
15
+ coordination: SharedValue<ScrollGestureState | null>;
16
+ metadata: SharedValue<ScrollMetadataState | null>;
17
+ };
18
+
19
+ const metadataWriters: Record<
20
+ ScreenKey,
21
+ Partial<Record<ScrollGestureAxis, string>>
22
+ > = {};
23
+
24
+ let nextMetadataWriterId = 0;
25
+
26
+ const createMetadataWriterId = () => {
27
+ nextMetadataWriterId += 1;
28
+ return `scroll-metadata-${nextMetadataWriterId}`;
29
+ };
30
+
31
+ const claimMetadataWriter = (
32
+ routeKey: ScreenKey,
33
+ axis: ScrollGestureAxis,
34
+ writerId: string,
35
+ ): boolean => {
36
+ const writers = metadataWriters[routeKey] ?? {};
37
+ metadataWriters[routeKey] = writers;
38
+
39
+ if (!writers[axis]) {
40
+ writers[axis] = writerId;
41
+ }
42
+
43
+ return writers[axis] === writerId;
44
+ };
45
+
46
+ const releaseMetadataWriter = (
47
+ routeKey: ScreenKey,
48
+ axis: ScrollGestureAxis,
49
+ writerId: string,
50
+ ): boolean => {
51
+ const writers = metadataWriters[routeKey];
52
+ if (!writers || writers[axis] !== writerId) return false;
53
+
54
+ delete writers[axis];
55
+
56
+ if (!writers.vertical && !writers.horizontal) {
57
+ delete metadataWriters[routeKey];
58
+ }
59
+
60
+ return true;
61
+ };
62
+
63
+ const hasMetadataWriters = (routeKey: ScreenKey): boolean => {
64
+ const writers = metadataWriters[routeKey];
65
+ return Boolean(writers?.vertical || writers?.horizontal);
66
+ };
67
+
68
+ const clearMetadataWriters = (routeKey: ScreenKey) => {
69
+ delete metadataWriters[routeKey];
11
70
  };
12
71
 
13
72
  /**
14
73
  * Route-keyed scroll geometry used by gesture activation and bounds measurement.
15
- * The state tracks coordinated ScrollView offsets and dimensions so consumers
16
- * can reason about overscroll without coupling to a specific scroll component.
74
+ * Coordination tracks gesture-owner scoped ScrollView offsets and dimensions;
75
+ * metadata tracks screen-scoped scroll values exposed to animation consumers.
17
76
  */
18
- export const ScrollStore = createStore<ScrollStoreMap>({
77
+ const scrollStore = createStore<ScrollStoreMap>({
19
78
  createBag: () => ({
20
- state: makeMutable<ScrollGestureState | null>(null),
79
+ coordination: makeMutable<ScrollGestureState | null>(null),
80
+ metadata: makeMutable<ScrollMetadataState | null>(null),
21
81
  }),
22
82
  disposeBag: (bag) => {
23
- cancelAnimation(bag.state);
83
+ cancelAnimation(bag.coordination);
84
+ cancelAnimation(bag.metadata);
24
85
  },
25
86
  });
87
+
88
+ export const ScrollStore = {
89
+ ...scrollStore,
90
+ createMetadataWriterId,
91
+ claimMetadataWriter,
92
+ releaseMetadataWriter,
93
+ hasMetadataWriters,
94
+ clearBag(routeKey: ScreenKey) {
95
+ clearMetadataWriters(routeKey);
96
+ scrollStore.clearBag(routeKey);
97
+ },
98
+ };
@@ -20,18 +20,35 @@ export type GestureProgressMode = "progress-driven" | "freeform";
20
20
 
21
21
  export type SnapPanAxis = "horizontal" | "vertical";
22
22
 
23
+ /**
24
+ * Axis reported by a transition-aware scrollable.
25
+ */
23
26
  export type ScrollGestureAxis = "vertical" | "horizontal";
24
27
 
28
+ /**
29
+ * Scroll geometry for one axis of a transition-aware scrollable.
30
+ */
25
31
  export type ScrollGestureAxisState = {
26
32
  offset: number;
27
33
  contentSize: number;
28
34
  layoutSize: number;
35
+ isTouched: boolean;
36
+ };
37
+
38
+ /**
39
+ * Scroll metadata exposed through screen transition layouts.
40
+ */
41
+ export type ScrollMetadataState = {
42
+ vertical: ScrollGestureAxisState | null;
43
+ horizontal: ScrollGestureAxisState | null;
29
44
  };
30
45
 
46
+ /**
47
+ * Scroll geometry used by gesture coordination.
48
+ */
31
49
  export type ScrollGestureState = {
32
50
  vertical: ScrollGestureAxisState;
33
51
  horizontal: ScrollGestureAxisState;
34
- isTouched: boolean;
35
52
  };
36
53
 
37
54
  export type SnapPanAxisConfig = {
@@ -36,6 +36,10 @@ export type {
36
36
  GestureValues,
37
37
  PanGestureDirection,
38
38
  PinchGestureDirection,
39
+ ScrollGestureAxis,
40
+ ScrollGestureAxisState,
41
+ ScrollGestureState,
42
+ ScrollMetadataState,
39
43
  SideActivation,
40
44
  } from "./gesture.types";
41
45
  export type { OverlayProps } from "./overlay.types";
@@ -7,6 +7,7 @@ import type {
7
7
  GestureActivationArea,
8
8
  GestureDirectionOption,
9
9
  GestureProgressMode,
10
+ ScrollMetadataState,
10
11
  } from "./gesture.types";
11
12
  import type { OverlayProps } from "./overlay.types";
12
13
 
@@ -27,6 +28,13 @@ export type ScreenLayouts = {
27
28
  * auto snap-point sizing. It is undefined until a real measurement exists.
28
29
  */
29
30
  content?: Layout;
31
+ /**
32
+ * Scroll metadata from the primary transition-aware scrollable on this screen.
33
+ *
34
+ * For nested same-axis scrollables, the outermost scrollable owns that axis.
35
+ * Cross-axis nested scrollables can each publish their own axis.
36
+ */
37
+ scroll?: ScrollMetadataState;
30
38
  };
31
39
 
32
40
  export type ScreenKey = string;
@@ -142,7 +142,7 @@ export const withInternalSpring = ((
142
142
 
143
143
  let settled = false;
144
144
 
145
- const updateSettled = (animation: SpringAnimation) => {
145
+ const notifySettled = (animation: SpringAnimation) => {
146
146
  "worklet";
147
147
  if (settled) {
148
148
  return;
@@ -154,6 +154,10 @@ export const withInternalSpring = ((
154
154
 
155
155
  settled = true;
156
156
  animation.settled = true;
157
+ callback?.({
158
+ finished: false,
159
+ settled: true,
160
+ });
157
161
  };
158
162
 
159
163
  config.skipAnimation = !checkIfConfigIsValid(config);
@@ -215,7 +219,7 @@ export const withInternalSpring = ((
215
219
  return true;
216
220
  }
217
221
 
218
- updateSettled(animation);
222
+ notifySettled(animation);
219
223
 
220
224
  return false;
221
225
  }
@@ -310,7 +314,7 @@ export const withInternalSpring = ((
310
314
  ? previousAnimation?.startTimestamp || now
311
315
  : now;
312
316
 
313
- updateSettled(animation);
317
+ notifySettled(animation);
314
318
  }
315
319
 
316
320
  const animation = {