From f89c484b54ab3ab3f860a8b1d1bfbedf847e3d87 Mon Sep 17 00:00:00 2001 From: Vibhor Verma Date: Fri, 1 Mar 2024 21:11:50 +0530 Subject: [PATCH 1/4] feat: added support for switch native driver usage in react native tab view --- .../src/navigators/createMaterialTopTabNavigator.tsx | 2 ++ packages/material-top-tabs/src/views/MaterialTopTabBar.tsx | 2 ++ packages/material-top-tabs/src/views/MaterialTopTabView.tsx | 3 +++ packages/react-native-tab-view/src/PagerViewAdapter.tsx | 5 ++++- packages/react-native-tab-view/src/PanResponderAdapter.tsx | 5 ++++- packages/react-native-tab-view/src/TabBar.tsx | 6 ++++-- packages/react-native-tab-view/src/TabBarIndicator.tsx | 5 +++-- packages/react-native-tab-view/src/TabView.tsx | 4 ++++ packages/react-native-tab-view/src/types.tsx | 2 ++ 9 files changed, 28 insertions(+), 6 deletions(-) diff --git a/packages/material-top-tabs/src/navigators/createMaterialTopTabNavigator.tsx b/packages/material-top-tabs/src/navigators/createMaterialTopTabNavigator.tsx index 0be5b5ed1c..dc2f223af9 100644 --- a/packages/material-top-tabs/src/navigators/createMaterialTopTabNavigator.tsx +++ b/packages/material-top-tabs/src/navigators/createMaterialTopTabNavigator.tsx @@ -35,6 +35,7 @@ function MaterialTopTabNavigator({ screenListeners, screenOptions, screenLayout, + useNativeDriver = true, ...rest }: Props) { const { state, descriptors, navigation, NavigationContent } = @@ -62,6 +63,7 @@ function MaterialTopTabNavigator({ state={state} navigation={navigation} descriptors={descriptors} + useNativeDriver={useNativeDriver} /> ); diff --git a/packages/material-top-tabs/src/views/MaterialTopTabBar.tsx b/packages/material-top-tabs/src/views/MaterialTopTabBar.tsx index e0110e2ca4..a01708fb23 100644 --- a/packages/material-top-tabs/src/views/MaterialTopTabBar.tsx +++ b/packages/material-top-tabs/src/views/MaterialTopTabBar.tsx @@ -17,6 +17,7 @@ export function MaterialTopTabBar({ state, navigation, descriptors, + useNativeDriver = true, ...rest }: MaterialTopTabBarProps) { const { colors } = useTheme(); @@ -38,6 +39,7 @@ export function MaterialTopTabBar({ bounces={focusedOptions.tabBarBounces} activeColor={activeColor} inactiveColor={inactiveColor} + useNativeDriver={useNativeDriver} pressColor={focusedOptions.tabBarPressColor} pressOpacity={focusedOptions.tabBarPressOpacity} tabStyle={focusedOptions.tabBarItemStyle} diff --git a/packages/material-top-tabs/src/views/MaterialTopTabView.tsx b/packages/material-top-tabs/src/views/MaterialTopTabView.tsx index 120c39f8cf..806f4b6b1d 100644 --- a/packages/material-top-tabs/src/views/MaterialTopTabView.tsx +++ b/packages/material-top-tabs/src/views/MaterialTopTabView.tsx @@ -30,6 +30,7 @@ export function MaterialTopTabView({ navigation, descriptors, sceneContainerStyle, + useNativeDriver = true, ...rest }: Props) { const { colors } = useTheme(); @@ -41,6 +42,7 @@ export function MaterialTopTabView({ state: state, navigation: navigation, descriptors: descriptors, + useNativeDriver: useNativeDriver, }); }; @@ -64,6 +66,7 @@ export function MaterialTopTabView({ )} navigationState={state} renderTabBar={renderTabBar} + useNativeDriver={useNativeDriver} renderLazyPlaceholder={({ route }) => descriptors[route.key].options.lazyPlaceholder?.() ?? null } diff --git a/packages/react-native-tab-view/src/PagerViewAdapter.tsx b/packages/react-native-tab-view/src/PagerViewAdapter.tsx index ef98a9c172..afc89ccb22 100644 --- a/packages/react-native-tab-view/src/PagerViewAdapter.tsx +++ b/packages/react-native-tab-view/src/PagerViewAdapter.tsx @@ -43,8 +43,11 @@ export function PagerViewAdapter({ children, style, animationEnabled, + useNativeDriver = true, ...rest }: Props) { + console.log('Pager VAdapter Mounted', useNativeDriver); + const { index } = navigationState; const listenersRef = React.useRef([]); @@ -157,7 +160,7 @@ export function PagerViewAdapter({ }, }, ], - { useNativeDriver: true } + { useNativeDriver: useNativeDriver } )} onPageSelected={(e) => { const index = e.nativeEvent.position; diff --git a/packages/react-native-tab-view/src/PanResponderAdapter.tsx b/packages/react-native-tab-view/src/PanResponderAdapter.tsx index 494c982a05..c99c0082a8 100644 --- a/packages/react-native-tab-view/src/PanResponderAdapter.tsx +++ b/packages/react-native-tab-view/src/PanResponderAdapter.tsx @@ -60,7 +60,10 @@ export function PanResponderAdapter({ style, animationEnabled = false, layoutDirection = 'ltr', + useNativeDriver = true, }: Props) { + console.log('Pan Responder Mounted', useNativeDriver); + const { routes, index } = navigationState; const panX = useAnimatedValue(0); @@ -88,7 +91,7 @@ export function PanResponderAdapter({ timing(panX, { ...transitionConfig, toValue: offset, - useNativeDriver: false, + useNativeDriver: useNativeDriver, }), ]).start(({ finished }) => { if (finished) { diff --git a/packages/react-native-tab-view/src/TabBar.tsx b/packages/react-native-tab-view/src/TabBar.tsx index edee5bb325..9397c67841 100644 --- a/packages/react-native-tab-view/src/TabBar.tsx +++ b/packages/react-native-tab-view/src/TabBar.tsx @@ -373,7 +373,9 @@ export function TabBar({ layout: propLayout, testID, android_ripple, + useNativeDriver = true, }: Props) { + console.log('Tab Bar Mounted', useNativeDriver); const [layout, setLayout] = React.useState( propLayout ?? { width: 0, height: 0 } ); @@ -607,9 +609,9 @@ export function TabBar({ }, }, ], - { useNativeDriver: true } + { useNativeDriver: useNativeDriver } ), - [scrollAmount] + [scrollAmount, useNativeDriver] ); const handleViewableItemsChanged = useLatestCallback( diff --git a/packages/react-native-tab-view/src/TabBarIndicator.tsx b/packages/react-native-tab-view/src/TabBarIndicator.tsx index e34bf6a524..84c0c75841 100644 --- a/packages/react-native-tab-view/src/TabBarIndicator.tsx +++ b/packages/react-native-tab-view/src/TabBarIndicator.tsx @@ -62,6 +62,7 @@ export function TabBarIndicator({ gap, style, children, + useNativeDriver = true, }: Props) { const isIndicatorShown = React.useRef(false); const isWidthDynamic = width === 'auto'; @@ -89,7 +90,7 @@ export function TabBarIndicator({ toValue: 1, duration: 150, easing: Easing.in(Easing.linear), - useNativeDriver: true, + useNativeDriver: useNativeDriver, }).start(); } }; @@ -97,7 +98,7 @@ export function TabBarIndicator({ fadeInIndicator(); return () => opacity.stopAnimation(); - }, [indicatorVisible, isWidthDynamic, opacity]); + }, [indicatorVisible, isWidthDynamic, opacity, useNativeDriver]); const { routes } = navigationState; diff --git a/packages/react-native-tab-view/src/TabView.tsx b/packages/react-native-tab-view/src/TabView.tsx index f72ac46ba9..063aa145f7 100644 --- a/packages/react-native-tab-view/src/TabView.tsx +++ b/packages/react-native-tab-view/src/TabView.tsx @@ -59,6 +59,7 @@ export function TabView({ tabBarPosition = 'top', animationEnabled = true, overScrollMode, + useNativeDriver = true, }: Props) { if ( Platform.OS !== 'web' && @@ -109,6 +110,7 @@ export function TabView({ overScrollMode={overScrollMode} style={pagerStyle} layoutDirection={direction} + useNativeDriver={useNativeDriver} > {({ position, render, addEnterListener, jumpTo }) => { // All the props here must not change between re-renders @@ -125,6 +127,7 @@ export function TabView({ renderTabBar({ ...sceneRendererProps, navigationState, + useNativeDriver: useNativeDriver, })} {render( navigationState.routes.map((route, i) => { @@ -155,6 +158,7 @@ export function TabView({ renderTabBar({ ...sceneRendererProps, navigationState, + useNativeDriver: useNativeDriver, })} ); diff --git a/packages/react-native-tab-view/src/types.tsx b/packages/react-native-tab-view/src/types.tsx index 774a8cfa2c..df5a850867 100644 --- a/packages/react-native-tab-view/src/types.tsx +++ b/packages/react-native-tab-view/src/types.tsx @@ -37,6 +37,7 @@ export type SceneRendererProps = { layout: Layout; position: Animated.AnimatedInterpolation; jumpTo: (key: string) => void; + useNativeDriver?: boolean; }; export type EventEmitterProps = { @@ -58,4 +59,5 @@ export type PagerProps = Omit< animationEnabled?: boolean; onSwipeStart?: () => void; onSwipeEnd?: () => void; + useNativeDriver?: boolean; }; From 1d59af36057426bba0963ae210065dab56b38594 Mon Sep 17 00:00:00 2001 From: Vibhor Verma Date: Mon, 4 Mar 2024 11:51:13 +0530 Subject: [PATCH 2/4] feat: added prop defination for useNativeDriver --- .../src/PanResponderAdapter.tsx | 2 +- packages/react-native-tab-view/src/types.tsx | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/react-native-tab-view/src/PanResponderAdapter.tsx b/packages/react-native-tab-view/src/PanResponderAdapter.tsx index c99c0082a8..2d42180c9e 100644 --- a/packages/react-native-tab-view/src/PanResponderAdapter.tsx +++ b/packages/react-native-tab-view/src/PanResponderAdapter.tsx @@ -106,7 +106,7 @@ export function PanResponderAdapter({ pendingIndexRef.current = undefined; } }, - [animationEnabled, panX] + [animationEnabled, panX, useNativeDriver] ); React.useEffect(() => { diff --git a/packages/react-native-tab-view/src/types.tsx b/packages/react-native-tab-view/src/types.tsx index df5a850867..74c3f148cb 100644 --- a/packages/react-native-tab-view/src/types.tsx +++ b/packages/react-native-tab-view/src/types.tsx @@ -37,6 +37,12 @@ export type SceneRendererProps = { layout: Layout; position: Animated.AnimatedInterpolation; jumpTo: (key: string) => void; + + /** + * Whether to use js thread or native UI thread for running animations. + * Setting it true will run animations on UI thread else will run on js thread. + * Deafult value is set to true. + */ useNativeDriver?: boolean; }; @@ -59,5 +65,11 @@ export type PagerProps = Omit< animationEnabled?: boolean; onSwipeStart?: () => void; onSwipeEnd?: () => void; + + /** + * Whether to use js thread or native UI thread for running animations. + * Setting it true will run animations on UI thread else will run on js thread. + * Deafult value is set to true. + */ useNativeDriver?: boolean; }; From 675e6febf0d05cda579d9b942f1c4ff52e7f2978 Mon Sep 17 00:00:00 2001 From: Vibhor Verma Date: Tue, 5 Mar 2024 12:28:06 +0530 Subject: [PATCH 3/4] chore: remove log --- packages/react-native-tab-view/src/PagerViewAdapter.tsx | 2 -- packages/react-native-tab-view/src/PanResponderAdapter.tsx | 2 -- 2 files changed, 4 deletions(-) diff --git a/packages/react-native-tab-view/src/PagerViewAdapter.tsx b/packages/react-native-tab-view/src/PagerViewAdapter.tsx index afc89ccb22..51199c3937 100644 --- a/packages/react-native-tab-view/src/PagerViewAdapter.tsx +++ b/packages/react-native-tab-view/src/PagerViewAdapter.tsx @@ -46,8 +46,6 @@ export function PagerViewAdapter({ useNativeDriver = true, ...rest }: Props) { - console.log('Pager VAdapter Mounted', useNativeDriver); - const { index } = navigationState; const listenersRef = React.useRef([]); diff --git a/packages/react-native-tab-view/src/PanResponderAdapter.tsx b/packages/react-native-tab-view/src/PanResponderAdapter.tsx index 2d42180c9e..526fa809ca 100644 --- a/packages/react-native-tab-view/src/PanResponderAdapter.tsx +++ b/packages/react-native-tab-view/src/PanResponderAdapter.tsx @@ -62,8 +62,6 @@ export function PanResponderAdapter({ layoutDirection = 'ltr', useNativeDriver = true, }: Props) { - console.log('Pan Responder Mounted', useNativeDriver); - const { routes, index } = navigationState; const panX = useAnimatedValue(0); From c3681c44109274dbb78eaf76a0cf7717049d8469 Mon Sep 17 00:00:00 2001 From: vibhorverma Date: Mon, 15 Apr 2024 16:52:40 +0530 Subject: [PATCH 4/4] feat: added use native driver value in tab navigator in test file for material top tab --- packages/material-top-tabs/src/__tests__/index.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-top-tabs/src/__tests__/index.test.tsx b/packages/material-top-tabs/src/__tests__/index.test.tsx index fec4dcbc82..48b75ef00a 100644 --- a/packages/material-top-tabs/src/__tests__/index.test.tsx +++ b/packages/material-top-tabs/src/__tests__/index.test.tsx @@ -42,7 +42,7 @@ it('renders a material top tab navigator with screens', async () => { const { findByText, queryByText } = render( - +