gorhom / react-native-animated-tabbar Goto Github PK
View Code? Open in Web Editor NEWA 60FPS animated tab bar with a variety of cool animation presets 😎
License: MIT License
A 60FPS animated tab bar with a variety of cool animation presets 😎
License: MIT License
Library | Version |
---|---|
@gorhom/animated-tabbar | 1.6.0 |
react-native | 0.61.5 |
react-native-reanimated | 1.9.0 |
react-native-gesture-handler | 1.6.1 |
react-native-svg | 12.1.0 |
reactn
to change some data in tab ADescribe what you expected to happen:
tabBarComponent: TabBar
line in createBottomTabNavigator()
options)null
Hello,
First, thank for the component ! 👍
But I have a small problem :(
When I first load the app, the inactiveColor what not apply , it the default icon color
but when I moving on other tab all working fine
I dont understand why ... If someone can help me
@gorhom/animated-tabbar 2.0.1
"react-native": "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz",
"react-native-reanimated": "~1.9.0",
"react-native-gesture-handler": "~1.6.0",
"react-native-svg": "12.1.0",
BubbleTabBarItemConfig,
TabsConfig,
} from "@gorhom/animated-tabbar";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
...
import Animated from "react-native-reanimated";
import AntDesignIcon from "react-native-vector-icons/AntDesign";
....
const Icon = Animated.createAnimatedComponent(AntDesignIcon);
const backgroundTab = (theme: ReactNativePaper.Theme): BackGroundTab => {
return {
backgroundTab: {
activeColor: theme.colors.primary,
inactiveColor: theme.dark ? "#272727" : "#f8f8f8",
},
iconTab: {
activeColor: Colors.white,
inactiveColor: theme.colors.text,
},
labelTab: {
color: Colors.white,
width: 60,
fontFamily: "product-sans",
},
};
};
const tabs = (
theme: ReactNativePaper.Theme
): TabsConfig<BubbleTabBarItemConfig> => {
return {
Home: {
labelStyle: backgroundTab(theme).labelTab,
icon: {
...backgroundTab(theme).iconTab,
component: (props) => <Icon name="home" {...props} />,
},
background: backgroundTab(theme).backgroundTab,
},
Manage: {
labelStyle: backgroundTab(theme).labelTab,
icon: {
...backgroundTab(theme).iconTab,
component: (props) => <Icon name="tool" {...props} />,
},
background: backgroundTab(theme).backgroundTab,
},
Summary: {
labelStyle: backgroundTab(theme).labelTab,
icon: {
...backgroundTab(theme).iconTab,
component: (props) => <Icon name="pushpino" {...props} />,
},
background: backgroundTab(theme).backgroundTab,
},
};
};
...
const Tab = createBottomTabNavigator<TabParamList>();
const TabStack: React.FC<{
theme: ReactNativePaper.Theme;
screenOptions: any;
}> = ({ theme, screenOptions }) => {
return (
<Tab.Navigator
initialRouteName="Home"
tabBar={(props) => (
<AnimatedTabBar
iconSize={24}
tabs={tabs(theme)}
{...props}
style={{
...styles.tabBarContainer,
backgroundColor: theme.dark ? "#272727" : "#f8f8f8",
elevation: 24,
}}
/>
)}
>
....
Adding tabBarOptions={{keyboardHidesTabBar: true}}
on either Tab.Navigator
component from React Navigation 5.x or AnimatedTabBar
from this library doesn't work - the tab bar still shows above keyboard.
Tested on Android v10 Emulator
Library | Version |
---|---|
@gorhom/animated-tabbar | 1.6.0 |
react-native | 0.62.2 |
react-native-reanimated | 1.9.0 |
react-native-gesture-handler | 1.6.1 |
react-native-svg | 12.1.0 |
tabBarOptions={{keyboardHidesTabBar: true}}
to Tab.Navigator
Describe what you expected to happen:
tabBarOptions={{keyboardHidesTabBar: true}}
should hide the tab bar when using keyboard<Tab.Navigator
tabBarOptions={{
keyboardHidesTabBar: true
}}
tabBar={props => (
<AnimatedTabBar style={{backgroundColor: '#272727'}} tabs={tabs} {...props}/>
)}
>
I have many use-cases for bubble tab bar but tab style is different so I couldn't achieve this.
it would be great and more effective if we can customize tabs styles or more
Awesome work 👏🏽👍🏽
As described in the title and shown in the screenshot below. It happens when there is more than 4 tab bar items and you are using a small device (this is taken from an iPhone 8)
Library | Version |
---|---|
@gorhom/animated-tabbar | https://github.com/jesster2k10/react-native-animated-tabbar.git |
react-native | 0.61.5 |
react-native-reanimated | ^1.7.0 |
react-native-gesture-handler | ^1.5.3 |
react-native-svg | ^12.0.3 |
Setup a tab bar with more than 4 screens and run it on an iPhone 8 or smaller.
Describe what you expected to happen:
There should be adequate spacing between the edges of the screen and the tab bar on smaller devices.
A possible solution would be to decrease the spacing between items on smaller devices or the font sizes/width to provide a better UI.
react navigation provide options
props in the Tab.Screen
, one of the options you pass to options
is tabBarVisible
as everyone knows, when using Tab navigator without this lib the tabBarVisible
works fine, but when i integrate it with this lib it stop working, the tab bar still visible even i pass the tabBarVisible
and set it to false
Library | Version |
---|---|
@gorhom/animated-tabbar | 2.0.0 |
react-native | 0.61.5 |
react-native-reanimated | 1.9.0 |
react-native-gesture-handler | 1.6.1 |
react-native-svg | 12.1.0 |
Hi @gorhom , it would be very useful to have working examples on https://snack.expo.io/
const tabs = {
[routeNames.app.main]: {
labelStyle: {
color: '#5B37B7',
},
icon: {
component: () => <AnimatedSVG />,
activeColor: 'rgba(91,55,183,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(223,215,243,1)',
inactiveColor: 'rgba(223,215,243,0)',
},
},
[routeNames.app.fixture]: {
labelStyle: {
color: '#1194AA',
},
icon: {
component: () => <AnimatedSVG />,
activeColor: 'rgba(17,148,170,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(207,235,239,1)',
inactiveColor: 'rgba(207,235,239,0)',
},
},
[routeNames.app.venue]: {
labelStyle: {
color: '#1194AA',
},
icon: {
component: () => <AnimatedSVG />,
activeColor: 'rgba(17,148,170,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(207,235,239,1)',
inactiveColor: 'rgba(207,235,239,0)',
},
},
[routeNames.app.profile]: {
labelStyle: {
color: '#1194AA',
},
icon: {
component: () => <AnimatedSVG />,
activeColor: 'rgba(17,148,170,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(207,235,239,1)',
inactiveColor: 'rgba(207,235,239,0)',
},
},
};
/**
* The main navigator for the authenticated section of the app. Uses a drawer/sidebar.
*/
export const AppStack = createBottomTabNavigator(
{
[routeNames.app.main]: {
screen: HomeStack,
},
[routeNames.app.fixture]: {
screen: FixtureStack,
},
[routeNames.app.venue]: {
screen: VenueStack,
},
[routeNames.app.profile]: {
screen: ProfileStack,
},
},
{
tabBarComponent: props => <AnimatedTabBar tabs={tabs} {...props} />,
},
);
Library | Version |
---|---|
@gorhom/animated-tabbar | 2.0.0 |
react-native | 0.61.5 |
react-native-reanimated | 1.4.0 |
react-native-gesture-handler | 1.5.0 |
react-native-svg | 9.12.0 |
react-navigation | 4.0.10 |
Followed install steps, using JS, not typescript and navigation v4
reload app
Describe what you expected to happen:
will try to add if needed
I would like to change the whole bottom bar's style change. If this would be optional, it will be great. Actually I just want to change some border radius and the colors and maybe add a shadow. Is that possible to let us change the style?
(I tried to add border radius via 'style' prop but bottom side there is a white background all the time)
Maybe it is because of the Navigation part but I could not fix it. Maybe you can guide me
More customization possibilities.
<AnimatedTabBar preset="flashy" tabs={tabs} iconSize={25} style={{borderRadius:16, backgroundColor:"#059505, ...shadowStyles}} {...props} />
type errors The Tabnavigator tabBar parameter receives a React.ReactNode or undefine component, however AnimatedTabBar and of type JSX Element
Library | Version |
---|---|
@gorhom/animated-tabbar | ^2.1.0 |
react-native | 0.63.3 |
react-native-reanimated | ^1.13.1 |
react-native-gesture-handler | ^1.8.0 |
react-native-svg | ^12.1.0 |
Describe what you expected to happen:
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import AnimatedTabBar, {
TabsConfig,
BubbleTabBarItemConfig,
} from '@gorhom/animated-tabbar';
import HomeIcon from '../Tab/icons/Home';
import ProfileIcon from '../Tab/icons/ProfileIcon';
import Home from '../../screens/Home';
import Profile from '../../screens/Profile';
const tabs: TabsConfig<BubbleTabBarItemConfig> = {
Home: {
labelStyle: {
color: '#5B37B7',
},
icon: {
component: <HomeIcon />,
activeColor: 'rgba(91,55,183,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(223,215,243,1)',
inactiveColor: 'rgba(223,215,243,0)',
},
},
Profile: {
labelStyle: {
color: '#1194AA',
},
icon: {
component: <ProfileIcon />,
activeColor: 'rgba(17,148,170,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(207,235,239,1)',
inactiveColor: 'rgba(207,235,239,0)',
},
},
};
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
tabBar={(props) => {
console.log(props);
return <AnimatedTabBar tabs={tabs} />;
}}>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="Profile" component={Profile} />
</Tab.Navigator>
</NavigationContainer>
);
}
Watch here: https://streamable.com/t7rnz3
import React from 'react';
import Icons from 'react-native-vector-icons/Ionicons';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import AnimatedTabBar from '@gorhom/animated-tabbar';
import Home from '../screens/Home';
const tabs = {
Home: {
labelStyle: { color: 'blue' },
icon: {
component: (props) => <Icons name="home-outline" {...props} />,
color: '#BBB',
},
},
Profile1: {
labelStyle: { color: 'blue' },
icon: {
component: (props) => <Icons name="home-outline" {...props} />,
color: '#BBB',
},
},
Profile2: {
labelStyle: { color: 'blue' },
icon: {
component: (props) => <Icons name="home-outline" {...props} />,
color: '#BBB',
},
},
Profile3: {
labelStyle: { color: 'blue' },
icon: {
component: (props) => <Icons name="home-outline" {...props} />,
color: '#BBB',
},
},
Profile4: {
labelStyle: { color: 'blue' },
icon: {
component: (props) => <Icons name="home-outline" {...props} />,
color: '#BBB',
},
},
};
const Tab = createBottomTabNavigator();
export default function App() {
return (
<Tab.Navigator
tabBar={(props) => (
<AnimatedTabBar
tabs={tabs}
preset="flashy"
itemInnerSpace={5}
{...props}
/>
)}
>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="Profile1" component={Home} />
<Tab.Screen name="Profile2" component={Home} />
<Tab.Screen name="Profile3" component={Home} />
<Tab.Screen name="Profile4" component={Home} />
</Tab.Navigator>
);
}
While running on iOS simulator there was a huge noticeable CPU usage when using this nice library which causes drop in the whole app performance.
Library | Version |
---|---|
@gorhom/animated-tabbar | 1.2.0 |
react-native | 0.61 |
react-native-reanimated | 1.8.0 |
react-native-gesture-handler | 1.6.1 |
react-native-svg | 12.1.0 |
By just simply adding it as a prop:
tabBar={props => (
<AnimatedTabBar
isRTL={I18nManager.isRTL}
duration={500}
iconSize={29}
//itemOuterSpace={{horizontal:20}}
itemInnerSpace={{horizontal: 15,}}
style={{
shadowOffset: {
height: 0,
width: 0,
},
shadowColor: 'rgba(0,0,0,0.16)',
shadowRadius: 5,
shadowOpacity: 0.4,
backgroundColor: '#FFFFFF',
height: hasNotch ? 98 : null,
paddingHorizontal: 0,
elevation: 12,
}}
tabs={tabs}
{...props}
/>
)}
Library | Version |
---|---|
@gorhom/animated-tabbar | ^2.1.0 |
react-native | 0.63.3 |
react-native-reanimated | ^1.13.0 |
react-native-gesture-handler | ^1.8.0 |
react-native-svg | ^12.1.0 |
@gorhom : Shouldn't it be a dev dependencies?
Hi, thanks for creating this. Could you provide a working JS example? I'm trying to convert but having problems left right centre!
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of BubbleTabBarItemComponent
.
This error is located at:
in RCTView (at BubbleTabBarItem.tsx:166)
in RCTView (at createAnimatedComponent.js:233)
in AnimatedComponent(Component) (at BubbleTabBarItem.tsx:165)
in RCTView (at createAnimatedComponent.js:233)
in AnimatedComponent(Component) (at BubbleTabBarItem.tsx:164)
in BubbleTabBarItemComponentit
in BubbleTabBarItemComponent (at BubbleTabBar.tsx:78)
in RCTView (at createAnimatedComponent.js:233)
in AnimatedComponent(Component) (at RawButton.tsx:109)
in LongPressGestureHandler (at RawButton.tsx:105)
in RCTView (at createAnimatedComponent.js:233)
in AnimatedComponent(Component) (at RawButton.tsx:96)
in TapGestureHandler (at RawButton.tsx:92)
in RawButton (at BubbleTabBar.tsx:70)
in RCTView (at BubbleTabBar.tsx:67)
and below image i do the same Docs
Hi @gorhom , as you requested I have opened a separate ticket.
it is based on the bubble Preset, only that you see the transition animation effect from one tab to another.
Library | Version |
---|---|
@gorhom/animated-tabbar | ^2.1.0 |
react-native | 0.63.3 |
react-native-reanimated | ^1.13.0 |
react-native-gesture-handler | ^1.8.0 |
react-native-svg | ^12.1.0 |
@gorhom : I am using the following boilerplate, the NavigationContainer is already defined at the app level as you can see.
This code I am using inside a containers, this is an example of container:
import React, { useState, useEffect } from 'react';
import { View, StyleSheet, Text } from 'react-native';
const Home = () => {
return (
<View>
<Text>Home</Text>
</View>
);
};
const Profile = () => {
return (
<View>
<Text>Home</Text>
</View>
);
};
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import AnimatedTabBar, {
TabsConfig,
BubbleTabConfig,
} from '@gorhom/animated-tabbar';
const Tab = createBottomTabNavigator();
const tabs = {
Home: {
labelStyle: {
color: '#5B37B7',
},
icon: {
activeColor: 'rgba(91,55,183,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(223,215,243,1)',
inactiveColor: 'rgba(223,215,243,0)',
},
},
Profile: {
labelStyle: {
color: '#1194AA',
},
icon: {
activeColor: 'rgba(17,148,170,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(207,235,239,1)',
inactiveColor: 'rgba(207,235,239,0)',
},
},
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#999',
},
tabBarContainer: {
borderRadius: 25,
},
});
const IndexHomeContainer = (props) => {
return (
<Tab.Navigator
tabBar={(props) => (
<AnimatedTabBar iconSize={20} tabs={tabs} {...props} />
)}>
<Tab.Screen
name="Home"
initialParams={{
backgroundColor: tabs.Home.labelStyle.color,
nextScreen: 'Likes',
}}
component={Home}
/>
<Tab.Screen
name="Profile"
initialParams={{
backgroundColor: tabs.Profile.labelStyle.color,
nextScreen: 'Home',
}}
component={Profile}
/>
</Tab.Navigator>
);
};
export default IndexHomeContainer;
I believe it is a problem. I can not add top border on the tab bar.
Is there any way to do this?
Library | Version |
---|---|
@gorhom/animated-tabbar | 2.1.0 |
react-native | 0.63.3 |
react-native-reanimated | 1.13.2 |
react-native-gesture-handler | 1.8.0 |
react-native-svg | 12.1.0 |
Describe what you expected to happen:
const tabs = { Home: { icon: { component: Svgs.Home, color: 'rgba(255,255,255,1)', }, ripple: { color: '#5B37B7', }, }, Category: { labelStyle: { color: '#ffffff', }, icon: { component: Svgs.Category, color: 'rgba(255,255,255,1)', }, // background: { // activeColor: '#ff9800', // inactiveColor: 'rgba(207,235,239,0)', // }, ripple: { color: '#C9379D', }, }, Search: { labelStyle: { color: '#ffffff', }, icon: { component: Svgs.Search, color: 'rgba(255,255,255,1)', }, // background: { // activeColor: '#ff9800', // inactiveColor: 'rgba(207,235,239,0)', // }, ripple: { color: '#202E2E', }, }, Payment: { labelStyle: { color: '#ffffff', }, icon: { component: Svgs.Payment, color: 'rgba(255,255,255,1)', }, // background: { // activeColor: '#ff9800', // inactiveColor: 'rgba(207,235,239,0)', // }, ripple: { color: '#E6A919', }, }, Profile: { labelStyle: { color: '#ffffff', }, icon: { component: Svgs.Profile, color: 'rgba(255,255,255,1)', }, ripple: { color: '#1194AA', }, }, };
<Tab.Navigator tabBarOptions={tabBarOptions} tabBar={(props) => ( <AnimatedTabBar preset="material" animation="iconWithLabel" iconSize={24} tabs={tabs} duration={500} {...props} /> )} > <Tab.Screen name="Home" component={Home} /> <Tab.Screen name="Category" component={Search} /> <Tab.Screen name="Search" component={Search} /> <Tab.Screen name="Payment" component={Payment} options={{ tabBarBadge: 3 }} /> <Tab.Screen name="Profile" component={Profile} /> </Tab.Navigator>
Below is my code:
<Tab.Navigator
tabBarOptions={{
style: {
backgroundColor: 'tomato',
},
}}
tabBar={(props) => (
<AnimatedTabBar
preset="material"
tabs={tabs}
iconSize={20}
duration={500}
{...props}
/>
)}
>
<Tab.Screen name="Home" component={HomeStack} />
<Tab.Screen
name="Profile"
component={ProfileStack}
options={({route}) => ({
tabBarVisible: getTabBarVisibility(route),
})}
/>
</Tab.Navigator>
I'm using mobx for states. I crated cart system. When cart count changes, badge not updating.
Cart.tsx file like this:
const CartSVG = ({ color, size }: SVGProps) => {
const user = CounterStore.user;
return (
<View>
<View style={styles.badge}>
<Text style={styles.badgeText}>{user.basket}</Text>
</View>
<SvgXml xml={xml} width="25" height="24" />
</View>
);
};
export default CartSVG;
Hi @gorhom , as you requested I have opened a separate ticket.
It would be useful to be able to put an image/photo, whether it is local or from http.
With the possibility of adding style code to make customizations.
Example as you can see from the image the circular black border on the image with a little padding.
undefined is not a function (near '...(0, _reactNativeReanimated.useCode)...')
It would be nice to explicitly add some information for
Animated.addWhitelistedNativeProps
Otherwise reanimated will constantly emit notifications over the bridge.
I see it in your SVG examples, but missed out initially.
I want to use this ticket also to thank you for this awesome package!
Hello, This library is awesome!
but, Flash Preset behaves strangely at React Native 0.61.5.
The example provided works very well,
but if you change the react native version to 0.61.5, the bug is reproduced.
It only happens on Android.
Library | Version |
---|---|
@gorhom/animated-tabbar | 1.2.0 |
react-native | 0.61.5 |
react-native-reanimated | 1.7.0 |
react-native-gesture-handler | 1.6.0 |
react-native-svg | 12.1.0 |
Thank you.
I am running an existing RN project on a new mac, when running the app on the IOS simulator I am seeing the below error
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of `FlashyTabBarItemComponent`.
This error is located at:
in RCTView (at FlashyTabBarItem.tsx:281)
in RCTView (at createAnimatedComponent.js:233)
in AnimatedComponent(Component) (at FlashyTabBarItem.tsx:280)
in RNCMaskedView (at MaskedView.js:74)
in MaskedView (at FlashyTabBarItem.tsx:276)
in RCTView (at createAnimatedComponent.js:233)
in AnimatedComponent(Component) (at FlashyTabBarItem.tsx:275)
in RCTView (at createAnimatedComponent.js:233)
in AnimatedComponent(Component) (at FlashyTabBarItem.tsx:274)
in FlashyTabBarItemComponent
in FlashyTabBarItemComponent (at FlashyTabBar.tsx:63)
in RCTView (at createAnimatedComponent.js:233)
in AnimatedComponent(Component) (at RawButton.tsx:91)
in LongPressGestureHandler (at RawButton.tsx:87)
in RCTView (at createAnimatedComponent.js:233)
in AnimatedComponent(Component) (at RawButton.tsx:79)
in TapGestureHandler (at RawButton.tsx:75)
in RawButton (at FlashyTabBar.tsx:55)
in RCTView (at FlashyTabBar.tsx:52)
in FlashyTabBarComponent
in FlashyTabBarComponent (at AnimatedTabBarView.tsx:96)
in AnimatedTabBarView (at AnimatedTabBar.tsx:178)
in AnimatedTabBar (at App/index.js:119)
in RCTView (at BottomTabView.tsx:96)
in SafeAreaConsumer (at SafeAreaProviderCompat.tsx:32)
in SafeAreaProviderCompat (at BottomTabView.tsx:95)
in BottomTabView (at createBottomTabNavigator.tsx:41)
in BottomTabNavigator (at App/index.js:117)
in TabScreen (at SceneView.tsx:121)
in StaticContainer
in StaticContainer (at SceneView.tsx:112)
in EnsureSingleNavigator (at SceneView.tsx:111)
in SceneView (at useDescriptors.tsx:147)
in RCTView (at CardContainer.tsx:199)
in RCTView (at CardContainer.tsx:198)
in RCTView (at CardSheet.tsx:33)
in ForwardRef(CardSheet) (at Card.tsx:543)
in RCTView (at createAnimatedComponent.js:151)
in AnimatedComponent (at Card.tsx:525)
in PanGestureHandler (at GestureHandler.native.tsx:13)
in PanGestureHandler (at Card.tsx:519)
in RCTView (at createAnimatedComponent.js:151)
in AnimatedComponent (at Card.tsx:510)
in RCTView (at Card.tsx:504)
in Card (at CardContainer.tsx:168)
in CardContainer (at CardStack.tsx:555)
in RCTView (at Screens.tsx:70)
in MaybeScreen (at CardStack.tsx:548)
in RCTView (at Screens.tsx:48)
in MaybeScreenContainer (at CardStack.tsx:439)
in CardStack (at StackView.tsx:435)
in KeyboardManager (at StackView.tsx:433)
in SafeAreaConsumer (at StackView.tsx:431)
in RNCSafeAreaView (at SafeAreaContext.tsx:50)
in SafeAreaProvider (at SafeAreaProviderCompat.tsx:42)
in SafeAreaConsumer (at SafeAreaProviderCompat.tsx:32)
in SafeAreaProviderCompat (at StackView.tsx:430)
in RCTView (at StackView.tsx:429)
in StackView (at createStackNavigator.tsx:82)
in StackNavigator (at App/index.js:129)
in RootStackScreen (at App/index.js:150)
in EnsureSingleNavigator (at BaseNavigationContainer.tsx:283)
in ForwardRef(BaseNavigationContainer) (at NavigationContainer.tsx:64)
in ThemeProvider (at NavigationContainer.tsx:63)
in ForwardRef(NavigationContainer) (at App/index.js:149)
in App (at renderApplication.js:40)
in RCTView (at AppContainer.js:101)
in RCTView (at AppContainer.js:119)
in AppContainer (at renderApplication.js:39)
renderRoot
[native code]:0
runRootCallback
[native code]:0
renderApplication
renderApplication.js:52:52
runnables.appKey.run
AppRegistry.js:116:10
runApplication
AppRegistry.js:197:26
callFunctionReturnFlushedQueue
[native code]:0
Usage
const tabs = {
Menu: {
labelStyle: {
color: "#5B37B7",
},
icon: {
component: <FontAwesomeIcon icon={faUtensils} />,
activeColor: "rgba(91,55,183,1)",
inactiveColor: "rgba(0,0,0,1)",
},
background: {
activeColor: "rgba(223,215,243,1)",
inactiveColor: "rgba(223,215,243,0)",
},
},
Account: {
labelStyle: {
color: "#1194AA",
},
icon: {
component: <FontAwesomeIcon icon={faUser} />,
activeColor: "rgba(17,148,170,1)",
inactiveColor: "rgba(0,0,0,1)",
},
background: {
activeColor: "rgba(207,235,239,1)",
inactiveColor: "rgba(207,235,239,0)",
},
},
};
const Tab = createBottomTabNavigator();
const TabScreen = () => (
<Tab.Navigator
tabBar={(props) => (
<AnimatedTabBar tabs={tabs} preset="flashy" {...props} />
)}
>
<Tab.Screen name="Menu" component={CatalogStackScreen} />
<Tab.Screen name="Account" component={AccountStackScreen} />
</Tab.Navigator>
);
Library | Version |
---|---|
@gorhom/animated-tabbar | 1.5.1 |
react-native | 0.61.5 |
react-native-reanimated | 1.8.0 |
react-native-gesture-handler | 1.6.1 |
react-native-svg | 12.1.0 |
the preventDefault method of the tabPress event doesn't work correctly, the focus remains on the tab that is pressed
Describe what you expected to happen:
the focus have to remain on the previous tab
<Tab.Screen name="Share" component={YourScreen} listeners={({navigation}) => ({ tabPress: event => { event.preventDefault(); navigation.navigate('YourScreen); }, })} />
When I try to add some curvature to the edges of the Tab Bar (so it doesn't look like a perfect rectangle), the Tab Bar does bend the edges but the background of the Tab Bar has a white background which ruins the whole point.
The only custom options I added to the given implementation in the README file is adding of these Tabbar options -
tabBarOptions={{ style: { backgroundColor: '#181818', borderRadius: 30, borderTopWidth: 2, borderColor: 'rgba(255, 255, 255, 0.1)', }, }}
FYI: Removing everything else from the above tabBarOptions, except for borderRadius also produces the same issue of white background.
Here is the image of how it looks now.
Library | Version |
---|---|
@gorhom/animated-tabbar | 2.0.0 |
react-native | 0.63.2 |
react-native-reanimated | 1.9.0 |
react-native-gesture-handler | 1.6.1 |
react-native-svg | ^12.1.0 |
Describe what you expected to happen:
<TabHere.Navigator initialRouteName="Clubs" tabBarOptions={{ style: { backgroundColor: '#181818', borderRadius: 30, borderTopWidth: 2, borderColor: 'rgba(255, 255, 255, 0.1)', }, }} tabBar={(props) => ( <AnimatedTabBar tabs={tabs} preset="flashy" keyboardHidesTabBar={true} iconSize={20} itemContainerWidth="fill" {...props} /> )}>
Awesome library. I'm happy to make a PR for this, if you're open to publishing it.
The default tabs object looks like this:
const tabs: TabsConfigsType = {
Home: {
labelStyle: {
color: '#5B37B7',
},
icon: {
component: () => null,
activeColor: 'rgba(91,55,183,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(223,215,243,1)',
inactiveColor: 'rgba(223,215,243,0)',
},
},
Profile: {
labelStyle: {
color: '#1194AA',
},
icon: {
component: () => null,
activeColor: 'rgba(17,148,170,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(207,235,239,1)',
inactiveColor: 'rgba(207,235,239,0)',
},
},
}
The keys, Home
and Profile
, could be any strings. I think this should be changed to be the keys of the tabs. This could be implemented by pulling the types passed to the createBottomTabNavigator
.
Prevent this error from happening, due to unclear types:
In src/types.ts
, this line defines the type for the dictionary:
export interface TabsConfigsType {
[key: string]: TabConfigsType;
}
I think the goal should be to let you optionally pass your React Navigation ParamList
type as an argument.
For example, if your Tab
looks like this:
type Params = {
party: undefined
account: undefined
}
const Tab = createBottomTabNavigator<Params>()
...then you should be able to pass Params
as an argument to TabsConfigsType
.
Change this:
export interface TabsConfigsType {
[key: string]: TabConfigsType;
}
To this:
export type TabsConfigsType<
T = { [key: string]: TabConfigsType },
K extends keyof T = keyof T
> = {
[key in K]: TabConfigsType
}
The first generic, T = { [key: string]: TabConfigsType }
is optional, since it has a default value. That default value is equal to the current type. If you don't provide a param list argument, then it will fall back to this.
The second generic, K extends keyof T = keyof T
, extracts the keys. Say your param list is like this:
type Params = {
home: undefined
notifications: undefined
}
const tabs: TabsConfigsType<Params> = {
home: {
// ...
}
notifs: { // 🚨"notifs" does not exist on TabsConfigsType<'home' | 'notifications'>
// ...
}
}
Meanwhile, if you don't pass a generic, it will work normally:
type Params = {
home: undefined
notifications: undefined
}
// no errors 😇
const tabs: TabsConfigsType = {
home: {
// ...
}
notifs: {
// ...
}
}
I changed it to a type
, because the TypeScript interface
doesn't support extracting a key from a union ([key in K]: TabConfigsType
isn't possible in an interface
).
import React from 'react'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import AnimatedTabBar from '@gorhom/animated-tabbar'
interface TabConfigsType {
labelStyle: TextStyle
icon: {
component:
| ((props: {
color: Animated.Node<string | number>
size: number
}) => React.ReactNode)
| React.ReactNode
activeColor: string
inactiveColor: string
}
background: {
activeColor: string
inactiveColor: string
}
}
type TabsConfigsType<
T = { [key: string]: TabConfigsType },
K extends keyof T = keyof T
> = {
[key in K]: TabConfigsType
}
const tabs: TabsConfigsType<MainTabsParams> = {
party: {
labelStyle: {
color: '#5B37B7',
},
icon: {
component: () => null,
activeColor: 'rgba(91,55,183,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(223,215,243,1)',
inactiveColor: 'rgba(223,215,243,0)',
},
},
account: {
labelStyle: {
color: '#1194AA',
},
icon: {
component: () => null,
activeColor: 'rgba(17,148,170,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(207,235,239,1)',
inactiveColor: 'rgba(207,235,239,0)',
},
},
}
type MainTabsParams = {
party: undefined
account: undefined
}
const Tab = createBottomTabNavigator<MainTabsParams>()
export default function MainTabs() {
return (
<Tab.Navigator tabBar={props => <AnimatedTabBar tabs={tabs} {...props} />}>
<Tab.Screen name={NavigationRoutes.party} component={Party} />
<Tab.Screen name={NavigationRoutes.account} component={Home} />
</Tab.Navigator>
)
}
Being able to change the label of the tab bars.
Hi @gorhom , Taking the bubble type as an example but it applies to everyone, I would need the way to change the label of the Screen Tab, the reason is that I allow the user to select the language based on the selected language I would like to show a different label (it depends language) next to the icon.
Example:
Search (en)
Cerca (it)
Rechercher (fr)
The BubbleTabBar could have better support for icons that are taller than they are wide.
The current code assumes all icons are squarish.
From BubbleTabBarItem.tsx:
const iconContainerStyle = [
styles.iconContainer,
{
minHeight: iconSize,
minWidth: iconSize,
},
];
The icon could take an optional minWidth prop.
Hi!
I wanted to use this in my project but I got the following error:
Invariant Violation: Element type is invalid: expected a string or a class/function but got: object.
Check the render method of 'BubbleTabBarItemComponent'.
I tried to copy the example on the readme, but since I'm working in js, I had to delete the TabsConfig<BubbleTabConfig>
part.
The code (part of):
import AnimatedTabBar from '@gorhom/animated-tabbar';
const tabs = {
Home: {
labelStyle: {
color: '#5B37B7',
},
icon: {
component: <FontAwesome name="home" size={25} />,
activeColor: 'rgba(91,55,183,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(223,215,243,1)',
inactiveColor: 'rgba(223,215,243,0)',
},
},
Map: {
labelStyle: {
color: '#5B37B7',
},
icon: {
component: <MaterialIcons name="map" size={25} />,
activeColor: 'rgba(91,55,183,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(223,215,243,1)',
inactiveColor: 'rgba(223,215,243,0)',
},
},
Profile: {
labelStyle: {
color: '#1194AA',
},
icon: {
component: <FontAwesome name="user" size={25} />,
activeColor: 'rgba(17,148,170,1)',
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: 'rgba(207,235,239,1)',
inactiveColor: 'rgba(207,235,239,0)',
},
},
};
const TabStack = createBottomTabNavigator();
function TabNavigator() {
return (
<TabStack.Navigator
initialRouteName="Home"
tabBar={props => (
<AnimatedTabBar tabs={tabs} {...props} />
)}
>
<TabStack.Screen name="Home" component={HomeScreen} />
<TabStack.Screen name="Map" component={MapScreen} />
<TabStack.Screen name="Profile" component={ProfileScreen} />
</TabStack.Navigator>
);
}
const MainStack = createStackNavigator();
function MainNavigator() {
return (
<MainStack.Navigator initialRouteName="Tab">
<MainStack.Screen name="Tab" component={TabNavigator} ></MainStack.Screen>
<MainStack.Screen name="PointDetails" component={PointDetailsScreen}></MainStack.Screen>
<MainStack.Screen name="PlanningScreen" component={PlanningScreen}></MainStack.Screen>
</MainStack.Navigator>
);
}
const AppStack = createStackNavigator();
class Navigation extends Component {
render() {
return (
<NavigationContainer>
<AppStack.Navigator>
{this.props.isLogged !== true ?
<AppStack.Screen name="Auth" component={LoginScreen} /> :
<AppStack.Screen name="Main" component={MainNavigator} />
}
</AppStack.Navigator>
</NavigationContainer>
);
}
}
function mapStateToProps(state) {
return { isLogged: state.user.isLogged };
}
export default connect(mapStateToProps)(Navigation);
Used versions:
"@gorhom/animated-tabbar": "^1.5.1",
"react-native-svg": "11.0.1",
"react-native-reanimated": "~1.7.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
"expo": "^37.0.0"
Here I am again :)
When I try to use a custom icon component, it simply gives me this error.
Library | Version |
---|---|
@gorhom/animated-tabbar | 1.5.1 |
react-native | 0.61.5 |
react-native-reanimated | 1.9.0 |
react-native-gesture-handler | 1.6.1 |
react-native-svg | 12.1.0 |
You can even use react-native-vector-icons. It works below 1.5.1 but not works on 1.5.1.
import Icon from "react-native-dynamic-vector-icons";
Upcoming: {
labelStyle: {
color: "#faeb5b",
},
icon: {
component: (
<Icon name="energy" type="SimpleLineIcons" size={20} color="#faeb5b" />
),
color: "rgba(230,169,25,0.8)",
},
},
Describe what you expected to happen:
src/bubble/item/BubbleTabBarItem.tsx
Add a focused
boolean to the custom Icon render function:
// render
const renderIcon = () => {
return typeof icon.component === 'function'
? icon.component({ color: animatedIconColor, size: iconSize, focused: index === selectedIndex })
: icon.component;
};
Also, add this in the typescript definition:
src/types.ts
export interface TabConfigsType {
labelStyle: TextStyle;
icon: {
component:
| ((props: {
color: Animated.Node<string | number>;
size: number;
focused: boolean // 👋 addition
}) => React.ReactNode)
| React.ReactNode;
activeColor: string;
inactiveColor: string;
};
background: {
activeColor: string;
inactiveColor: string;
};
}
in BubbleTabBar.tsx
,
const animatedFocusValues = useMemo(
() =>
tabs.map((_, index) =>
// eslint-disable-next-line react-hooks/rules-of-hooks
useTabBarItemFocusTransition({
index,
selectedIndex,
duration,
easing,
})
),
// eslint-disable-next-line react-hooks/exhaustive-deps
[tabs, duration, easing]
);
the way useTabBarItemFocusTransition
was used breaks the react hooks rules, which are:
is there another way to define animatedFocusValues
?
Hi @gorhom ,
by clicking on an element of the tabbar, normal behavior should change screen.
But a long press on an element of the tabbar could trigger an effect.
For example, as seen in the image it makes a tooltip or popper appear.
Instagram, for example, to a different behavior, if you click on the last element of the tabbar, it allows you to switch accounts.
To give a little originality to everything.
Find below my Navigator
working Fine on IOS but in android Tab is not working ,
but when i change createDrawerNavigator to createStackNavigator it will work like a charm
Thanks in Advance
// Root Navigatorts
const RootNavigator = createDrawerNavigator(
{
Home: {
screen: TabNavigator,
},
Profile: {
screen: Profile,
},
},
{
contentComponent: drawerContentComponents,
drawerBackgroundColor:'#FAFAFA',
// drawerWidth:Dimensions.get('window').width,
}
);
const TabNavigator = createBottomTabNavigator(
{
Explore: Explore,
Gallery: Gallery,
Membership: Explore,
Shop: Gallery,
},
{
tabBarComponent: props => <AnimatedTabBar tabs={tabs} {...props} />,
},
);
Hi @gorhom , as you requested I have opened a separate ticket.
Similar to Material Preset.
When a tab is selected, the other tabs are moved as shown in the image, if it has the label, only its label is visible.
Hey @gorhom, i'm the guy from reddit with the translation issues.
Here's a repo to reproduce:
https://github.com/efstathiosntonas/react-native-animated-tabbar-translated
When you first open the app it will display an error Cannot read property of 'inactiveColor' of undefined
. That's because js reads the code inside the tabs
array before i18n is initialized. Can you think of a solution?
I've tried converting tabs
into a function and pass translate
to it, that way it works but changing tabs no longer works, it stays on the same screen even though tabs are being highlighted (because of useMemo/memo maybe?)
eg:
<AnimatedTabBar tabs={tabs(translate} {...props} />
I get the above error when adding {...props} to my Icon component.
import IconFeather from 'react-native-vector-icons/Feather';
const Icon = Animated.createAnimatedComponent(IconFeather);
...
const tabs: TabsConfig<BubbleTabConfig> = {
Message: {
labelStyle: {
color: Colors.BLUE,
},
icon: {
component: (props) => <Icon name="message-square" {...props}/>,
activeColor: Colors.BLUE_LIGHT,
inactiveColor: 'rgba(0,0,0,1)',
},
background: {
activeColor: Colors.BLUE_LIGHT,
inactiveColor: 'rgba(223,215,243,0)',
},
},
...
TypeError: Cannot add property 13, object is not extensible
That is because the returned props color and isFocused returns functions instead of attributes value. This is what I'm getting for the color prop:
AnimatedCallFunc {__lastLoopID: {…}, __memoizedValue: {…}, __children: Array(0), __nodeID: 823, __nodeConfig: {…}, …}__children: []__initialized: false__inputNodes: (4) [AnimatedOperator, AnimatedOperator, AnimatedOperator, AnimatedOperator]__lastLoopID: {"": -1}__memoizedValue: {"": null}__nodeConfig: {type: "callfunc", what: 47, args: Array(4), params: Array(4)}__nodeID: 823_args: (4) [AnimatedOperator, AnimatedOperator, AnimatedOperator, AnimatedOperator]_params: (4) [AnimatedParam, AnimatedParam, AnimatedParam, AnimatedParam]_what: AnimatedFunction {__lastLoopID: {…}, __memoizedValue: {…}, __children: Array(0), __nodeID: 47, __nodeConfig: {…}, …}__proto__: AnimatedNode
Any clue why @gorhom ? Thank you
@gorhom/animated-tabbar": "2.1.0
react-native": "0.62.2"
react-native-reanimated": "^1.9.0"
react-native-gesture-handler": "^1.6.1"
react-navigation": "^4.4.0"
react-native-svg": "^12.1.0"
I can not add top border on the tab bar.Is there any way to do this?
When pressing a tab item, there is no immediate visible feedback to the user. Making the tab item have a ripple effect (for android), a opacity change (for iOS), or something more custom would be great!
For the user to have a more smooth animated experience.
Not exactly sure, but I think <RawButton />
would need to be modified. Maybe somehow integrating a <Pressable />
(https://reactnative.dev/docs/pressable) or a touchable (https://docs.swmansion.com/react-native-gesture-handler/docs/component-touchables)? @gorhom if you have an idea how to implement this, please let me know since I'm not sure and I would like to open a PR implementing it (but I don't have a lot of experience with animated stuff), unless you would like to do it.
Not sure yet
Im not sure if this is possible at the moment, but it would be great if you could control the X and Y values for inner and outer space independently
If you want a different ratio between X and Y padding for the icons
itemInnerSpace={{x: 10, y: 5}}
itemOuterSpace={{x: 10, y: 5}}
Ideally a solution to allow full control over each side could also be an option i.e Top, Right, Down, Left?
Library | Version |
---|---|
@gorhom/animated-tabbar | 1.5.1 |
react-native | 0.62.2 |
react-native-reanimated | 0.62.2 |
react-native-gesture-handler | 1.6.1 |
react-native-svg | 12.1.0 |
import { default as AnimatedTabBar, TabsConfig, FlashyTabConfig } from '@gorhom/animated-tabbar'
import { createBottomTabNavigator } from 'react-navigation-tabs';
const tabs: TabsConfig<FlashyTabConfig> = {
Beranda: {
icon: {
color: color.primary,
component: props => (
<Feather name="home" {...props}/>
)
},
labelStyle: {
fontFamily: 'Medium',
color: 'black'
},
},
Palugada: {
icon: {
color: color.primary,
component: props => (
<Feather name="home" {...props}/>
)
},
labelStyle: {
fontFamily: 'Medium',
color: 'black'
},
},
Jelajahi: {
icon: {
color: color.primary,
component: props => (
<Feather name="home" {...props}/>
)
},
labelStyle: {
fontFamily: 'Medium',
color: 'black'
},
},
Keranjang: {
icon: {
color: color.primary,
component: props => (
<Feather name="home" {...props}/>
)
},
labelStyle: {
fontFamily: 'Medium',
color: 'black'
},
},
Akun: {
icon: {
color: color.primary,
component: props => (
<Feather name="home" {...props}/>
)
},
labelStyle: {
fontFamily: 'Medium',
color: 'black',
},
},
}
createBottomTabNavigator({
...
tabBarComponent: props => (
<AnimatedTabBar preset="flashy" tabs={tabs} {...props} />
)
})
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.