Skip to content

Instantly share code, notes, and snippets.

@IjzerenHein
Created February 28, 2022 15:53
Show Gist options
  • Save IjzerenHein/172826535bb7bf782b2a8d6381da42d8 to your computer and use it in GitHub Desktop.
Save IjzerenHein/172826535bb7bf782b2a8d6381da42d8 to your computer and use it in GitHub Desktop.
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { useFocusEffect } from '@react-navigation/native';
import React, { useCallback } from 'react';
import { Animated, StyleSheet } from 'react-native';
import { IconName } from '../components/Icon';
import TabBar from '../components/tabbar/TabBar';
import AccountScreen from '../screens/AccountScreen';
import HelpScreen from '../screens/HelpScreen';
import MyPlaceScreen from '../screens/myplace/MyPlaceScreen';
const Tab = createBottomTabNavigator();
const animTabIndex = new Animated.Value(0);
function createAnimatedTab(Component: React.ComponentType<any>, index: number) {
return function (props: React.ComponentProps<typeof Component>) {
useFocusEffect(
useCallback(() => {
Animated.spring(animTabIndex, {
toValue: index,
stiffness: 200,
damping: 30,
mass: 0.5,
useNativeDriver: true,
}).start();
}, []),
);
return (
<Animated.View
style={{
flex: 1,
opacity: animTabIndex.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [0, 1, 0],
extrapolate: 'clamp',
}),
transform: [
{
translateX: animTabIndex.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [100, 0, -100],
extrapolate: 'clamp',
}),
},
],
}}
>
<Component {...props} />
</Animated.View>
);
};
}
const tabs: {
name: string;
icon: IconName;
title: string;
Component: React.ComponentType<any>;
}[] = [
{
name: 'MyPlace',
Component: MyPlaceScreen,
title: 'My Place',
icon: 'home',
},
{
name: 'Account',
Component: AccountScreen,
title: 'Account',
icon: 'user',
},
{
name: 'Help',
Component: HelpScreen,
title: 'Help',
icon: 'question-circle',
},
];
const TabComponents = tabs.map((tab, index) =>
createAnimatedTab(tab.Component, index),
);
export default function RouterTabs() {
return (
<Tab.Navigator
detachInactiveScreens={false}
keepInactiveScreensVisible
sceneContainerStyle={styles.sceneContainer}
screenOptions={{ headerShown: false }}
tabBar={(props) => (
<TabBar {...props} getIcon={(index) => tabs[index].icon} />
)}
>
{tabs.map((tab, index) => (
<Tab.Screen
key={tab.name}
name={tab.name}
component={TabComponents[index]}
options={{ tabBarLabel: tab.title }}
/>
))}
</Tab.Navigator>
);
}
const styles = StyleSheet.create({
sceneContainer: {
backgroundColor: 'transparent',
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment