gorhom / react-native-animated-tabbar

A 60FPS animated tab bar with a variety of cool animation presets šŸ˜Ž
MIT License
1.7k stars 131 forks source link
animated react-native react-navigation reanimated ta tabbar

Animated TabBar

[![npm](https://img.shields.io/npm/v/@gorhom/animated-tabbar?style=flat-square)](https://www.npmjs.com/package/@gorhom/animated-tabbar) [![npm](https://img.shields.io/npm/l/@gorhom/animated-tabbar?style=flat-square)](https://www.npmjs.com/package/@gorhom/animated-tabbar) [![npm](https://img.shields.io/badge/types-included-blue?style=flat-square)](https://www.npmjs.com/package/@gorhom/animated-tabbar) A **60FPS** animated tab bar with a variety of cool animation presets šŸ˜Ž

Table of Contents

  1. Features
  2. Installation
  3. Usage
    1. Animated Icons
  4. Props
  5. Presets
    1. Bubble Preset
    2. Flashy Preset
    3. Material Preset
  6. Migration
  7. To Do
  8. Credits
  9. License

Features

Installation

yarn add @gorhom/animated-tabbar
# or
npm install @gorhom/animated-tabbar

Also, you need to install react-native-reanimated, react-native-gesture-handler & react-native-svg, and follow their installation instructions.

Usage

Originally Animated TabBar worked only with React Navigation, but I notice that it could be use as a standalone component and be more useful for the community.

Now the library export two main components:

Standalone Component ```tsx import React, { useState } from 'react'; import { View, Text, StyleSheet } from 'react-native'; import AnimatedTabBar, {TabsConfig, BubbleTabBarItemConfig} from '@gorhom/animated-tabbar'; const tabs: TabsConfig = { Home: { labelStyle: { color: '#5B37B7', }, icon: { component: /* ICON COMPONENT */, 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: /* ICON COMPONENT */, 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, }, }); export default function App() { const [index, setIndex] = useState(0); return ( {index} ) } ```
React Navigation v5 (TypeScript) ```tsx 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'; const tabs: TabsConfig = { Home: { labelStyle: { color: '#5B37B7', }, icon: { component: /* ICON COMPONENT */, 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: /* ICON COMPONENT */, 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 ( ( )} > ) } ```
React Navigation v5 (JavaScript) ```jsx import React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import AnimatedTabBar from '@gorhom/animated-tabbar'; const tabs = { Home: { // < Screen name labelStyle: { color: '#5B37B7', }, icon: { component: /* ICON COMPONENT */, 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: { // < Screen name labelStyle: { color: '#1194AA', }, icon: { component: /* ICON COMPONENT */, 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 ( ( )} > ) } ```
React Navigation v4 ```tsx import React from 'react'; import {createAppContainer} from 'react-navigation'; import {createBottomTabNavigator} from 'react-navigation-tabs'; import {SafeAreaProvider} from 'react-native-safe-area-context'; import AnimatedTabBar, {TabsConfig, BubbleTabBarItemConfig} from '@gorhom/animated-tabbar'; const tabs: TabsConfig = { Home: { labelStyle: { color: '#5B37B7', }, icon: { component: /* ICON COMPONENT */, 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: /* ICON COMPONENT */, 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 TabNavigator = createBottomTabNavigator( { Home: HomeScreen, Profile: ProfileScreen, }, { tabBarComponent: props => , }, ); const AppContainer = createAppContainer(TabNavigator); export default () => ( ); ```

To configure animated icons, please have a look at Animated Icons.

Props

name description required type default
preset Animation preset, currently options are ['bubble', 'flashy', 'material']. NO PresetEnum 'bubble'
tabs Tabs configurations. A generic dictionary of selected preset tab config. YES TabsConfig<T>
style View style to be applied to tab bar container, default value will be based on selected preset. NO StyleProp
duration Animation duration, default value will be based on selected preset. NO number
easing Animation easing function, default value will be based on selected preset. NO EasingFunction
itemInnerSpace Tab item inner space to be added to the tab item, default value will be based on selected preset. NO number | Space
itemOuterSpace Tab item outer space to be added to the tab item, default value will be based on selected preset. NO number | Space
itemContainerWidth Tab item width stretch strategy, default value will be based on selected preset. NO 'auto' | 'fill'
iconSize Tab item icon size, default value will be based on selected preset. NO number
isRTL Tab bar layout and animation direction. NO boolean false
onLongPress Callback on item long press, by default it is integrated with React Navigation. NO (index: number) => void noop

Preset Configurations

Some presets will have its own configurations - like material - which they will be added the root view props.

Material Preset Example notice here we added `animation`, `inactiveOpacity` & `inactiveScale` to the root view. ```tsx import React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import AnimatedTabBar, {TabsConfig, MaterialTabBarItemConfig} from '@gorhom/animated-tabbar'; const tabs: TabsConfig = { Home: { icon: { component: /* ICON COMPONENT */, color: 'rgba(255,255,255,1)', }, ripple: { color: '#5B37B7', }, }, Profile: { icon: { component: /* ICON COMPONENT */, color: 'rgba(255,255,255,1)', }, ripple: { color: '#1194AA', }, }, }; const Tab = createBottomTabNavigator(); export default function App() { return ( ( )} > ) } ```

Presets

Originally Animated TabBar started with Bubble as the only animation preset embedded. However, I felt the library structure could include many other variety of animation presets.

Bubble Preset

Flashy Preset

Material Preset

Migration

V1 to V2 Due to extend the library functionality, I had to rename existing interfaces as following: - `BubbleTabConfig` to `BubbleTabBarItemConfig` - `BubbleTabIconProps` to `BubbleTabBarIconProps` - `FlashyTabConfig` to `FlashyTabBarItemConfig` - `FlashyTabIconProps` to `FlashyTabBarIconProps`

Author

Sponsor & Support

To keep this library maintained and up-to-date please consider sponsoring it on GitHub. Or if you are looking for a private support or help in customizing the experience, then reach out to me on Twitter @gorhom.

License

MIT

Built With ā¤ļø


Mo Gorhom