react-native-header-motion 0.4.0 → 1.0.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 (140) hide show
  1. package/README.md +400 -335
  2. package/lib/module/components/Bridge.js +16 -0
  3. package/lib/module/components/Bridge.js.map +1 -0
  4. package/lib/module/components/FlatList.js +5 -62
  5. package/lib/module/components/FlatList.js.map +1 -1
  6. package/lib/module/components/Header.js +71 -13
  7. package/lib/module/components/Header.js.map +1 -1
  8. package/lib/module/components/HeaderDynamic.js +34 -0
  9. package/lib/module/components/HeaderDynamic.js.map +1 -0
  10. package/lib/module/components/HeaderMotion.js +59 -23
  11. package/lib/module/components/HeaderMotion.js.map +1 -1
  12. package/lib/module/components/HeaderPanBoundary.js +54 -0
  13. package/lib/module/components/HeaderPanBoundary.js.map +1 -0
  14. package/lib/module/components/NavigationBridge.js +20 -0
  15. package/lib/module/components/NavigationBridge.js.map +1 -0
  16. package/lib/module/components/ScrollManager.js +7 -5
  17. package/lib/module/components/ScrollManager.js.map +1 -1
  18. package/lib/module/components/ScrollView.js +6 -47
  19. package/lib/module/components/ScrollView.js.map +1 -1
  20. package/lib/module/components/createHeaderMotionScrollable.js +136 -0
  21. package/lib/module/components/createHeaderMotionScrollable.js.map +1 -0
  22. package/lib/module/components/index.js +3 -1
  23. package/lib/module/components/index.js.map +1 -1
  24. package/lib/module/context.js +8 -1
  25. package/lib/module/context.js.map +1 -1
  26. package/lib/module/hooks/index.js +1 -0
  27. package/lib/module/hooks/index.js.map +1 -1
  28. package/lib/module/hooks/useActiveScrollId.js +7 -6
  29. package/lib/module/hooks/useActiveScrollId.js.map +1 -1
  30. package/lib/module/hooks/useHeaderMotionBridge.js +14 -0
  31. package/lib/module/hooks/useHeaderMotionBridge.js.map +1 -0
  32. package/lib/module/hooks/useMotionProgress.js +10 -36
  33. package/lib/module/hooks/useMotionProgress.js.map +1 -1
  34. package/lib/module/hooks/useMotionProgress.test.js +56 -0
  35. package/lib/module/hooks/useMotionProgress.test.js.map +1 -0
  36. package/lib/module/hooks/useScrollManager.js +219 -109
  37. package/lib/module/hooks/useScrollManager.js.map +1 -1
  38. package/lib/module/index.js +21 -18
  39. package/lib/module/index.js.map +1 -1
  40. package/lib/module/utils/defaults.js +2 -1
  41. package/lib/module/utils/defaults.js.map +1 -1
  42. package/lib/module/utils/header.js +24 -0
  43. package/lib/module/utils/header.js.map +1 -0
  44. package/lib/module/utils/headerOffsetStyle.js +31 -0
  45. package/lib/module/utils/headerOffsetStyle.js.map +1 -0
  46. package/lib/module/utils/index.js +3 -0
  47. package/lib/module/utils/index.js.map +1 -1
  48. package/lib/module/utils/refreshControl.js +93 -0
  49. package/lib/module/utils/refreshControl.js.map +1 -0
  50. package/lib/module/utils/values.js +36 -0
  51. package/lib/module/utils/values.js.map +1 -1
  52. package/lib/typescript/src/components/Bridge.d.ts +19 -0
  53. package/lib/typescript/src/components/Bridge.d.ts.map +1 -0
  54. package/lib/typescript/src/components/FlatList.d.ts +7 -15
  55. package/lib/typescript/src/components/FlatList.d.ts.map +1 -1
  56. package/lib/typescript/src/components/Header.d.ts +73 -12
  57. package/lib/typescript/src/components/Header.d.ts.map +1 -1
  58. package/lib/typescript/src/components/HeaderDynamic.d.ts +11 -0
  59. package/lib/typescript/src/components/HeaderDynamic.d.ts.map +1 -0
  60. package/lib/typescript/src/components/HeaderMotion.d.ts +37 -18
  61. package/lib/typescript/src/components/HeaderMotion.d.ts.map +1 -1
  62. package/lib/typescript/src/components/HeaderPanBoundary.d.ts +11 -0
  63. package/lib/typescript/src/components/HeaderPanBoundary.d.ts.map +1 -0
  64. package/lib/typescript/src/components/NavigationBridge.d.ts +19 -0
  65. package/lib/typescript/src/components/NavigationBridge.d.ts.map +1 -0
  66. package/lib/typescript/src/components/ScrollManager.d.ts +18 -25
  67. package/lib/typescript/src/components/ScrollManager.d.ts.map +1 -1
  68. package/lib/typescript/src/components/ScrollView.d.ts +7 -14
  69. package/lib/typescript/src/components/ScrollView.d.ts.map +1 -1
  70. package/lib/typescript/src/components/createHeaderMotionScrollable.d.ts +86 -0
  71. package/lib/typescript/src/components/createHeaderMotionScrollable.d.ts.map +1 -0
  72. package/lib/typescript/src/components/index.d.ts +3 -1
  73. package/lib/typescript/src/components/index.d.ts.map +1 -1
  74. package/lib/typescript/src/context.d.ts +3 -13
  75. package/lib/typescript/src/context.d.ts.map +1 -1
  76. package/lib/typescript/src/hooks/index.d.ts +1 -0
  77. package/lib/typescript/src/hooks/index.d.ts.map +1 -1
  78. package/lib/typescript/src/hooks/useActiveScrollId.d.ts +7 -6
  79. package/lib/typescript/src/hooks/useActiveScrollId.d.ts.map +1 -1
  80. package/lib/typescript/src/hooks/useHeaderMotionBridge.d.ts +10 -0
  81. package/lib/typescript/src/hooks/useHeaderMotionBridge.d.ts.map +1 -0
  82. package/lib/typescript/src/hooks/useMotionProgress.d.ts +8 -25
  83. package/lib/typescript/src/hooks/useMotionProgress.d.ts.map +1 -1
  84. package/lib/typescript/src/hooks/useMotionProgress.test.d.ts +2 -0
  85. package/lib/typescript/src/hooks/useMotionProgress.test.d.ts.map +1 -0
  86. package/lib/typescript/src/hooks/useScrollManager.d.ts +63 -31
  87. package/lib/typescript/src/hooks/useScrollManager.d.ts.map +1 -1
  88. package/lib/typescript/src/index.d.ts +56 -26
  89. package/lib/typescript/src/index.d.ts.map +1 -1
  90. package/lib/typescript/src/types.d.ts +63 -15
  91. package/lib/typescript/src/types.d.ts.map +1 -1
  92. package/lib/typescript/src/utils/defaults.d.ts +3 -2
  93. package/lib/typescript/src/utils/defaults.d.ts.map +1 -1
  94. package/lib/typescript/src/utils/header.d.ts +10 -0
  95. package/lib/typescript/src/utils/header.d.ts.map +1 -0
  96. package/lib/typescript/src/utils/headerOffsetStyle.d.ts +19 -0
  97. package/lib/typescript/src/utils/headerOffsetStyle.d.ts.map +1 -0
  98. package/lib/typescript/src/utils/index.d.ts +3 -0
  99. package/lib/typescript/src/utils/index.d.ts.map +1 -1
  100. package/lib/typescript/src/utils/refreshControl.d.ts +150 -0
  101. package/lib/typescript/src/utils/refreshControl.d.ts.map +1 -0
  102. package/lib/typescript/src/utils/values.d.ts +4 -1
  103. package/lib/typescript/src/utils/values.d.ts.map +1 -1
  104. package/package.json +13 -5
  105. package/src/components/Bridge.tsx +29 -0
  106. package/src/components/FlatList.tsx +18 -84
  107. package/src/components/Header.tsx +159 -23
  108. package/src/components/HeaderDynamic.tsx +45 -0
  109. package/src/components/HeaderMotion.tsx +114 -41
  110. package/src/components/HeaderPanBoundary.tsx +92 -0
  111. package/src/components/NavigationBridge.tsx +30 -0
  112. package/src/components/ScrollManager.tsx +38 -43
  113. package/src/components/ScrollView.tsx +16 -68
  114. package/src/components/createHeaderMotionScrollable.tsx +438 -0
  115. package/src/components/index.ts +3 -1
  116. package/src/context.ts +12 -18
  117. package/src/hooks/index.ts +1 -0
  118. package/src/hooks/useActiveScrollId.ts +7 -6
  119. package/src/hooks/useHeaderMotionBridge.ts +15 -0
  120. package/src/hooks/useMotionProgress.test.ts +67 -0
  121. package/src/hooks/useMotionProgress.ts +12 -37
  122. package/src/hooks/useScrollManager.ts +310 -129
  123. package/src/index.ts +82 -36
  124. package/src/types.ts +85 -25
  125. package/src/utils/defaults.ts +7 -1
  126. package/src/utils/header.tsx +52 -0
  127. package/src/utils/headerOffsetStyle.ts +40 -0
  128. package/src/utils/index.ts +3 -0
  129. package/src/utils/refreshControl.tsx +118 -0
  130. package/src/utils/values.ts +57 -1
  131. package/lib/module/components/HeaderBase.js +0 -59
  132. package/lib/module/components/HeaderBase.js.map +0 -1
  133. package/lib/module/hooks/refreshControl.js +0 -31
  134. package/lib/module/hooks/refreshControl.js.map +0 -1
  135. package/lib/typescript/src/components/HeaderBase.d.ts +0 -34
  136. package/lib/typescript/src/components/HeaderBase.d.ts.map +0 -1
  137. package/lib/typescript/src/hooks/refreshControl.d.ts +0 -13
  138. package/lib/typescript/src/hooks/refreshControl.d.ts.map +0 -1
  139. package/src/components/HeaderBase.tsx +0 -51
  140. package/src/hooks/refreshControl.ts +0 -55
