react-navigation-reanimated-top-tabs 0.6.2 → 0.8.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 (90) hide show
  1. package/lib/commonjs/components/ReanimatedTopTab/AnimationHelper.js +1 -1
  2. package/lib/commonjs/components/ReanimatedTopTab/AnimationHelper.js.map +1 -1
  3. package/lib/commonjs/components/ReanimatedTopTab/ReanimatedTabView.js +4 -2
  4. package/lib/commonjs/components/ReanimatedTopTab/ReanimatedTabView.js.map +1 -1
  5. package/lib/commonjs/components/ReanimatedTopTab/types.js.map +1 -1
  6. package/lib/commonjs/components/elements/TabBarBaseComponent.js +42 -17
  7. package/lib/commonjs/components/elements/TabBarBaseComponent.js.map +1 -1
  8. package/lib/commonjs/components/elements/TabBarBaseItem.js +52 -0
  9. package/lib/commonjs/components/elements/TabBarBaseItem.js.map +1 -0
  10. package/lib/commonjs/components/wrappers/GestureWrapper.js +14 -4
  11. package/lib/commonjs/components/wrappers/GestureWrapper.js.map +1 -1
  12. package/lib/commonjs/components/wrappers/SectionList.js +72 -0
  13. package/lib/commonjs/components/wrappers/SectionList.js.map +1 -0
  14. package/lib/commonjs/context/Context.hooks.js +10 -7
  15. package/lib/commonjs/context/Context.hooks.js.map +1 -1
  16. package/lib/commonjs/hooks/useHeader.js +2 -10
  17. package/lib/commonjs/hooks/useHeader.js.map +1 -1
  18. package/lib/commonjs/hooks/useScreenDimensions.js +23 -0
  19. package/lib/commonjs/hooks/useScreenDimensions.js.map +1 -0
  20. package/lib/commonjs/hooks/useScreenScrollable.js +2 -2
  21. package/lib/commonjs/hooks/useScreenScrollable.js.map +1 -1
  22. package/lib/commonjs/index.js +2 -0
  23. package/lib/commonjs/index.js.map +1 -1
  24. package/lib/commonjs/navigator/createReanimatedTopTabNavigator.js +24 -22
  25. package/lib/commonjs/navigator/createReanimatedTopTabNavigator.js.map +1 -1
  26. package/lib/commonjs/types.js.map +1 -1
  27. package/lib/module/components/ReanimatedTopTab/AnimationHelper.js +3 -3
  28. package/lib/module/components/ReanimatedTopTab/AnimationHelper.js.map +1 -1
  29. package/lib/module/components/ReanimatedTopTab/ReanimatedTabView.js +4 -2
  30. package/lib/module/components/ReanimatedTopTab/ReanimatedTabView.js.map +1 -1
  31. package/lib/module/components/ReanimatedTopTab/types.js.map +1 -1
  32. package/lib/module/components/elements/TabBarBaseComponent.js +44 -19
  33. package/lib/module/components/elements/TabBarBaseComponent.js.map +1 -1
  34. package/lib/module/components/elements/TabBarBaseItem.js +45 -0
  35. package/lib/module/components/elements/TabBarBaseItem.js.map +1 -0
  36. package/lib/module/components/wrappers/GestureWrapper.js +14 -4
  37. package/lib/module/components/wrappers/GestureWrapper.js.map +1 -1
  38. package/lib/module/components/wrappers/SectionList.js +66 -0
  39. package/lib/module/components/wrappers/SectionList.js.map +1 -0
  40. package/lib/module/context/Context.hooks.js +10 -7
  41. package/lib/module/context/Context.hooks.js.map +1 -1
  42. package/lib/module/hooks/useHeader.js +3 -11
  43. package/lib/module/hooks/useHeader.js.map +1 -1
  44. package/lib/module/hooks/useScreenDimensions.js +18 -0
  45. package/lib/module/hooks/useScreenDimensions.js.map +1 -0
  46. package/lib/module/hooks/useScreenScrollable.js +2 -2
  47. package/lib/module/hooks/useScreenScrollable.js.map +1 -1
  48. package/lib/module/index.js +2 -0
  49. package/lib/module/index.js.map +1 -1
  50. package/lib/module/navigator/createReanimatedTopTabNavigator.js +25 -23
  51. package/lib/module/navigator/createReanimatedTopTabNavigator.js.map +1 -1
  52. package/lib/module/types.js.map +1 -1
  53. package/lib/typescript/src/components/ReanimatedTopTab/ReanimatedTabView.d.ts +2 -0
  54. package/lib/typescript/src/components/ReanimatedTopTab/ReanimatedTabView.d.ts.map +1 -1
  55. package/lib/typescript/src/components/ReanimatedTopTab/types.d.ts +3 -1
  56. package/lib/typescript/src/components/ReanimatedTopTab/types.d.ts.map +1 -1
  57. package/lib/typescript/src/components/elements/TabBarBaseComponent.d.ts +1 -1
  58. package/lib/typescript/src/components/elements/TabBarBaseComponent.d.ts.map +1 -1
  59. package/lib/typescript/src/components/elements/TabBarBaseItem.d.ts +14 -0
  60. package/lib/typescript/src/components/elements/TabBarBaseItem.d.ts.map +1 -0
  61. package/lib/typescript/src/components/wrappers/GestureWrapper.d.ts.map +1 -1
  62. package/lib/typescript/src/components/wrappers/SectionList.d.ts +3 -0
  63. package/lib/typescript/src/components/wrappers/SectionList.d.ts.map +1 -0
  64. package/lib/typescript/src/context/Context.hooks.d.ts.map +1 -1
  65. package/lib/typescript/src/hooks/useHeader.d.ts +0 -6
  66. package/lib/typescript/src/hooks/useHeader.d.ts.map +1 -1
  67. package/lib/typescript/src/hooks/useScreenDimensions.d.ts +2 -0
  68. package/lib/typescript/src/hooks/useScreenDimensions.d.ts.map +1 -0
  69. package/lib/typescript/src/hooks/useScreenProperties.d.ts +1 -1
  70. package/lib/typescript/src/index.d.ts +3 -8
  71. package/lib/typescript/src/index.d.ts.map +1 -1
  72. package/lib/typescript/src/navigator/createReanimatedTopTabNavigator.d.ts +1 -1
  73. package/lib/typescript/src/navigator/createReanimatedTopTabNavigator.d.ts.map +1 -1
  74. package/lib/typescript/src/types.d.ts +8 -4
  75. package/lib/typescript/src/types.d.ts.map +1 -1
  76. package/package.json +1 -1
  77. package/src/components/ReanimatedTopTab/AnimationHelper.ts +3 -3
  78. package/src/components/ReanimatedTopTab/ReanimatedTabView.tsx +4 -0
  79. package/src/components/ReanimatedTopTab/types.ts +3 -1
  80. package/src/components/elements/TabBarBaseComponent.tsx +53 -19
  81. package/src/components/elements/TabBarBaseItem.tsx +76 -0
  82. package/src/components/wrappers/GestureWrapper.tsx +12 -2
  83. package/src/components/wrappers/SectionList.tsx +75 -0
  84. package/src/context/Context.hooks.ts +13 -5
  85. package/src/hooks/useHeader.ts +3 -21
  86. package/src/hooks/useScreenDimensions.ts +17 -0
  87. package/src/hooks/useScreenScrollable.ts +2 -2
  88. package/src/index.tsx +2 -0
  89. package/src/navigator/createReanimatedTopTabNavigator.tsx +30 -26
  90. package/src/types.ts +18 -4
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
2
  import type { SharedValue } from 'react-native-reanimated';
