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.
- package/README.md +400 -335
- package/lib/module/components/Bridge.js +16 -0
- package/lib/module/components/Bridge.js.map +1 -0
- package/lib/module/components/FlatList.js +5 -62
- package/lib/module/components/FlatList.js.map +1 -1
- package/lib/module/components/Header.js +71 -13
- package/lib/module/components/Header.js.map +1 -1
- package/lib/module/components/HeaderDynamic.js +34 -0
- package/lib/module/components/HeaderDynamic.js.map +1 -0
- package/lib/module/components/HeaderMotion.js +59 -23
- package/lib/module/components/HeaderMotion.js.map +1 -1
- package/lib/module/components/HeaderPanBoundary.js +54 -0
- package/lib/module/components/HeaderPanBoundary.js.map +1 -0
- package/lib/module/components/NavigationBridge.js +20 -0
- package/lib/module/components/NavigationBridge.js.map +1 -0
- package/lib/module/components/ScrollManager.js +7 -5
- package/lib/module/components/ScrollManager.js.map +1 -1
- package/lib/module/components/ScrollView.js +6 -47
- package/lib/module/components/ScrollView.js.map +1 -1
- package/lib/module/components/createHeaderMotionScrollable.js +136 -0
- package/lib/module/components/createHeaderMotionScrollable.js.map +1 -0
- package/lib/module/components/index.js +3 -1
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/context.js +8 -1
- package/lib/module/context.js.map +1 -1
- package/lib/module/hooks/index.js +1 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useActiveScrollId.js +7 -6
- package/lib/module/hooks/useActiveScrollId.js.map +1 -1
- package/lib/module/hooks/useHeaderMotionBridge.js +14 -0
- package/lib/module/hooks/useHeaderMotionBridge.js.map +1 -0
- package/lib/module/hooks/useMotionProgress.js +10 -36
- package/lib/module/hooks/useMotionProgress.js.map +1 -1
- package/lib/module/hooks/useMotionProgress.test.js +56 -0
- package/lib/module/hooks/useMotionProgress.test.js.map +1 -0
- package/lib/module/hooks/useScrollManager.js +219 -109
- package/lib/module/hooks/useScrollManager.js.map +1 -1
- package/lib/module/index.js +21 -18
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/defaults.js +2 -1
- package/lib/module/utils/defaults.js.map +1 -1
- package/lib/module/utils/header.js +24 -0
- package/lib/module/utils/header.js.map +1 -0
- package/lib/module/utils/headerOffsetStyle.js +31 -0
- package/lib/module/utils/headerOffsetStyle.js.map +1 -0
- package/lib/module/utils/index.js +3 -0
- package/lib/module/utils/index.js.map +1 -1
- package/lib/module/utils/refreshControl.js +93 -0
- package/lib/module/utils/refreshControl.js.map +1 -0
- package/lib/module/utils/values.js +36 -0
- package/lib/module/utils/values.js.map +1 -1
- package/lib/typescript/src/components/Bridge.d.ts +19 -0
- package/lib/typescript/src/components/Bridge.d.ts.map +1 -0
- package/lib/typescript/src/components/FlatList.d.ts +7 -15
- package/lib/typescript/src/components/FlatList.d.ts.map +1 -1
- package/lib/typescript/src/components/Header.d.ts +73 -12
- package/lib/typescript/src/components/Header.d.ts.map +1 -1
- package/lib/typescript/src/components/HeaderDynamic.d.ts +11 -0
- package/lib/typescript/src/components/HeaderDynamic.d.ts.map +1 -0
- package/lib/typescript/src/components/HeaderMotion.d.ts +37 -18
- package/lib/typescript/src/components/HeaderMotion.d.ts.map +1 -1
- package/lib/typescript/src/components/HeaderPanBoundary.d.ts +11 -0
- package/lib/typescript/src/components/HeaderPanBoundary.d.ts.map +1 -0
- package/lib/typescript/src/components/NavigationBridge.d.ts +19 -0
- package/lib/typescript/src/components/NavigationBridge.d.ts.map +1 -0
- package/lib/typescript/src/components/ScrollManager.d.ts +18 -25
- package/lib/typescript/src/components/ScrollManager.d.ts.map +1 -1
- package/lib/typescript/src/components/ScrollView.d.ts +7 -14
- package/lib/typescript/src/components/ScrollView.d.ts.map +1 -1
- package/lib/typescript/src/components/createHeaderMotionScrollable.d.ts +86 -0
- package/lib/typescript/src/components/createHeaderMotionScrollable.d.ts.map +1 -0
- package/lib/typescript/src/components/index.d.ts +3 -1
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/context.d.ts +3 -13
- package/lib/typescript/src/context.d.ts.map +1 -1
- package/lib/typescript/src/hooks/index.d.ts +1 -0
- package/lib/typescript/src/hooks/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useActiveScrollId.d.ts +7 -6
- package/lib/typescript/src/hooks/useActiveScrollId.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useHeaderMotionBridge.d.ts +10 -0
- package/lib/typescript/src/hooks/useHeaderMotionBridge.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useMotionProgress.d.ts +8 -25
- package/lib/typescript/src/hooks/useMotionProgress.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useMotionProgress.test.d.ts +2 -0
- package/lib/typescript/src/hooks/useMotionProgress.test.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useScrollManager.d.ts +63 -31
- package/lib/typescript/src/hooks/useScrollManager.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +56 -26
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +63 -15
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils/defaults.d.ts +3 -2
- package/lib/typescript/src/utils/defaults.d.ts.map +1 -1
- package/lib/typescript/src/utils/header.d.ts +10 -0
- package/lib/typescript/src/utils/header.d.ts.map +1 -0
- package/lib/typescript/src/utils/headerOffsetStyle.d.ts +19 -0
- package/lib/typescript/src/utils/headerOffsetStyle.d.ts.map +1 -0
- package/lib/typescript/src/utils/index.d.ts +3 -0
- package/lib/typescript/src/utils/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/refreshControl.d.ts +150 -0
- package/lib/typescript/src/utils/refreshControl.d.ts.map +1 -0
- package/lib/typescript/src/utils/values.d.ts +4 -1
- package/lib/typescript/src/utils/values.d.ts.map +1 -1
- package/package.json +13 -5
- package/src/components/Bridge.tsx +29 -0
- package/src/components/FlatList.tsx +18 -84
- package/src/components/Header.tsx +159 -23
- package/src/components/HeaderDynamic.tsx +45 -0
- package/src/components/HeaderMotion.tsx +114 -41
- package/src/components/HeaderPanBoundary.tsx +92 -0
- package/src/components/NavigationBridge.tsx +30 -0
- package/src/components/ScrollManager.tsx +38 -43
- package/src/components/ScrollView.tsx +16 -68
- package/src/components/createHeaderMotionScrollable.tsx +438 -0
- package/src/components/index.ts +3 -1
- package/src/context.ts +12 -18
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useActiveScrollId.ts +7 -6
- package/src/hooks/useHeaderMotionBridge.ts +15 -0
- package/src/hooks/useMotionProgress.test.ts +67 -0
- package/src/hooks/useMotionProgress.ts +12 -37
- package/src/hooks/useScrollManager.ts +310 -129
- package/src/index.ts +82 -36
- package/src/types.ts +85 -25
- package/src/utils/defaults.ts +7 -1
- package/src/utils/header.tsx +52 -0
- package/src/utils/headerOffsetStyle.ts +40 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/refreshControl.tsx +118 -0
- package/src/utils/values.ts +57 -1
- package/lib/module/components/HeaderBase.js +0 -59
- package/lib/module/components/HeaderBase.js.map +0 -1
- package/lib/module/hooks/refreshControl.js +0 -31
- package/lib/module/hooks/refreshControl.js.map +0 -1
- package/lib/typescript/src/components/HeaderBase.d.ts +0 -34
- package/lib/typescript/src/components/HeaderBase.d.ts.map +0 -1
- package/lib/typescript/src/hooks/refreshControl.d.ts +0 -13
- package/lib/typescript/src/hooks/refreshControl.d.ts.map +0 -1
- package/src/components/HeaderBase.tsx +0 -51
- 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 {
|
|
5
|
-
import {
|
|
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,
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
}, [
|
|
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
|
-
|
|
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
|
-
|
|
103
|
+
const scrollValue = value[id];
|
|
109
104
|
if (!scrollValue) {
|
|
110
|
-
value
|
|
111
|
-
scrollValue = value[id];
|
|
105
|
+
return value;
|
|
112
106
|
}
|
|
113
107
|
const progressDiff = oldProgress - newProgress;
|
|
114
|
-
newCur = scrollValue.current - progressDiff *
|
|
115
|
-
const newMin = newCur - newProgress *
|
|
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
|
-
|
|
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 -
|
|
169
|
+
value[id].min = Math.max(0, newCurrent - threshold);
|
|
143
170
|
}
|
|
144
171
|
return value;
|
|
145
172
|
});
|
|
146
|
-
}, [
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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(
|
|
174
|
-
|
|
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
|
-
|
|
290
|
+
contentContainerMinHeight
|
|
181
291
|
};
|
|
182
292
|
return {
|
|
183
293
|
scrollableProps,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useContext","useCallback","useEffect","
|
|
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":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -1,42 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import {
|
|
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
|
-
*
|
|
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.
|
|
18
|
-
* {(
|
|
14
|
+
* <HeaderMotion.Bridge>
|
|
15
|
+
* {(value) => (
|
|
19
16
|
* <Stack.Screen
|
|
20
17
|
* options={{
|
|
21
18
|
* header: () => (
|
|
22
|
-
* <
|
|
19
|
+
* <HeaderMotion.NavigationBridge value={value}>
|
|
20
|
+
* <MyAnimatedHeader />
|
|
21
|
+
* </HeaderMotion.NavigationBridge>
|
|
23
22
|
* ),
|
|
24
23
|
* }}
|
|
25
24
|
* />
|
|
26
25
|
* )}
|
|
27
|
-
* </HeaderMotion.
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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 {
|
|
43
|
+
export { createHeaderMotionScrollable };
|
|
44
|
+
export { Bridge, Header, NavigationBridge };
|
|
42
45
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
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":";;
|
|
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 +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":[]}
|