@@ -1,82 +1,83 @@
1
1
  "use strict";
2
2
 
3
- import { useContext, useCallback, useEffect } from 'react';
4
- import { measure, scrollTo, useAnimatedReaction, useAnimatedRef, useAnimatedScrollHandler, useAnimatedStyle } from 'react-native-reanimated';
5
- import { RuntimeKind, scheduleOnUI } from 'react-native-worklets';
3
+ import { useContext, useCallback, useEffect, useState } from 'react';
4
+ import { cancelAnimation, scrollTo, useAnimatedReaction, useAnimatedRef, useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated';
5
+ import { scheduleOnRN, scheduleOnUI } from 'react-native-worklets';
6
6
  import { HeaderMotionContext } from "../context.js";
7
- import { DEFAULT_SCROLL_ID, getInitialScrollValue } from "../utils/index.js";
8
- import { resolveRefreshControl } from "./refreshControl.js";
7
+ import { resolveRefreshControl, DEFAULT_SCROLL_ID, ensureScrollValueRegistered, warnIfMissingActiveScrollId } from "../utils/index.js";
9
8
  import { useConsumerScrollHandlers, useScrollHandlerComposition } from "./useConsumerScrollHandlers.js";
10
-
11
- /**
12
- * Hook that manages scroll tracking and synchronization for header animations.
13
- * Returns props to apply to scrollable components and additional values that help with adjusting styling of the scrollables to header's dimensions.
14
- *
15
- * This hook handles:
16
- * - Scroll position tracking
17
- * - Synchronization between multiple scroll views (when using multiple scroll IDs)
18
- * - Content container minimum height calculations for cases where one of the tracked scrollables does not take enough space to reach the progress threshold/
19
- *
20
- * Must be used within a HeaderMotion component.
21
- *
22
- * @param scrollId - Optional unique identifier for the related scrollable.
23
- * Use when you have multiple scrollables (e.g., in tabs).
24
- * @param options - Optional configuration object.
25
- * @param options.animatedRef - Optional animated ref to use instead of creating one internally.
26
- * Useful when you need access to the scroll view ref from outside.
27
- * @returns Configuration object containing:
28
- * - `scrollableProps`: Props to apply to scrollable component (onScroll, scrollEventThrottle, ref)
29
- * - `headerMotionContext`: Header context values (originalHeaderHeight, minHeightContentContainerStyle)
30
- *
31
- * @throws Error if used outside of a HeaderMotion component
32
- *
33
- * @example
34
- * ```tsx
35
- * function CustomScrollComponent() {
36
- * const { scrollableProps, headerMotionContext } = useScrollManager('myScroll');
37
- *
38
- * return (
39
- * <CustomScrollView {...scrollableProps}>
40
- * <View style={{ paddingTop: headerMotionContext.originalHeaderHeight }}>
41
- * Content
42
- * </View>
43
- * </CustomScrollView>
44
- * );
45
- * }
46
- * ```
47
- */
48
-
49
- export function useScrollManager(scrollId, options) {
9
+ const SCROLL_TOLERANCE = 0.5;
10
+ function useScrollManagerContext() {
50
11
  const ctxValue = useContext(HeaderMotionContext);
51
12
  if (!ctxValue) {
52
13
  throw new Error('useScrollManager must be used within a HeaderMotion component');
53
14
  }
15
+ return ctxValue;
16
+ }
17
+ function useScrollManagerContentMinHeight({
18
+ enabled
19
+ }) {
20
+ const {
21
+ progressThreshold
22
+ } = useScrollManagerContext();
23
+ const preservedScrollContainerHeight = useSharedValue(0);
24
+ const [contentContainerMinHeight, setContentContainerMinHeight] = useState(undefined);
25
+ const handleLayout = useCallback(e => {
26
+ if (!enabled) {
27
+ return;
28
+ }
29
+ const nextHeight = e.nativeEvent.layout.height;
30
+ scheduleOnUI(height => {
31
+ 'worklet';
32
+
33
+ preservedScrollContainerHeight.set(height);
34
+ const nextMinHeight = height + progressThreshold.get();
35
+ scheduleOnRN(setContentContainerMinHeight, nextMinHeight);
36
+ }, nextHeight);
37
+ }, [enabled, preservedScrollContainerHeight, progressThreshold]);
38
+ useAnimatedReaction(() => progressThreshold.get(), (threshold, previousThreshold) => {
39
+ if (!enabled || previousThreshold === null || previousThreshold === threshold) {
40
+ return;
41
+ }
42
+ const currentHeight = preservedScrollContainerHeight.get();
43
+ if (currentHeight <= 0) {
44
+ return;
45
+ }
46
+ const nextMinHeight = currentHeight + threshold;
47
+ scheduleOnRN(setContentContainerMinHeight, nextMinHeight);
48
+ });
49
+ return {
50
+ contentContainerMinHeight,
51
+ handleLayout: enabled ? handleLayout : undefined
52
+ };
53
+ }
54
+ function useScrollManagerSynchronization({
55
+ animatedRef,
56
+ id
57
+ }) {
54
58
  const {
55
- scrollValues,
56
- progress,
57
59
  activeScrollId,
60
+ progress,
58
61
  progressThreshold,
59
- originalHeaderHeight
60
- } = ctxValue;
61
- const id = scrollId ?? DEFAULT_SCROLL_ID;
62
- const localRef = useAnimatedRef(); // TODO: better typing
63
- const animatedRef = options?.animatedRef ?? localRef;
64
- const refreshControl = options?.refreshControl;
65
- const refreshing = options?.refreshing;
66
- const onRefresh = options?.onRefresh;
67
- const progressViewOffset = options?.progressViewOffset ?? originalHeaderHeight;
68
- const {
69
- onScroll,
70
- onBeginDrag,
71
- onEndDrag,
72
- onMomentumBegin,
73
- onMomentumEnd
74
- } = useConsumerScrollHandlers({
75
- onScroll: options?.onScroll,
76
- onScrollBeginDrag: options?.onScrollBeginDrag,
77
- onScrollEndDrag: options?.onScrollEndDrag,
78
- onMomentumScrollBegin: options?.onMomentumScrollBegin,
79
- onMomentumScrollEnd: options?.onMomentumScrollEnd
62
+ scrollToRef,
63
+ scrollValues
64
+ } = useScrollManagerContext();
65
+ useAnimatedReaction(() => activeScrollId?.get(), activeId => {
66
+ const currentValues = ensureScrollValueRegistered(scrollValues, id);
67
+ warnIfMissingActiveScrollId(currentValues, id, activeId);
68
+ if (!activeId || activeId === id) {
69
+ // TODO: Could we just be passing current scrollRef instead of the entire function?
70
+ scrollToRef.current = (y, scrollOptions = {}) => {
71
+ 'worklet';
72
+
73
+ const {
74
+ isValueDelta = true,
75
+ animated = false
76
+ } = scrollOptions;
77
+ const newY = isValueDelta ? scrollValues.get()[id].current - y : y;
78
+ scrollTo(animatedRef, 0, newY, animated);
79
+ };
80
+ }
80
81
  });
81
82
  useEffect(() => {
82
83
  return () => {
@@ -89,30 +90,23 @@ export function useScrollManager(scrollId, options) {
89
90
  });
90
91
  }, id);
91
92
  };
92
- }, [scrollValues, id]);
93
+ }, [id, scrollValues]);
93
94
  useAnimatedReaction(() => progress.value, (newProgress, oldProgress) => {
94
- // FUTURE: If really needed for, can use other scroll handlers to only do this either on scroll end or between scroll end and momentum end in onScroll (keep context in shared value)
95
- // Only sync inactive scroll views when we have multiple tabs being tracked
96
95
  const currentActiveScrollId = activeScrollId?.get();
97
96
  if (!currentActiveScrollId || id === currentActiveScrollId || oldProgress === null) {
98
97
  return;
99
98
  }
100
- if (!scrollValues.get()[id]) {
101
- scrollValues.modify(value => {
102
- value[id] = getInitialScrollValue();
103
- return value;
104
- });
105
- }
99
+ ensureScrollValueRegistered(scrollValues, id);
106
100
  let newCur = -1;
101
+ const threshold = progressThreshold.get();
107
102
  scrollValues.modify(value => {
108
- let scrollValue = value[id];
103
+ const scrollValue = value[id];
109
104
  if (!scrollValue) {
110
- value[id] = getInitialScrollValue();
111
- scrollValue = value[id];
105
+ return value;
112
106
  }
113
107
  const progressDiff = oldProgress - newProgress;
114
- newCur = scrollValue.current - progressDiff * progressThreshold;
115
- const newMin = newCur - newProgress * progressThreshold;
108
+ newCur = scrollValue.current - progressDiff * threshold;
109
+ const newMin = newCur - newProgress * threshold;
116
110
  scrollValue.current = newCur;
117
111
  scrollValue.min = newMin;
118
112
  return value;
@@ -121,47 +115,163 @@ export function useScrollManager(scrollId, options) {
121
115
  scrollTo(animatedRef, 0, newCur, false);
122
116
  }
123
117
  });
124
- const scrollHandler = useCallback(e => {
118
+ }
119
+ function useScrollManagerHandlers({
120
+ consumerHandlers,
121
+ id
122
+ }) {
123
+ const {
124
+ activeScrollId,
125
+ headerPanMomentumOffset,
126
+ progressThreshold,
127
+ scrollValues
128
+ } = useScrollManagerContext();
129
+ const {
130
+ onScroll,
131
+ onBeginDrag,
132
+ onEndDrag,
133
+ onMomentumBegin,
134
+ onMomentumEnd
135
+ } = useConsumerScrollHandlers(consumerHandlers);
136
+ const handleScroll = useCallback((e, ctx) => {
125
137
  'worklet';
126
138
 
127
139
  onScroll?.(e);
140
+ const newCurrent = e.contentOffset.y;
141
+ if (ctx.lastOffset !== undefined && Math.abs(ctx.lastOffset - newCurrent) < SCROLL_TOLERANCE) {
142
+ return;
143
+ }
144
+ ctx.lastOffset = newCurrent;
145
+ const threshold = progressThreshold.get();
146
+ const values = scrollValues.get();
147
+ const scrollValue = values[id];
148
+ if (!scrollValue) {
149
+ return;
150
+ }
151
+ const activeScrollIdValue = activeScrollId?.get();
152
+ if (activeScrollIdValue && activeScrollIdValue !== id) {
153
+ return;
154
+ }
155
+ const oldCurrent = scrollValue.current;
156
+ const oldMin = scrollValue.min;
157
+ const isCollapsed = oldCurrent >= oldMin + threshold - 0.001;
158
+ if (isCollapsed && newCurrent >= threshold) {
159
+ scrollValue.current = newCurrent;
160
+ scrollValue.min = newCurrent - threshold;
161
+ return;
162
+ }
128
163
  scrollValues.modify(value => {
129
164
  if (!value[id]) {
130
165
  return value;
131
166
  }
132
- const activeScrollIdValue = activeScrollId?.get();
133
- if (activeScrollIdValue && activeScrollIdValue !== id) {
134
- return value;
135
- }
136
- const oldCurrent = value[id].current;
137
- const oldMin = value[id].min;
138
- const isCollapsed = oldCurrent >= oldMin + progressThreshold - 0.001;
139
- const newCurrent = e.contentOffset.y;
140
167
  value[id].current = newCurrent;
141
168
  if (isCollapsed) {
142
- value[id].min = Math.max(0, newCurrent - progressThreshold);
169
+ value[id].min = Math.max(0, newCurrent - threshold);
143
170
  }
144
171
  return value;
145
172
  });
146
- }, [scrollValues, id, activeScrollId, progressThreshold, onScroll]);
147
- const animatedScrollHandler = useAnimatedScrollHandler({
148
- onScroll: scrollHandler,
149
- onBeginDrag,
173
+ }, [activeScrollId, id, onScroll, progressThreshold, scrollValues]);
174
+ const handleBeginDrag = useCallback(e => {
175
+ 'worklet';
176
+
177
+ onBeginDrag?.(e);
178
+ if (headerPanMomentumOffset.get() === null) {
179
+ return;
180
+ }
181
+ cancelAnimation(headerPanMomentumOffset);
182
+ headerPanMomentumOffset.set(null);
183
+ }, [headerPanMomentumOffset, onBeginDrag]);
184
+ return useAnimatedScrollHandler({
185
+ onBeginDrag: handleBeginDrag,
186
+ onScroll: handleScroll,
150
187
  onEndDrag,
151
188
  onMomentumBegin,
152
189
  onMomentumEnd
153
190
  });
154
- const minHeightContentContainerStyle = useAnimatedStyle(() => {
155
- if (globalThis.__RUNTIME_KIND === RuntimeKind.ReactNative) {
156
- return {};
157
- }
158
- const measurement = measure(animatedRef);
159
- if (!measurement) {
160
- return {};
191
+ }
192
+ /**
193
+ * Wires a custom scrollable into HeaderMotion.
194
+ *
195
+ * Most code should not use this hook directly.
196
+ *
197
+ * **Prefer `createHeaderMotionScrollable()` whenever possible.** It gives
198
+ * you the same integration in a reusable component wrapper with less manual
199
+ * wiring. Reach for `useScrollManager()` only in more complex cases where the
200
+ * factory API is not enough, for example when a third-party scrollable needs
201
+ * highly custom composition.
202
+ *
203
+ * It returns two things:
204
+ * - `scrollableProps`: the event handlers / ref / refresh-control props that
205
+ * should go on the scrollable itself
206
+ * - `headerMotionContext`: layout values you can use to offset the content
207
+ * below the measured header
208
+ *
209
+ * In multi-scroll setups, pass a unique `scrollId` for each scrollable.
210
+ * In single-scroll setups, you usually do not need one.
211
+ *
212
+ * If you need the same fallback behavior but prefer render-prop composition
213
+ * over a hook, use `HeaderMotion.ScrollManager`.
214
+ *
215
+ * @param scrollId Optional unique identifier for the managed scrollable.
216
+ * @param options Optional configuration for refs, refresh handling, user
217
+ * scroll callbacks, and short-content fallback behavior.
218
+ * @returns Object containing:
219
+ * - `scrollableProps`: props to spread onto the scrollable (`ref`, managed
220
+ * `onScroll`, optional `onLayout`, and resolved `refreshControl`)
221
+ * - `headerMotionContext`: layout values for offsetting the content container
222
+ * (`originalHeaderHeight` and optional `contentContainerMinHeight`)
223
+ *
224
+ * @example
225
+ * ```tsx
226
+ * function CustomScrollComponent() {
227
+ * const { scrollableProps, headerMotionContext } = useScrollManager('myScroll');
228
+ *
229
+ * return (
230
+ * <CustomScrollView {...scrollableProps}>
231
+ * <View
232
+ * style={{
233
+ * paddingTop: headerMotionContext.originalHeaderHeight,
234
+ * minHeight: headerMotionContext.contentContainerMinHeight,
235
+ * }}
236
+ * >
237
+ * Content
238
+ * </View>
239
+ * </CustomScrollView>
240
+ * );
241
+ * }
242
+ * ```
243
+ */
244
+ export function useScrollManager(scrollId, options) {
245
+ const {
246
+ originalHeaderHeight
247
+ } = useScrollManagerContext();
248
+ const id = scrollId ?? DEFAULT_SCROLL_ID;
249
+ const ensureScrollableContentMinHeight = options?.ensureScrollableContentMinHeight ?? false;
250
+ const refreshControl = options?.refreshControl;
251
+ const refreshing = options?.refreshing;
252
+ const onRefresh = options?.onRefresh;
253
+ const progressViewOffset = options?.progressViewOffset ?? originalHeaderHeight;
254
+ const localRef = useAnimatedRef();
255
+ const animatedRef = options?.animatedRef ?? localRef;
256
+ const {
257
+ contentContainerMinHeight,
258
+ handleLayout
259
+ } = useScrollManagerContentMinHeight({
260
+ enabled: ensureScrollableContentMinHeight
261
+ });
262
+ useScrollManagerSynchronization({
263
+ id,
264
+ animatedRef
265
+ });
266
+ const animatedOnScroll = useScrollManagerHandlers({
267
+ id,
268
+ consumerHandlers: {
269
+ onScroll: options?.onScroll,
270
+ onScrollBeginDrag: options?.onScrollBeginDrag,
271
+ onScrollEndDrag: options?.onScrollEndDrag,
272
+ onMomentumScrollBegin: options?.onMomentumScrollBegin,
273
+ onMomentumScrollEnd: options?.onMomentumScrollEnd
161
274
  }
162
- return {
163
- minHeight: measurement.height + progressThreshold
164
- };
165
275
  });
166
276
  const resolvedRefreshControl = resolveRefreshControl({
167
277
  refreshControl,
@@ -170,14 +280,14 @@ export function useScrollManager(scrollId, options) {
170
280
  progressViewOffset
171
281
  });
172
282
  const scrollableProps = {
173
- onScroll: useScrollHandlerComposition(animatedScrollHandler, options?.onScroll),
174
- scrollEventThrottle: 16,
283
+ onScroll: useScrollHandlerComposition(animatedOnScroll, options?.onScroll),
284
+ onLayout: handleLayout,
175
285
  ref: animatedRef,
176
286
  refreshControl: resolvedRefreshControl
177
287
  };
178
288
  const headerMotionContext = {
179
289
  originalHeaderHeight,
180
- minHeightContentContainerStyle
290
+ contentContainerMinHeight
181
291
  };
182
292
  return {
183
293
  scrollableProps,
@@ -1 +1 @@
1
- {"version":3,"names":["useContext","useCallback","useEffect","measure","scrollTo","useAnimatedReaction","useAnimatedRef","useAnimatedScrollHandler","useAnimatedStyle","RuntimeKind","scheduleOnUI","HeaderMotionContext","DEFAULT_SCROLL_ID","getInitialScrollValue","resolveRefreshControl","useConsumerScrollHandlers","useScrollHandlerComposition","useScrollManager","scrollId","options","ctxValue","Error","scrollValues","progress","activeScrollId","progressThreshold","originalHeaderHeight","id","localRef","animatedRef","refreshControl","refreshing","onRefresh","progressViewOffset","onScroll","onBeginDrag","onEndDrag","onMomentumBegin","onMomentumEnd","onScrollBeginDrag","onScrollEndDrag","onMomentumScrollBegin","onMomentumScrollEnd","scrollIdToDelete","modify","value","newProgress","oldProgress","currentActiveScrollId","get","newCur","scrollValue","progressDiff","current","newMin","min","scrollHandler","e","activeScrollIdValue","oldCurrent","oldMin","isCollapsed","newCurrent","contentOffset","y","Math","max","animatedScrollHandler","minHeightContentContainerStyle","globalThis","__RUNTIME_KIND","ReactNative","measurement","minHeight","height","resolvedRefreshControl","scrollableProps","scrollEventThrottle","ref","headerMotionContext"],"sourceRoot":"../../../src","sources":["hooks/useScrollManager.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useContext","useCallback","useEffect","useState","cancelAnimation","scrollTo","useAnimatedReaction","useAnimatedRef","useAnimatedScrollHandler","useSharedValue","scheduleOnRN","scheduleOnUI","HeaderMotionContext","resolveRefreshControl","DEFAULT_SCROLL_ID","ensureScrollValueRegistered","warnIfMissingActiveScrollId","useConsumerScrollHandlers","useScrollHandlerComposition","SCROLL_TOLERANCE","useScrollManagerContext","ctxValue","Error","useScrollManagerContentMinHeight","enabled","progressThreshold","preservedScrollContainerHeight","contentContainerMinHeight","setContentContainerMinHeight","undefined","handleLayout","e","nextHeight","nativeEvent","layout","height","set","nextMinHeight","get","threshold","previousThreshold","currentHeight","useScrollManagerSynchronization","animatedRef","id","activeScrollId","progress","scrollToRef","scrollValues","activeId","currentValues","current","y","scrollOptions","isValueDelta","animated","newY","scrollIdToDelete","modify","value","newProgress","oldProgress","currentActiveScrollId","newCur","scrollValue","progressDiff","newMin","min","useScrollManagerHandlers","consumerHandlers","headerPanMomentumOffset","onScroll","onBeginDrag","onEndDrag","onMomentumBegin","onMomentumEnd","handleScroll","ctx","newCurrent","contentOffset","lastOffset","Math","abs","values","activeScrollIdValue","oldCurrent","oldMin","isCollapsed","max","handleBeginDrag","useScrollManager","scrollId","options","originalHeaderHeight","ensureScrollableContentMinHeight","refreshControl","refreshing","onRefresh","progressViewOffset","localRef","animatedOnScroll","onScrollBeginDrag","onScrollEndDrag","onMomentumScrollBegin","onMomentumScrollEnd","resolvedRefreshControl","scrollableProps","onLayout","ref","headerMotionContext"],"sourceRoot":"../../../src","sources":["hooks/useScrollManager.ts"],"mappings":"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","ignoreList":[]}
@@ -1,42 +1,45 @@
1
1
  "use strict";
2
2
 
3
- import { AnimatedHeaderBase, HeaderBase, HeaderMotionContextProvider, HeaderMotionFlatList, HeaderMotionHeader, HeaderMotionScrollManager, HeaderMotionScrollView } from "./components/index.js";
4
-
5
- /**
6
- * Compound component type for HeaderMotion.
7
- * Provides the main context provider and sub-components for building collapsible headers.
8
- */
9
-
3
+ import { createHeaderMotionScrollable, Bridge, HeaderMotionContextProvider, FlatList, Header, NavigationBridge, ScrollManager, ScrollView } from "./components/index.js";
10
4
  /**
11
5
  * Main HeaderMotion component.
12
- * A compound component that provides context for collapsible header animations.
6
+ * Root provider and compound entrypoint for the library.
7
+ *
8
+ * It tracks header measurements, derives the shared `progress` value, and
9
+ * exposes the pre-wired subcomponents used to connect headers and scrollables.
13
10
  *
14
11
  * @example
15
12
  * ```tsx
16
13
  * <HeaderMotion>
17
- * <HeaderMotion.Header>
18
- * {(headerProps) => (
14
+ * <HeaderMotion.Bridge>
15
+ * {(value) => (
19
16
  * <Stack.Screen
20
17
  * options={{
21
18
  * header: () => (
22
- * <MyAnimatedHeader {...headerProps} />
19
+ * <HeaderMotion.NavigationBridge value={value}>
20
+ * <MyAnimatedHeader />
21
+ * </HeaderMotion.NavigationBridge>
23
22
  * ),
24
23
  * }}
25
24
  * />
26
25
  * )}
27
- * </HeaderMotion.Header>
26
+ * </HeaderMotion.Bridge>
28
27
  * <HeaderMotion.ScrollView>
29
28
  * <MyScrollableContent />
30
29
  * </HeaderMotion.ScrollView>
31
30
  * </HeaderMotion>
32
31
  * ```
33
32
  */
34
- const HeaderMotion = HeaderMotionContextProvider;
35
- HeaderMotion.Header = HeaderMotionHeader;
36
- HeaderMotion.ScrollManager = HeaderMotionScrollManager;
37
- HeaderMotion.ScrollView = HeaderMotionScrollView;
38
- HeaderMotion.FlatList = HeaderMotionFlatList;
33
+ const HeaderMotion = Object.assign(HeaderMotionContextProvider, {
34
+ Header,
35
+ Bridge,
36
+ NavigationBridge,
37
+ ScrollManager,
38
+ ScrollView,
39
+ FlatList
40
+ });
39
41
  export default HeaderMotion;
40
42
  export * from "./hooks/index.js";
41
- export { AnimatedHeaderBase, HeaderBase };
43
+ export { createHeaderMotionScrollable };
44
+ export { Bridge, Header, NavigationBridge };
42
45
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["AnimatedHeaderBase","HeaderBase","HeaderMotionContextProvider","HeaderMotionFlatList","HeaderMotionHeader","HeaderMotionScrollManager","HeaderMotionScrollView","HeaderMotion","Header","ScrollManager","ScrollView","FlatList"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SACEA,kBAAkB,EAClBC,UAAU,EACVC,2BAA2B,EAC3BC,oBAAoB,EACpBC,kBAAkB,EAClBC,yBAAyB,EACzBC,sBAAsB,QAMjB,uBAAc;;AAGrB;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,YAAY,GAAGL,2BAAoD;AACzEK,YAAY,CAACC,MAAM,GAAGJ,kBAAkB;AACxCG,YAAY,CAACE,aAAa,GAAGJ,yBAAyB;AACtDE,YAAY,CAACG,UAAU,GAAGJ,sBAAsB;AAChDC,YAAY,CAACI,QAAQ,GAAGR,oBAAoB;AAE5C,eAAeI,YAAY;AAC3B,cAAc,kBAAS;AAEvB,SAASP,kBAAkB,EAAEC,UAAU","ignoreList":[]}
1
+ {"version":3,"names":["createHeaderMotionScrollable","Bridge","HeaderMotionContextProvider","FlatList","Header","NavigationBridge","ScrollManager","ScrollView","HeaderMotion","Object","assign"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SACEA,4BAA4B,EAC5BC,MAAM,EACNC,2BAA2B,EAC3BC,QAAQ,EACRC,MAAM,EACNC,gBAAgB,EAChBC,aAAa,EACbC,UAAU,QAUL,uBAAc;AA8CrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,YAAkC,GAAGC,MAAM,CAACC,MAAM,CACtDR,2BAA2B,EAC3B;EACEE,MAAM;EACNH,MAAM;EACNI,gBAAgB;EAChBC,aAAa;EACbC,UAAU;EACVJ;AACF,CACF,CAAC;AAED,eAAeK,YAAY;AAC3B,cAAc,kBAAS;AAEvB,SAASR,4BAA4B;AACrC,SAASC,MAAM,EAAEG,MAAM,EAAEC,gBAAgB","ignoreList":[]}
@@ -2,9 +2,10 @@
2
2
 
3
3
  const DEFAULT_PROGRESS_THRESHOLD = measuredHeaderValue => measuredHeaderValue;
4
4
  const DEFAULT_MEASURE_DYNAMIC = e => e.nativeEvent.layout.height;
5
+ const DEFAULT_HEADER_OFFSET_STRATEGY = 'padding';
5
6
 
6
7
  // Symbol doesn't work?
7
8
  // const DEFAULT_SCROLL_ID = Symbol("HEADER_MOTION_DEFAULT_SCROLL_ID");
8
9
  const DEFAULT_SCROLL_ID = '__HEADER_MOTION_DEFAULT_SCROLL_ID__';
9
- export { DEFAULT_MEASURE_DYNAMIC, DEFAULT_PROGRESS_THRESHOLD, DEFAULT_SCROLL_ID };
10
+ export { DEFAULT_HEADER_OFFSET_STRATEGY, DEFAULT_MEASURE_DYNAMIC, DEFAULT_PROGRESS_THRESHOLD, DEFAULT_SCROLL_ID };
10
11
  //# sourceMappingURL=defaults.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["DEFAULT_PROGRESS_THRESHOLD","measuredHeaderValue","DEFAULT_MEASURE_DYNAMIC","e","nativeEvent","layout","height","DEFAULT_SCROLL_ID"],"sourceRoot":"../../../src","sources":["utils/defaults.ts"],"mappings":";;AAEA,MAAMA,0BAA6C,GAAIC,mBAAmB,IACxEA,mBAAmB;AACrB,MAAMC,uBAA8C,GAAIC,CAAC,IACvDA,CAAC,CAACC,WAAW,CAACC,MAAM,CAACC,MAAM;;AAE7B;AACA;AACA,MAAMC,iBAAiB,GAAG,qCAAqC;AAE/D,SACEL,uBAAuB,EACvBF,0BAA0B,EAC1BO,iBAAiB","ignoreList":[]}
1
+ {"version":3,"names":["DEFAULT_PROGRESS_THRESHOLD","measuredHeaderValue","DEFAULT_MEASURE_DYNAMIC","e","nativeEvent","layout","height","DEFAULT_HEADER_OFFSET_STRATEGY","DEFAULT_SCROLL_ID"],"sourceRoot":"../../../src","sources":["utils/defaults.ts"],"mappings":";;AAMA,MAAMA,0BAA6C,GAAIC,mBAAmB,IACxEA,mBAAmB;AACrB,MAAMC,uBAA8C,GAAIC,CAAC,IACvDA,CAAC,CAACC,WAAW,CAACC,MAAM,CAACC,MAAM;AAC7B,MAAMC,8BAA0D,GAAG,SAAS;;AAE5E;AACA;AACA,MAAMC,iBAAiB,GAAG,qCAAqC;AAE/D,SACED,8BAA8B,EAC9BL,uBAAuB,EACvBF,0BAA0B,EAC1BQ,iBAAiB","ignoreList":[]}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ import { Fragment, cloneElement, isValidElement } from 'react';
4
+ export function composeOnLayoutHandlers(userHandler, internalHandler) {
5
+ return e => {
6
+ internalHandler?.(e);
7
+ userHandler?.(e);
8
+ };
9
+ }
10
+ export function resolveSlottableChild(componentName, child) {
11
+ if (! /*#__PURE__*/isValidElement(child) || child.type === Fragment) {
12
+ throw new Error(`${componentName} with \`asChild\` expects a single valid React element child that accepts \`onLayout\`.`);
13
+ }
14
+ return child;
15
+ }
16
+ export function cloneWithOnLayout(child, onLayout, componentName) {
17
+ if (! /*#__PURE__*/isValidElement(child)) {
18
+ throw new Error(`${componentName} with \`asChild\` expects a valid React element child.`);
19
+ }
20
+ return /*#__PURE__*/cloneElement(child, {
21
+ onLayout: composeOnLayoutHandlers(child.props.onLayout, onLayout)
22
+ });
23
+ }
24
+ //# sourceMappingURL=header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Fragment","cloneElement","isValidElement","composeOnLayoutHandlers","userHandler","internalHandler","e","resolveSlottableChild","componentName","child","type","Error","cloneWithOnLayout","onLayout","props"],"sourceRoot":"../../../src","sources":["utils/header.tsx"],"mappings":";;AAAA,SACEA,QAAQ,EACRC,YAAY,EACZC,cAAc,QAET,OAAO;AASd,OAAO,SAASC,uBAAuBA,CACrCC,WAAkC,EAClCC,eAAsC,EACtC;EACA,OAAQC,CAAoD,IAAK;IAC/DD,eAAe,GAAGC,CAAC,CAAC;IACpBF,WAAW,GAAGE,CAAC,CAAC;EAClB,CAAC;AACH;AAEA,OAAO,SAASC,qBAAqBA,CACnCC,aAAqB,EACrBC,KAAmB,EACnB;EACA,IAAI,eAACP,cAAc,CAACO,KAAK,CAAC,IAAIA,KAAK,CAACC,IAAI,KAAKV,QAAQ,EAAE;IACrD,MAAM,IAAIW,KAAK,CACb,GAAGH,aAAa,yFAClB,CAAC;EACH;EAEA,OAAOC,KAAK;AACd;AAEA,OAAO,SAASG,iBAAiBA,CAC/BH,KAAuB,EACvBI,QAA+B,EAC/BL,aAAqB,EACrB;EACA,IAAI,eAACN,cAAc,CAACO,KAAK,CAAC,EAAE;IAC1B,MAAM,IAAIE,KAAK,CACb,GAAGH,aAAa,wDAClB,CAAC;EACH;EAEA,oBAAOP,YAAY,CAACQ,KAAK,EAAE;IACzBI,QAAQ,EAAEV,uBAAuB,CAACM,KAAK,CAACK,KAAK,CAACD,QAAQ,EAAEA,QAAQ;EAClE,CAAC,CAAC;AACJ","ignoreList":[]}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ import { DEFAULT_HEADER_OFFSET_STRATEGY } from "./defaults.js";
4
+ export function resolveHeaderOffsetStyle(originalHeaderHeight, headerOffsetStrategy = DEFAULT_HEADER_OFFSET_STRATEGY) {
5
+ switch (headerOffsetStrategy) {
6
+ case 'none':
7
+ return undefined;
8
+ case 'margin':
9
+ return {
10
+ marginTop: originalHeaderHeight
11
+ };
12
+ case 'top':
13
+ return {
14
+ top: originalHeaderHeight,
15
+ paddingBottom: originalHeaderHeight
16
+ };
17
+ case 'translate':
18
+ return {
19
+ transform: [{
20
+ translateY: originalHeaderHeight
21
+ }],
22
+ paddingBottom: originalHeaderHeight
23
+ };
24
+ case 'padding':
25
+ default:
26
+ return {
27
+ paddingTop: originalHeaderHeight
28
+ };
29
+ }
30
+ }
31
+ //# sourceMappingURL=headerOffsetStyle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DEFAULT_HEADER_OFFSET_STRATEGY","resolveHeaderOffsetStyle","originalHeaderHeight","headerOffsetStrategy","undefined","marginTop","top","paddingBottom","transform","translateY","paddingTop"],"sourceRoot":"../../../src","sources":["utils/headerOffsetStyle.ts"],"mappings":";;AAEA,SAASA,8BAA8B,QAAQ,eAAY;AAc3D,OAAO,SAASC,wBAAwBA,CACtCC,oBAAuC,EACvCC,oBAAgD,GAAGH,8BAA8B,EAC9D;EACnB,QAAQG,oBAAoB;IAC1B,KAAK,MAAM;MACT,OAAOC,SAAS;IAClB,KAAK,QAAQ;MACX,OAAO;QAAEC,SAAS,EAAEH;MAAqB,CAAC;IAC5C,KAAK,KAAK;MACR,OAAO;QACLI,GAAG,EAAEJ,oBAAoB;QACzBK,aAAa,EAAEL;MACjB,CAAC;IACH,KAAK,WAAW;MACd,OAAO;QACLM,SAAS,EAAE,CAAC;UAAEC,UAAU,EAAEP;QAAqB,CAAC,CAAC;QACjDK,aAAa,EAAEL;MACjB,CAAC;IACH,KAAK,SAAS;IACd;MACE,OAAO;QAAEQ,UAAU,EAAER;MAAqB,CAAC;EAC/C;AACF","ignoreList":[]}
@@ -1,5 +1,8 @@
1
1
  "use strict";
2
2
 
3
3
  export * from "./defaults.js";
4
+ export * from "./header.js";
5
+ export * from "./headerOffsetStyle.js";
4
6
  export * from "./values.js";
7
+ export * from "./refreshControl.js";
5
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sourceRoot":"../../../src","sources":["utils/index.ts"],"mappings":";;AAAA,cAAc,eAAY;AAC1B,cAAc,aAAU","ignoreList":[]}
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["utils/index.ts"],"mappings":";;AAAA,cAAc,eAAY;AAC1B,cAAc,aAAU;AACxB,cAAc,wBAAqB;AACnC,cAAc,aAAU;AACxB,cAAc,qBAAkB","ignoreList":[]}