3
+ import type { ReanimatedTopTabNavigation } from 'react-navigation-reanimated-top-tabs';
3
4
 
4
5
  export namespace ReanimatedTabViewTypes {
5
6
  export interface Route {
6
7
  key: string;
7
8
  name: string;
8
- tabBarLabel?: () => React.ReactNode;
9
+ tabBarLabel?: (focused: boolean) => React.ReactNode;
9
10
  title?: string;
10
11
  }
11
12
 
@@ -15,6 +16,7 @@ export namespace ReanimatedTabViewTypes {
15
16
  navigationState: NavigationState;
16
17
  position: SharedValue<number>;
17
18
  navigate(index: number): void;
19
+ screenOptions?: ReanimatedTopTabNavigation.NavigationOptions;
18
20
  }
19
21
 
20
22
  export interface SceneProps {
@@ -1,13 +1,16 @@
1
1
  import * as React from 'react';
2
- import { Pressable, StyleSheet, Text, useWindowDimensions } from 'react-native';
2
+ import { StyleSheet, useWindowDimensions } from 'react-native';
3
3
  import Reanimated, {
4
- type AnimatedStyle,
5
4
  interpolate,
6
5
  useAnimatedReaction,
6
+ useAnimatedStyle,
7
+ useSharedValue,
8
+ type AnimatedStyle,
7
9
  } from 'react-native-reanimated';
8
10
 
9
11
  import { useTabContext } from '../../hooks/useTabContext';
10
12
  import { type ReanimatedTabViewTypes } from '../ReanimatedTopTab/types';
13
+ import { TabBarBaseItem } from './TabBarBaseItem';
11
14
 
12
15
  export interface TabBarProps extends ReanimatedTabViewTypes.RenderTabsParams {
13
16
  children?: React.ReactNode;
@@ -20,10 +23,35 @@ export const TabBarBaseComponent = ({
20
23
  position,
21
24
  style,
22
25
  navigate,
26
+ screenOptions,
23
27
  }: TabBarProps) => {
24
28
  const layout = useWindowDimensions();
25
-
26
29
  const { topTabHeight, transformationX } = useTabContext();
30
+ const width = useSharedValue(0);
31
+
32
+ const { tabBarIndicatorStyle, tabBarItemStyle, tabBarStyle } =
33
+ screenOptions ?? {};
34
+
35
+ const inputRange = navigationState.routes.map((_, index) => index);
36
+
37
+ const indicatorStyle = useAnimatedStyle(() => {
38
+ const outputRange = navigationState.routes.map(
39
+ (_, index) => index * (width.value / navigationState.routes.length)
40
+ );
41
+
42
+ return {
43
+ transform: [
44
+ {
45
+ translateX: interpolate(
46
+ transformationX.value,
47
+ inputRange,
48
+ outputRange
49
+ ),
50
+ },
51
+ ],
52
+ width: width.value / navigationState.routes.length,
53
+ };
54
+ });
27
55
 
28
56
  //Assign interpolated offsetX to transformationX
29
57
  useAnimatedReaction(
@@ -46,21 +74,27 @@ export const TabBarBaseComponent = ({
46
74
  topTabHeight.value = nativeEvent.layout.height;
47
75
  }}
48
76
  >
49
- <Reanimated.View style={[styles.wrapper, style]}>
77
+ <Reanimated.View
78
+ onLayout={({ nativeEvent }) => {
79
+ width.value = nativeEvent.layout.width;
80
+ }}
81
+ style={[styles.wrapper, tabBarStyle, style]}
82
+ >
83
+ <Reanimated.View
84
+ style={[styles.indicator, indicatorStyle, tabBarIndicatorStyle]}
85
+ />
50
86
  {navigationState.routes.map((route, index) => (
51
- <Pressable
52
- style={styles.labelWrapper}
87
+ <TabBarBaseItem
88
+ index={index}
89
+ inputRange={inputRange}
90
+ position={transformationX}
53
91
  key={route.key}
54
92
  onPress={() => {
55
93
  navigate(index);
56
94
  }}
57
- >
58
- {route.tabBarLabel ? (
59
- route.tabBarLabel()
60
- ) : (
61
- <Text style={styles.label}>{route.title}</Text>
62
- )}
63
- </Pressable>
95
+ route={route}
96
+ style={tabBarItemStyle}
97
+ />
64
98
  ))}
65
99
  </Reanimated.View>
66
100
  {children}
@@ -75,14 +109,14 @@ const styles = StyleSheet.create({
75
109
  alignItems: 'center',
76
110
  justifyContent: 'center',
77
111
  },
78
- label: {
79
- color: 'red',
80
- },
81
112
  wrapper: {
82
- width: '100%',
83
113
  flexDirection: 'row',
84
114
  backgroundColor: 'white',
85
- paddingVertical: 8,
86
- height: 50,
115
+ },
116
+ indicator: {
117
+ backgroundColor: 'black',
118
+ bottom: 0,
119
+ height: 2,
120
+ position: 'absolute',
87
121
  },
88
122
  });
@@ -0,0 +1,76 @@
1
+ import {
2
+ Pressable,
3
+ StyleSheet,
4
+ Text,
5
+ type StyleProp,
6
+ type ViewStyle,
7
+ } from 'react-native';
8
+ import Animated, {
9
+ type SharedValue,
10
+ useAnimatedStyle,
11
+ interpolate,
12
+ } from 'react-native-reanimated';
13
+ import { type ReanimatedTabViewTypes } from '../ReanimatedTopTab/types';
14
+
15
+ interface TabBarBaseItemProps {
16
+ position: SharedValue<number>;
17
+ index: number;
18
+ inputRange: Array<number>;
19
+ onPress: (index: number) => void;
20
+ route: ReanimatedTabViewTypes.Route;
21
+ style?: StyleProp<ViewStyle>;
22
+ }
23
+
24
+ export const TabBarBaseItem = ({
25
+ position,
26
+ index,
27
+ inputRange,
28
+ onPress,
29
+ route,
30
+ style,
31
+ }: TabBarBaseItemProps) => {
32
+ const activeStyle = useAnimatedStyle(() => ({
33
+ opacity: interpolate(
34
+ position.value,
35
+ inputRange,
36
+ inputRange.map((i) => (i === index ? 1 : 0))
37
+ ),
38
+ position: 'absolute',
39
+ }));
40
+
41
+ const inactiveStyle = useAnimatedStyle(() => ({
42
+ opacity: interpolate(
43
+ position.value,
44
+ inputRange,
45
+ inputRange.map((i) => (i === index ? 0 : 1))
46
+ ),
47
+ }));
48
+
49
+ return (
50
+ <Pressable onPress={() => onPress(index)} style={[styles.container, style]}>
51
+ <Animated.View style={activeStyle}>
52
+ {route.tabBarLabel ? (
53
+ route.tabBarLabel(true)
54
+ ) : (
55
+ <Text>{route.title}</Text>
56
+ )}
57
+ </Animated.View>
58
+ <Animated.View style={inactiveStyle}>
59
+ {route.tabBarLabel ? (
60
+ route.tabBarLabel(false)
61
+ ) : (
62
+ <Text>{route.title}</Text>
63
+ )}
64
+ </Animated.View>
65
+ </Pressable>
66
+ );
67
+ };
68
+
69
+ const styles = StyleSheet.create({
70
+ container: {
71
+ alignItems: 'center',
72
+ flex: 1,
73
+ justifyContent: 'center',
74
+ minHeight: 50,
75
+ },
76
+ });
@@ -12,6 +12,7 @@ import Reanimated, {
12
12
  } from 'react-native-reanimated';
13
13
 
14
14
  import { useTabContext } from '../../hooks/useTabContext';
15
+ import { StyleSheet, View } from 'react-native';
15
16
 
16
17
  interface GestureWrapperProps {
17
18
  children: React.ReactNode;
@@ -43,7 +44,7 @@ export const GestureWrapper = ({ children }: GestureWrapperProps) => {
43
44
  easing: Easing.bezier(0.25, 0.1, 0.25, 1),
44
45
  } as const;
45
46
 
46
- const [_gestureEnabled, setGestureEnabled] = useState(gestureEnabled.value);
47
+ const [_gestureEnabled, setGestureEnabled] = useState(true);
47
48
 
48
49
  useAnimatedReaction(
49
50
  () => gestureEnabled.value,
@@ -124,7 +125,16 @@ export const GestureWrapper = ({ children }: GestureWrapperProps) => {
124
125
 
125
126
  return (
126
127
  <GestureDetector gesture={gesture}>
127
- <Reanimated.View style={style}>{children}</Reanimated.View>
128
+ <View style={styles.container}>
129
+ <Reanimated.View style={style}>{children}</Reanimated.View>
130
+ </View>
128
131
  </GestureDetector>
129
132
  );
130
133
  };
134
+
135
+ const styles = StyleSheet.create({
136
+ container: {
137
+ overflow: 'hidden',
138
+ flex: 1,
139
+ },
140
+ });
@@ -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,6 +15,7 @@ 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.
@@ -46,11 +47,18 @@ const useResetApproachingScreenScrollOffset = ({
46
47
  shouldReset: boolean
47
48
  ) => {
48
49
  if (shouldReset) {
49
- const { scrollTo } = context.screen.getRef(
50
+ const ref = context.screen.getRef(
50
51
  context.route.getKeyForIndex(index)
51
- ).current ?? { scrollTo: () => {} };
52
- //NOTE: use reanimated scrollTo does not work
53
- scrollTo({ y: 0, animated: false });
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
 
@@ -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
  });
@@ -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, transformationX, transformationY } = useTabContext();
5
+ const { headerHeight, transformationX } = useTabContext();
10
6
 
11
7
  const hideHeader = () => {
12
8
  transformationX.value = withTiming(-headerHeight.value);
13
9
  };
14
10
 
15
- const defaultStyle = useAnimatedStyle(() => ({
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
  };
@@ -0,0 +1,17 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { Dimensions } from 'react-native';
3
+
4
+ const screenDimensions = Dimensions.get('screen');
5
+
6
+ export const useScreenDimensions = () => {
7
+ const [dimensions, setDimensions] = useState(screenDimensions);
8
+
9
+ useEffect(() => {
10
+ const subscription = Dimensions.addEventListener('change', ({ screen }) => {
11
+ setDimensions(screen);
12
+ });
13
+ return () => subscription?.remove();
14
+ });
15
+
16
+ return dimensions;
17
+ };
@@ -1,5 +1,4 @@
1
1
  import { useRoute } from '@react-navigation/native';
2
- import { useWindowDimensions } from 'react-native';
3
2
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
3
  import { useTabContext } from './useTabContext';
5
4
  import * as React from 'react';
@@ -13,10 +12,11 @@ import {
13
12
  } from 'react-native-reanimated';
14
13
 
15
14
  import { useScreenProperties } from './useScreenProperties';
15
+ import { useScreenDimensions } from './useScreenDimensions';
16
16
 
17
17
  export const useScreenScrollable = () => {
18
18
  const { key } = useRoute();
19
- const { height } = useWindowDimensions();
19
+ const { height } = useScreenDimensions();
20
20
  const { bottom, top } = useSafeAreaInsets();
21
21
  const {
22
22
  currentYPosition,
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,6 +20,7 @@ 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,
@@ -62,10 +63,11 @@ const TabViewNavigator = ({
62
63
  descriptors[route.key]?.options,
63
64
  'tabBarLabel'
64
65
  );
66
+
65
67
  const tabBarLabel = descriptors[route.key]?.options.tabBarLabel
66
- ? () =>
68
+ ? (focused: boolean) =>
67
69
  descriptors[route.key]?.options.tabBarLabel?.({
68
- focused: state.index === index,
70
+ focused,
69
71
  title: descriptors[route.key]?.options.title || route.name,
70
72
  index,
71
73
  })
@@ -88,30 +90,32 @@ const TabViewNavigator = ({
88
90
  return (
89
91
  <Provider config={_config} context={context}>
90
92
  {({ headerHeight, transformationY }) => (
91
- <>
92
- <Reanimated.View
93
- onLayout={({ nativeEvent }) => {
94
- headerHeight.value = nativeEvent.layout.height;
95
- }}
96
- >
97
- {HeaderComponent ? (
98
- <HeaderComponent
99
- headerHeight={headerHeight}
100
- transformationY={transformationY}
101
- />
102
- ) : null}
103
- </Reanimated.View>
104
- <NavigationContent>
105
- <GestureWrapper>
106
- <ReanimatedTabView
107
- navigationState={navigationState}
108
- navigate={navigate}
109
- renderScene={renderScene}
110
- renderTabBar={TabBarComponent}
111
- />
112
- </GestureWrapper>
113
- </NavigationContent>
114
- </>
93
+ <NavigationContent>
94
+ {TopComponent ? (
95
+ <TopComponent transformationY={transformationY} />
96
+ ) : null}
97
+ <GestureWrapper>
98
+ <Reanimated.View
99
+ onLayout={({ nativeEvent }) => {
100
+ headerHeight.value = nativeEvent.layout.height;
101
+ }}
102
+ >
103
+ {HeaderComponent ? (
104
+ <HeaderComponent
105
+ headerHeight={headerHeight}
106
+ transformationY={transformationY}
107
+ />
108
+ ) : null}
109
+ </Reanimated.View>
110
+ <ReanimatedTabView
111
+ navigationState={navigationState}
112
+ navigate={navigate}
113
+ renderScene={renderScene}
114
+ renderTabBar={TabBarComponent}
115
+ screenOptions={screenOptions}
116
+ />
117
+ </GestureWrapper>
118
+ </NavigationContent>
115
119
  )}
116
120
  </Provider>
117
121
  );
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 { type LayoutRectangle } from 'react-native';
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';
@@ -29,11 +34,16 @@ export namespace ReanimatedTopTabNavigation {
29
34
  nativeGesture: NativeGesture;
30
35
  outerLayout: SharedValue<LayoutRectangle>;
31
36
  scrollY: SharedValue<number>;
32
- scrollRef: { current: Reanimated.ScrollView | null };
37
+ scrollRef: { current: Reanimated.ScrollView | SectionList | null };
33
38
  }
34
39
  >;
35
- setRef(key: string, ref: Reanimated.ScrollView | null): void;
36
- getRef(key: string): { current: Reanimated.ScrollView | null };
40
+ setRef(
41
+ key: string,
42
+ ref: Reanimated.ScrollView | SectionList | null
43
+ ): void;
44
+ getRef(key: string): {
45
+ current: Reanimated.ScrollView | SectionList | null;
46
+ };
37
47
  };
38
48
  route: {
39
49
  map: Record<number, string>;
@@ -46,6 +56,7 @@ export namespace ReanimatedTopTabNavigation {
46
56
  HeaderComponent?: React.ComponentType<
47
57
  Pick<ContextType, 'transformationY' | 'headerHeight'>
48
58
  >;
59
+ TopComponent?: React.ComponentType<Pick<ContextType, 'transformationY'>>;
49
60
  TabBarComponent?: typeof TabBarBaseComponent;
50
61
  children: ReactNode;
51
62
  config?: string[];
@@ -64,5 +75,8 @@ export namespace ReanimatedTopTabNavigation {
64
75
  title: string;
65
76
  }) => React.ReactNode;
66
77
  title?: string;
78
+ tabBarIndicatorStyle?: StyleProp<ViewStyle>;
79
+ tabBarItemStyle?: StyleProp<ViewStyle>;
80
+ tabBarStyle?: StyleProp<ViewStyle>;
67
81
  }
68
82
  }