react-navigation-reanimated-top-tabs 0.7.0 → 0.9.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/lib/commonjs/components/ReanimatedTopTab/AnimationHelper.js +21 -26
- package/lib/commonjs/components/ReanimatedTopTab/AnimationHelper.js.map +1 -1
- package/lib/commonjs/components/ReanimatedTopTab/ReanimatedTabView.js +13 -12
- package/lib/commonjs/components/ReanimatedTopTab/ReanimatedTabView.js.map +1 -1
- package/lib/commonjs/components/elements/TabBarBaseComponent.js +42 -25
- package/lib/commonjs/components/elements/TabBarBaseComponent.js.map +1 -1
- package/lib/commonjs/components/elements/TabBarBaseItem.js +55 -0
- package/lib/commonjs/components/elements/TabBarBaseItem.js.map +1 -0
- package/lib/commonjs/components/elements/TabBarLabelBaseComponent.js +3 -3
- package/lib/commonjs/components/elements/TabBarLabelBaseComponent.js.map +1 -1
- package/lib/commonjs/components/wrappers/GestureWrapper.js +40 -11
- package/lib/commonjs/components/wrappers/GestureWrapper.js.map +1 -1
- package/lib/commonjs/components/wrappers/SectionList.js +72 -0
- package/lib/commonjs/components/wrappers/SectionList.js.map +1 -0
- package/lib/commonjs/context/Context.hooks.js +22 -17
- package/lib/commonjs/context/Context.hooks.js.map +1 -1
- package/lib/commonjs/context/Context.js +11 -8
- package/lib/commonjs/context/Context.js.map +1 -1
- package/lib/commonjs/hooks/useHeader.js +2 -10
- package/lib/commonjs/hooks/useHeader.js.map +1 -1
- package/lib/commonjs/hooks/useTabOffset.js +2 -2
- package/lib/commonjs/hooks/useTabOffset.js.map +1 -1
- package/lib/commonjs/index.js +2 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/navigator/createReanimatedTopTabNavigator.js +27 -23
- package/lib/commonjs/navigator/createReanimatedTopTabNavigator.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/module/components/ReanimatedTopTab/AnimationHelper.js +23 -28
- package/lib/module/components/ReanimatedTopTab/AnimationHelper.js.map +1 -1
- package/lib/module/components/ReanimatedTopTab/ReanimatedTabView.js +14 -13
- package/lib/module/components/ReanimatedTopTab/ReanimatedTabView.js.map +1 -1
- package/lib/module/components/elements/TabBarBaseComponent.js +44 -27
- package/lib/module/components/elements/TabBarBaseComponent.js.map +1 -1
- package/lib/module/components/elements/TabBarBaseItem.js +48 -0
- package/lib/module/components/elements/TabBarBaseItem.js.map +1 -0
- package/lib/module/components/elements/TabBarLabelBaseComponent.js +3 -3
- package/lib/module/components/elements/TabBarLabelBaseComponent.js.map +1 -1
- package/lib/module/components/wrappers/GestureWrapper.js +41 -12
- package/lib/module/components/wrappers/GestureWrapper.js.map +1 -1
- package/lib/module/components/wrappers/SectionList.js +66 -0
- package/lib/module/components/wrappers/SectionList.js.map +1 -0
- package/lib/module/context/Context.hooks.js +22 -17
- package/lib/module/context/Context.hooks.js.map +1 -1
- package/lib/module/context/Context.js +11 -8
- package/lib/module/context/Context.js.map +1 -1
- package/lib/module/hooks/useHeader.js +3 -11
- package/lib/module/hooks/useHeader.js.map +1 -1
- package/lib/module/hooks/useTabOffset.js +2 -2
- package/lib/module/hooks/useTabOffset.js.map +1 -1
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/navigator/createReanimatedTopTabNavigator.js +28 -24
- package/lib/module/navigator/createReanimatedTopTabNavigator.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/src/components/ReanimatedTopTab/AnimationHelper.d.ts.map +1 -1
- package/lib/typescript/src/components/ReanimatedTopTab/ReanimatedTabView.d.ts +2 -1
- package/lib/typescript/src/components/ReanimatedTopTab/ReanimatedTabView.d.ts.map +1 -1
- package/lib/typescript/src/components/ReanimatedTopTab/types.d.ts +3 -7
- package/lib/typescript/src/components/ReanimatedTopTab/types.d.ts.map +1 -1
- package/lib/typescript/src/components/elements/TabBarBaseComponent.d.ts +1 -1
- package/lib/typescript/src/components/elements/TabBarBaseComponent.d.ts.map +1 -1
- package/lib/typescript/src/components/elements/TabBarBaseItem.d.ts +12 -0
- package/lib/typescript/src/components/elements/TabBarBaseItem.d.ts.map +1 -0
- package/lib/typescript/src/components/wrappers/GestureWrapper.d.ts +2 -1
- package/lib/typescript/src/components/wrappers/GestureWrapper.d.ts.map +1 -1
- package/lib/typescript/src/components/wrappers/SectionList.d.ts +3 -0
- package/lib/typescript/src/components/wrappers/SectionList.d.ts.map +1 -0
- package/lib/typescript/src/context/Context.d.ts.map +1 -1
- package/lib/typescript/src/context/Context.hooks.d.ts +4 -3
- package/lib/typescript/src/context/Context.hooks.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useHeader.d.ts +0 -6
- package/lib/typescript/src/hooks/useHeader.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useScreenProperties.d.ts +1 -1
- package/lib/typescript/src/index.d.ts +3 -8
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/navigator/createReanimatedTopTabNavigator.d.ts +1 -1
- package/lib/typescript/src/navigator/createReanimatedTopTabNavigator.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +11 -5
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/ReanimatedTopTab/AnimationHelper.ts +24 -32
- package/src/components/ReanimatedTopTab/ReanimatedTabView.tsx +19 -17
- package/src/components/ReanimatedTopTab/types.ts +3 -5
- package/src/components/elements/TabBarBaseComponent.tsx +47 -36
- package/src/components/elements/TabBarBaseItem.tsx +76 -0
- package/src/components/elements/TabBarLabelBaseComponent.tsx +3 -3
- package/src/components/wrappers/GestureWrapper.tsx +41 -14
- package/src/components/wrappers/SectionList.tsx +75 -0
- package/src/context/Context.hooks.ts +26 -16
- package/src/context/Context.tsx +8 -5
- package/src/hooks/useHeader.ts +4 -22
- package/src/hooks/useTabOffset.ts +2 -2
- package/src/index.tsx +2 -0
- package/src/navigator/createReanimatedTopTabNavigator.tsx +31 -26
- package/src/types.ts +21 -5
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type DefaultSectionT,
|
|
3
|
+
type LayoutChangeEvent,
|
|
4
|
+
type SectionListProps,
|
|
5
|
+
SectionList as RNSectionList,
|
|
6
|
+
StyleSheet,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import { GestureDetector } from 'react-native-gesture-handler';
|
|
9
|
+
import Reanimated from 'react-native-reanimated';
|
|
10
|
+
import { useRef } from 'react';
|
|
11
|
+
import { useRoute } from '@react-navigation/native';
|
|
12
|
+
import { useTabContext } from '../../hooks/useTabContext';
|
|
13
|
+
import { useScreenGesture } from '../../hooks/useScreenGesture';
|
|
14
|
+
import { useScreenScrollable } from '../../hooks/useScreenScrollable';
|
|
15
|
+
import { useScreenProperties } from '../../hooks/useScreenProperties';
|
|
16
|
+
|
|
17
|
+
export const SectionList = <ItemT, SectionT = DefaultSectionT>({
|
|
18
|
+
children,
|
|
19
|
+
style,
|
|
20
|
+
contentContainerStyle,
|
|
21
|
+
onLayout,
|
|
22
|
+
...props
|
|
23
|
+
}: SectionListProps<ItemT, SectionT>) => {
|
|
24
|
+
const gesture = useScreenGesture();
|
|
25
|
+
const {
|
|
26
|
+
style: _style,
|
|
27
|
+
contentContainerStyle: _contentContainerStyle,
|
|
28
|
+
onScroll,
|
|
29
|
+
bounces,
|
|
30
|
+
animatedProps,
|
|
31
|
+
overScrollMode,
|
|
32
|
+
} = useScreenScrollable();
|
|
33
|
+
const { innerLayout } = useScreenProperties();
|
|
34
|
+
const { context } = useTabContext();
|
|
35
|
+
|
|
36
|
+
const { key } = useRoute();
|
|
37
|
+
const _ref = useRef<RNSectionList<any>>(null);
|
|
38
|
+
|
|
39
|
+
const _onLayout = (event: LayoutChangeEvent) => {
|
|
40
|
+
onLayout?.(event);
|
|
41
|
+
innerLayout.value = event.nativeEvent.layout;
|
|
42
|
+
context.screen.setRef(key, _ref.current);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<GestureDetector gesture={gesture}>
|
|
47
|
+
<AnimatedSectionList
|
|
48
|
+
ref={_ref}
|
|
49
|
+
contentContainerStyle={[
|
|
50
|
+
_contentContainerStyle,
|
|
51
|
+
styleSheet.contentContainerStyle,
|
|
52
|
+
contentContainerStyle,
|
|
53
|
+
]}
|
|
54
|
+
onLayout={_onLayout}
|
|
55
|
+
style={[_style, style]}
|
|
56
|
+
onScroll={onScroll}
|
|
57
|
+
bounces={bounces}
|
|
58
|
+
animatedProps={animatedProps}
|
|
59
|
+
overScrollMode={overScrollMode}
|
|
60
|
+
{...props}
|
|
61
|
+
>
|
|
62
|
+
{children}
|
|
63
|
+
</AnimatedSectionList>
|
|
64
|
+
</GestureDetector>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const styleSheet = StyleSheet.create({
|
|
69
|
+
contentContainerStyle: {
|
|
70
|
+
flexGrow: 1,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const AnimatedSectionList =
|
|
75
|
+
Reanimated.createAnimatedComponent<SectionListProps<any, any>>(RNSectionList);
|
|
@@ -15,13 +15,14 @@ import type {
|
|
|
15
15
|
import { Gesture } from 'react-native-gesture-handler';
|
|
16
16
|
import { assign, throttle } from 'lodash';
|
|
17
17
|
import { ContextHelpers } from './Context.helpers';
|
|
18
|
+
import { SectionList } from 'react-native';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Hook to reset the scroll offset for the approaching screen in a tab navigation context.
|
|
21
22
|
*
|
|
22
23
|
* @param {Object} params - The parameters for configuring the scroll offset reset.
|
|
23
24
|
* @param {ReanimatedTopTabNavigation.ContextType["context"]} params.context - The context containing navigation and screen information.
|
|
24
|
-
* @param {ReanimatedTopTabNavigation.ContextType["
|
|
25
|
+
* @param {ReanimatedTopTabNavigation.ContextType["positionX"]} params.positionX - The horizontal transformation value used in animations.
|
|
25
26
|
* @param {ReanimatedTopTabNavigation.ContextType["currentYPosition"]} params.currentYPosition - The current vertical scroll position.
|
|
26
27
|
*
|
|
27
28
|
* The hook is responsible for resetting the vertical scroll offset of the "approaching" screen within a tabbed navigation interface,
|
|
@@ -31,11 +32,11 @@ import { ContextHelpers } from './Context.helpers';
|
|
|
31
32
|
*/
|
|
32
33
|
const useResetApproachingScreenScrollOffset = ({
|
|
33
34
|
context,
|
|
34
|
-
|
|
35
|
+
positionX,
|
|
35
36
|
currentYPosition,
|
|
36
37
|
}: Pick<
|
|
37
38
|
ReanimatedTopTabNavigation.ContextType,
|
|
38
|
-
'context' | 'currentYPosition' | '
|
|
39
|
+
'context' | 'currentYPosition' | 'positionX'
|
|
39
40
|
>) => {
|
|
40
41
|
const screenOffsets = useDerivedValue(() =>
|
|
41
42
|
Object.values(context.screen.properties).map(({ scrollY }) => scrollY.value)
|
|
@@ -46,16 +47,23 @@ const useResetApproachingScreenScrollOffset = ({
|
|
|
46
47
|
shouldReset: boolean
|
|
47
48
|
) => {
|
|
48
49
|
if (shouldReset) {
|
|
49
|
-
const
|
|
50
|
+
const ref = context.screen.getRef(
|
|
50
51
|
context.route.getKeyForIndex(index)
|
|
51
|
-
).current
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
).current;
|
|
53
|
+
|
|
54
|
+
if (ref instanceof SectionList) {
|
|
55
|
+
ref.scrollToLocation({
|
|
56
|
+
animated: false,
|
|
57
|
+
sectionIndex: 0,
|
|
58
|
+
itemIndex: 0,
|
|
59
|
+
viewOffset: 0,
|
|
60
|
+
});
|
|
61
|
+
} else ref?.scrollTo({ y: 0, animated: false });
|
|
54
62
|
}
|
|
55
63
|
};
|
|
56
64
|
|
|
57
65
|
useAnimatedReaction(
|
|
58
|
-
() =>
|
|
66
|
+
() => positionX.value,
|
|
59
67
|
(current, previous) => {
|
|
60
68
|
const approachingIndex = ContextHelpers.getTargetIndex(current, previous);
|
|
61
69
|
|
|
@@ -145,7 +153,7 @@ const usePrepareScreen = ({
|
|
|
145
153
|
)
|
|
146
154
|
);
|
|
147
155
|
|
|
148
|
-
const setRef = (key: string, ref: Reanimated.ScrollView) => {
|
|
156
|
+
const setRef = (key: string, ref: Reanimated.ScrollView | SectionList) => {
|
|
149
157
|
const newProperties = assign({}, screenProperties.current[key], {
|
|
150
158
|
scrollRef: { current: ref },
|
|
151
159
|
});
|
|
@@ -197,7 +205,7 @@ const usePrepareContext = ({
|
|
|
197
205
|
* @param {Array} params.config - An array of configuration settings to determine the header's transformation.
|
|
198
206
|
* @returns {Object} An object containing shared values for header transformations and positioning:
|
|
199
207
|
* - transformationY: The derived Y-axis transformation value for the header.
|
|
200
|
-
* -
|
|
208
|
+
* - positionX: The shared X-axis transformation value to be observed.
|
|
201
209
|
* - currentYPosition: The shared Y-axis position of the header.
|
|
202
210
|
* - headerHeight: The shared height value of the header.
|
|
203
211
|
*/
|
|
@@ -207,7 +215,8 @@ const useTransformHeaderOnTabChange = ({
|
|
|
207
215
|
const headerHeight = useSharedValue(0);
|
|
208
216
|
const isHeaderHeightSet = useSharedValue(false);
|
|
209
217
|
const transformationY = useSharedValue(0);
|
|
210
|
-
const
|
|
218
|
+
const scrollY = useSharedValue(0);
|
|
219
|
+
const positionX = useSharedValue(0);
|
|
211
220
|
const currentYPosition = useSharedValue(0);
|
|
212
221
|
|
|
213
222
|
//Hide header base on config
|
|
@@ -255,7 +264,7 @@ const useTransformHeaderOnTabChange = ({
|
|
|
255
264
|
);
|
|
256
265
|
|
|
257
266
|
useAnimatedReaction(
|
|
258
|
-
() =>
|
|
267
|
+
() => positionX.value,
|
|
259
268
|
(value) => {
|
|
260
269
|
if (currentYPosition.value === -headerHeight.value) return;
|
|
261
270
|
transformationY.value = interpolate(
|
|
@@ -269,21 +278,22 @@ const useTransformHeaderOnTabChange = ({
|
|
|
269
278
|
|
|
270
279
|
return {
|
|
271
280
|
transformationY,
|
|
272
|
-
|
|
281
|
+
positionX,
|
|
273
282
|
currentYPosition,
|
|
274
283
|
headerHeight,
|
|
275
284
|
isHeaderHeightSet,
|
|
285
|
+
scrollY,
|
|
276
286
|
};
|
|
277
287
|
};
|
|
278
288
|
|
|
279
289
|
const useApproachingTabChange = ({
|
|
280
290
|
config,
|
|
281
|
-
|
|
291
|
+
positionX,
|
|
282
292
|
gestureEnabled,
|
|
283
293
|
currentScreenIndex,
|
|
284
294
|
}: Pick<
|
|
285
295
|
ReanimatedTopTabNavigation.ContextType,
|
|
286
|
-
'config' | '
|
|
296
|
+
'config' | 'positionX' | 'currentScreenIndex' | 'gestureEnabled'
|
|
287
297
|
>) => {
|
|
288
298
|
const onIndexApproach = (index: number) => {
|
|
289
299
|
'worklet';
|
|
@@ -301,7 +311,7 @@ const useApproachingTabChange = ({
|
|
|
301
311
|
};
|
|
302
312
|
|
|
303
313
|
useAnimatedReaction(
|
|
304
|
-
() =>
|
|
314
|
+
() => positionX.value,
|
|
305
315
|
(current, previous) => {
|
|
306
316
|
const approachingIndex = ContextHelpers.getTargetIndex(current, previous);
|
|
307
317
|
onIndexApproach(approachingIndex);
|
package/src/context/Context.tsx
CHANGED
|
@@ -24,23 +24,24 @@ export const Provider = memo(
|
|
|
24
24
|
const topTabNativeGesture = useRef(Gesture.Native()).current;
|
|
25
25
|
|
|
26
26
|
const {
|
|
27
|
-
|
|
27
|
+
positionX,
|
|
28
28
|
transformationY,
|
|
29
29
|
currentYPosition,
|
|
30
30
|
headerHeight,
|
|
31
31
|
isHeaderHeightSet,
|
|
32
|
+
scrollY,
|
|
32
33
|
} = ContextHooks.useTransformHeaderOnTabChange({ config });
|
|
33
34
|
|
|
34
35
|
ContextHooks.useResetApproachingScreenScrollOffset({
|
|
35
36
|
currentYPosition,
|
|
36
|
-
|
|
37
|
+
positionX,
|
|
37
38
|
context,
|
|
38
39
|
});
|
|
39
40
|
|
|
40
41
|
ContextHooks.useApproachingTabChange({
|
|
41
42
|
config,
|
|
42
43
|
gestureEnabled,
|
|
43
|
-
|
|
44
|
+
positionX,
|
|
44
45
|
currentScreenIndex,
|
|
45
46
|
});
|
|
46
47
|
|
|
@@ -56,10 +57,11 @@ export const Provider = memo(
|
|
|
56
57
|
navHeight,
|
|
57
58
|
topTabHeight,
|
|
58
59
|
topTabNativeGesture,
|
|
59
|
-
|
|
60
|
+
positionX,
|
|
60
61
|
transformationY,
|
|
61
62
|
context,
|
|
62
63
|
isHeaderHeightSet,
|
|
64
|
+
scrollY,
|
|
63
65
|
}}
|
|
64
66
|
>
|
|
65
67
|
{children({
|
|
@@ -72,10 +74,11 @@ export const Provider = memo(
|
|
|
72
74
|
navHeight,
|
|
73
75
|
topTabHeight,
|
|
74
76
|
topTabNativeGesture,
|
|
75
|
-
|
|
77
|
+
positionX,
|
|
76
78
|
transformationY,
|
|
77
79
|
context,
|
|
78
80
|
isHeaderHeightSet,
|
|
81
|
+
scrollY,
|
|
79
82
|
})}
|
|
80
83
|
</Context.Provider>
|
|
81
84
|
);
|
package/src/hooks/useHeader.ts
CHANGED
|
@@ -1,30 +1,12 @@
|
|
|
1
1
|
import { useTabContext } from './useTabContext';
|
|
2
|
-
import {
|
|
3
|
-
interpolate,
|
|
4
|
-
useAnimatedStyle,
|
|
5
|
-
withTiming,
|
|
6
|
-
} from 'react-native-reanimated';
|
|
2
|
+
import { withTiming } from 'react-native-reanimated';
|
|
7
3
|
|
|
8
4
|
export const useHeader = () => {
|
|
9
|
-
const { headerHeight,
|
|
5
|
+
const { headerHeight, transformationY } = useTabContext();
|
|
10
6
|
|
|
11
7
|
const hideHeader = () => {
|
|
12
|
-
|
|
8
|
+
transformationY.value = withTiming(-headerHeight.value);
|
|
13
9
|
};
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
transform: [
|
|
17
|
-
{
|
|
18
|
-
translateY: interpolate(
|
|
19
|
-
transformationY.value,
|
|
20
|
-
[0, -headerHeight.value],
|
|
21
|
-
[0, -headerHeight.value],
|
|
22
|
-
'clamp'
|
|
23
|
-
),
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
zIndex: -1,
|
|
27
|
-
}));
|
|
28
|
-
|
|
29
|
-
return { hideHeader, defaultStyle };
|
|
11
|
+
return { hideHeader };
|
|
30
12
|
};
|
|
@@ -3,6 +3,6 @@ import { useTabContext } from './useTabContext';
|
|
|
3
3
|
import { useDerivedValue } from 'react-native-reanimated';
|
|
4
4
|
|
|
5
5
|
export const useTabOffset = () => {
|
|
6
|
-
const {
|
|
7
|
-
return useDerivedValue(() =>
|
|
6
|
+
const { positionX } = useTabContext();
|
|
7
|
+
return useDerivedValue(() => positionX.value);
|
|
8
8
|
};
|
package/src/index.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ScrollView } from './components/wrappers/ScrollView';
|
|
2
|
+
import { SectionList } from './components/wrappers/SectionList';
|
|
2
3
|
import { ScreenWrapper } from './components/wrappers/ScreenWrapper';
|
|
3
4
|
import { TabBarBaseComponent } from './components/elements/TabBarBaseComponent';
|
|
4
5
|
import { TabBarLabelBaseComponent } from './components/elements/TabBarLabelBaseComponent';
|
|
@@ -33,6 +34,7 @@ export const TabHooks = {
|
|
|
33
34
|
|
|
34
35
|
export const Tab = {
|
|
35
36
|
ScrollView,
|
|
37
|
+
SectionList,
|
|
36
38
|
ScreenWrapper,
|
|
37
39
|
TabBarBaseComponent,
|
|
38
40
|
TabBarLabelBaseComponent,
|
|
@@ -20,11 +20,13 @@ import { ContextHooks } from '../context/Context.hooks';
|
|
|
20
20
|
|
|
21
21
|
const TabViewNavigator = ({
|
|
22
22
|
HeaderComponent,
|
|
23
|
+
TopComponent,
|
|
23
24
|
TabBarComponent = TabBarBaseComponent,
|
|
24
25
|
children,
|
|
25
26
|
config,
|
|
26
27
|
initialRouteName,
|
|
27
28
|
screenOptions = {},
|
|
29
|
+
bounces,
|
|
28
30
|
}: ReanimatedTopTabNavigation.TabViewNavigatorProps) => {
|
|
29
31
|
const { NavigationContent, descriptors, navigation, state } =
|
|
30
32
|
useNavigationBuilder<
|
|
@@ -62,10 +64,11 @@ const TabViewNavigator = ({
|
|
|
62
64
|
descriptors[route.key]?.options,
|
|
63
65
|
'tabBarLabel'
|
|
64
66
|
);
|
|
67
|
+
|
|
65
68
|
const tabBarLabel = descriptors[route.key]?.options.tabBarLabel
|
|
66
|
-
? () =>
|
|
69
|
+
? (focused: boolean) =>
|
|
67
70
|
descriptors[route.key]?.options.tabBarLabel?.({
|
|
68
|
-
focused
|
|
71
|
+
focused,
|
|
69
72
|
title: descriptors[route.key]?.options.title || route.name,
|
|
70
73
|
index,
|
|
71
74
|
})
|
|
@@ -88,30 +91,32 @@ const TabViewNavigator = ({
|
|
|
88
91
|
return (
|
|
89
92
|
<Provider config={_config} context={context}>
|
|
90
93
|
{({ headerHeight, transformationY }) => (
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
94
|
+
<NavigationContent>
|
|
95
|
+
{TopComponent ? (
|
|
96
|
+
<TopComponent transformationY={transformationY} />
|
|
97
|
+
) : null}
|
|
98
|
+
<GestureWrapper bounces={bounces}>
|
|
99
|
+
<Reanimated.View
|
|
100
|
+
onLayout={({ nativeEvent }) => {
|
|
101
|
+
headerHeight.value = nativeEvent.layout.height;
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
{HeaderComponent ? (
|
|
105
|
+
<HeaderComponent
|
|
106
|
+
headerHeight={headerHeight}
|
|
107
|
+
transformationY={transformationY}
|
|
108
|
+
/>
|
|
109
|
+
) : null}
|
|
110
|
+
</Reanimated.View>
|
|
111
|
+
<ReanimatedTabView
|
|
112
|
+
navigationState={navigationState}
|
|
113
|
+
navigate={navigate}
|
|
114
|
+
renderScene={renderScene}
|
|
115
|
+
renderTabBar={TabBarComponent}
|
|
116
|
+
screenOptions={screenOptions}
|
|
117
|
+
/>
|
|
118
|
+
</GestureWrapper>
|
|
119
|
+
</NavigationContent>
|
|
115
120
|
)}
|
|
116
121
|
</Provider>
|
|
117
122
|
);
|
package/src/types.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { TabBarBaseComponent } from './components/elements/TabBarBaseComponent';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { type ReactNode } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
SectionList,
|
|
6
|
+
type LayoutRectangle,
|
|
7
|
+
type StyleProp,
|
|
8
|
+
type ViewStyle,
|
|
9
|
+
} from 'react-native';
|
|
5
10
|
import { type NativeGesture } from 'react-native-gesture-handler';
|
|
6
11
|
import Reanimated, { type SharedValue } from 'react-native-reanimated';
|
|
7
12
|
import { type StackNavigationOptions } from '@react-navigation/stack';
|
|
@@ -18,8 +23,9 @@ export namespace ReanimatedTopTabNavigation {
|
|
|
18
23
|
navHeight: SharedValue<number>;
|
|
19
24
|
topTabHeight: SharedValue<number>;
|
|
20
25
|
topTabNativeGesture: NativeGesture;
|
|
21
|
-
|
|
26
|
+
positionX: SharedValue<number>;
|
|
22
27
|
transformationY: SharedValue<number>;
|
|
28
|
+
scrollY: SharedValue<number>;
|
|
23
29
|
context: {
|
|
24
30
|
screen: {
|
|
25
31
|
properties: Record<
|
|
@@ -29,11 +35,16 @@ export namespace ReanimatedTopTabNavigation {
|
|
|
29
35
|
nativeGesture: NativeGesture;
|
|
30
36
|
outerLayout: SharedValue<LayoutRectangle>;
|
|
31
37
|
scrollY: SharedValue<number>;
|
|
32
|
-
scrollRef: { current: Reanimated.ScrollView | null };
|
|
38
|
+
scrollRef: { current: Reanimated.ScrollView | SectionList | null };
|
|
33
39
|
}
|
|
34
40
|
>;
|
|
35
|
-
setRef(
|
|
36
|
-
|
|
41
|
+
setRef(
|
|
42
|
+
key: string,
|
|
43
|
+
ref: Reanimated.ScrollView | SectionList | null
|
|
44
|
+
): void;
|
|
45
|
+
getRef(key: string): {
|
|
46
|
+
current: Reanimated.ScrollView | SectionList | null;
|
|
47
|
+
};
|
|
37
48
|
};
|
|
38
49
|
route: {
|
|
39
50
|
map: Record<number, string>;
|
|
@@ -46,11 +57,13 @@ export namespace ReanimatedTopTabNavigation {
|
|
|
46
57
|
HeaderComponent?: React.ComponentType<
|
|
47
58
|
Pick<ContextType, 'transformationY' | 'headerHeight'>
|
|
48
59
|
>;
|
|
60
|
+
TopComponent?: React.ComponentType<Pick<ContextType, 'transformationY'>>;
|
|
49
61
|
TabBarComponent?: typeof TabBarBaseComponent;
|
|
50
62
|
children: ReactNode;
|
|
51
63
|
config?: string[];
|
|
52
64
|
initialRouteName?: string;
|
|
53
65
|
screenOptions?: StackNavigationOptions;
|
|
66
|
+
bounces?: boolean;
|
|
54
67
|
}
|
|
55
68
|
|
|
56
69
|
export type TopTabContextProps = Pick<ContextType, 'config' | 'context'> & {
|
|
@@ -64,5 +77,8 @@ export namespace ReanimatedTopTabNavigation {
|
|
|
64
77
|
title: string;
|
|
65
78
|
}) => React.ReactNode;
|
|
66
79
|
title?: string;
|
|
80
|
+
tabBarIndicatorStyle?: StyleProp<ViewStyle>;
|
|
81
|
+
tabBarItemStyle?: StyleProp<ViewStyle>;
|
|
82
|
+
tabBarStyle?: StyleProp<ViewStyle>;
|
|
67
83
|
}
|
|
68
84
|
}
|