Giter VIP home page Giter VIP logo

react-native-animated-tabbar's Introduction

Animated TabBar

npm npm npm

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

  • 60FPS smooth animation for all presets.
  • Fully integrated with React Navigation v4 & v5.
  • Standalone usage.
  • Right-to-left layout support.
  • Accessibility support.
  • Written in TypeScript.

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:

  • AnimatedTabBar ( default ) : the React Navigation integrated tab bar.
  • AnimatedTabBarView: the standalone tab bar.
Standalone Component
import React, { useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import AnimatedTabBar, {TabsConfig, BubbleTabBarItemConfig} from '@gorhom/animated-tabbar';

const tabs: TabsConfig<BubbleTabBarItemConfig> = {
  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 (
    <View style={styles.container}>
      <Text>{index}</Text>
      <AnimatedTabBarView
        tabs={tabs}
        itemOuterSpace={{
          horizontal: 6,
          vertical: 12,
        }}
        itemInnerSpace={12}
        iconSize={20}
        style={styles.tabBarContainer}
        index={index}
        onIndexChange={setIndex}
      />
    </View>
  )
}
React Navigation v5 (TypeScript)
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<BubbleTabBarItemConfig> = {
  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 (
    <NavigationContainer>
      <Tab.Navigator
        tabBar={props => (
          <AnimatedTabBar tabs={tabs} {...props} />
        )}
      >
        <Tab.Screen
          name="Home"
          component={HomeScreen}
        />
        <Tab.Screen
          name="Profile"
          component={ProfileScreen}
        />
      </Tab.Navigator>
    </NavigationContainer>
  )
}
React Navigation v5 (JavaScript)
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 (
    <NavigationContainer>
      <Tab.Navigator
        tabBar={props => (
          <AnimatedTabBar tabs={tabs} {...props} />
        )}
      >
        <Tab.Screen
          name="Home"
          component={HomeScreen}
        />
        <Tab.Screen
          name="Profile"
          component={ProfileScreen}
        />
      </Tab.Navigator>
    </NavigationContainer>
  )
}
React Navigation v4
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<BubbleTabConfig> = {
  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 => <AnimatedTabBar tabs={tabs} {...props} />,
  },
);

const AppContainer = createAppContainer(TabNavigator);

export default () => (
  <SafeAreaProvider>
    <AppContainer />
  </SafeAreaProvider>
);

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.

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<MaterialTabBarItemConfig> = {
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 (
  <NavigationContainer>
    <Tab.Navigator
      tabBar={props => (
        <AnimatedTabBar
          preset='material'
          tabs={tabs}
          animation="iconWithLabelOnFocus"
          inactiveOpacity={0.25}
          inactiveScale={0.5}
          {...props}
        />
      )}
    >
      <Tab.Screen
        name="Home"
        component={HomeScreen}
      />
      <Tab.Screen
        name="Profile"
        component={ProfileScreen}
      />
    </Tab.Navigator>
  </NavigationContainer>
)
}

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.

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

react-native-animated-tabbar's People

Contributors

bechir avatar casprine avatar danielwinkler avatar darkbasic avatar gorhom avatar josephsemrai avatar sconaway avatar vincentbello avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-animated-tabbar's Issues

Cannot read property 'color' of undefined

Bug

Screenshot_20200616-180532_Juabali

Environment info

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

Reproducible sample code

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} />
    )
})

Material Preset Shifting Tab

Feature Request

Why it is needed

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.

useTabBarItemFocusTransition breaks hook rule, why still use it this way?

Bug

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:

  • Call them at the top level in the body of a function component.
  • Call them at the top level in the body of a custom Hook.

is there another way to define animatedFocusValues?

Add onPress visual feedback for tab items (RawButton)

Feature Request

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!

Why it is needed

For the user to have a more smooth animated experience.

Possible implementation

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.

Code sample

Not sure yet

keyboardHidesTabBar option doesn't work

Bug

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

Environment info

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

Steps To Reproduce

  1. Use the example with React Navigation 5.x;
  2. Try adding tabBarOptions={{keyboardHidesTabBar: true}} to Tab.Navigator

Describe what you expected to happen:

  1. Adding tabBarOptions={{keyboardHidesTabBar: true}} should hide the tab bar when using keyboard

Reproducible sample code

<Tab.Navigator
	tabBarOptions={{
		keyboardHidesTabBar: true
	}}
	tabBar={props => (
		<AnimatedTabBar style={{backgroundColor: '#272727'}} tabs={tabs} {...props}/>
	)}
>

animated-tabbar is not working with Drawer Navigator

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} />,
},

);

Badge text not updates on change

Bug

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;

Add more customizable props and enhancements

Feature Request

  • Add more customizable props like tab style for bubble preset
  • Remove isRTL it's redundant because I18nmanager.forceRTL(true) is translates the view to right automatically and your code amazingly supports all views and styles for I18nmanager so you don't need to worry about this

Why it is needed

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 πŸ‘πŸ½πŸ‘πŸ½

i can't do with JS

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)

it is my code by JS :
Screenshot 2020-07-20 at 00 45 46

and below image i do the same Docs

Expensive iOS CPU usage

Bug

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.

ezgif-7-f7729bbbc3eb

Environment info

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

Reproducible sample code

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}
/>
)}

Change the label tab bar

Feature Request

Being able to change the label of the tab bars.

Why it is needed

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)

Add TypeScript typings for TabsConfigsType.

Awesome library. I'm happy to make a PR for this, if you're open to publishing it.

Feature Request

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.

Why it is needed

Prevent this error from happening, due to unclear types:

IMG_526844E00DAD-1

Possible implementation

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.

Proposed solution

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).

Code sample

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>
  )
}

Add focused boolean prop to icon

? icon.component({ color: animatedIconColor, size: iconSize })

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:

color: Animated.Node<string | number>;

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;
  };
}

BubbleTabBar - better support for icons that are taller than they are wide

Feature Request

The BubbleTabBar could have better support for icons that are taller than they are wide.

Why it is needed

The current code assumes all icons are squarish.
From BubbleTabBarItem.tsx:

  const iconContainerStyle = [
    styles.iconContainer,
    {
      minHeight: iconSize,
      minWidth: iconSize,
    },
  ];

Possible implementation

The icon could take an optional minWidth prop.

Navigation events not fired correctly

Bug

Environment info

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

Steps To Reproduce

  1. Create a simple tab bar with 2 pages
  2. Use redux or reactn to change some data in tab A
  3. Try to render conditionally based on data changed from tab A

Describe what you expected to happen:

  1. I expect to see the updates in tabs!
  2. If I use the default react-navigation tab bar, it's working correctly! (try to comment out the tabBarComponent: TabBar line in createBottomTabNavigator() options)

Reproducible sample code

null

color and isFocused returns functions instead of attribute values.

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"

Error observed

undefined is not a function (near '...(0, _reactNativeReanimated.useCode)...')

Flash Preset behaves strangely at React Native 0.61.5

Bug

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.

Environment info

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

Steps To Reproduce

  1. Use animated-tabbar on react native 0.61.5

screenshot_1

Thank you.

backgroundColor not working when I set preset props is material? How can i change backgroundColor Tabbar in this case?

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>

Tab bar pushes too close to the edges of the screen on small devices

Bug

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)

Screenshot 2020-04-10 at 12 41 32

Environment info

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

Steps To Reproduce

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.

The label was line break

Bug

Environment info

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

Steps To Reproduce

  1. Create 5 tabs with label

Screen Shot 2020-12-10 at 10 15 35 PM

Describe what you expected to happen:

  1. The label in one line

Reproducible sample code

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>

Bottom Bar Complete Style Change Customization

Feature Request

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

Why it is needed

More customization possibilities.

Code sample

    <AnimatedTabBar preset="flashy" tabs={tabs} iconSize={25} style={{borderRadius:16, backgroundColor:"#059505,  ...shadowStyles}} {...props} />

Invariant Violation: Element type is invalid. Check the render method of 'BubbleTabBarItemComponent'

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"

Adding to borderRadius to tabBarOptions leave a white background. Can not add radius to the Tab Bar.

Bug

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.
20200829_201102 (1)

Environment info

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

Steps To Reproduce

  1. Add borderRadius to tabBarOptions
  2. The Tab bar does have a radius now, but there is a white background in the back which ruins the whole point.

Describe what you expected to happen:

  1. There should be a way to add radius to the white background in the back as well or it has to be transparent, so, more custom tab bars on top of the brilliant TabBar provided by this package

Reproducible sample code

<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} /> )}>

preventDefault doesn't work correctly

Bug

the preventDefault method of the tabPress event doesn't work correctly, the focus remains on the tab that is pressed

Steps To Reproduce

  1. add the tabPress listener with the navigate method to the Tab.Screen
  2. Run the App
  3. Click to the relative tab
  4. Press back icon to return to the previous screen

Describe what you expected to happen:
the focus have to remain on the previous tab

Reproducible sample code

<Tab.Screen name="Share" component={YourScreen} listeners={({navigation}) => ({ tabPress: event => { event.preventDefault(); navigation.navigate('YourScreen); }, })} />

t_video5947238981388207483

How to translate the tabs?

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} />

react-native-svg could not be found

Bug

Schermata 2020-11-18 alle 15 22 07

Environment info

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

Steps To Reproduce

  1. I have installed the module.
  2. pod install
  3. npx react-native link
  4. I started app.

@gorhom : Shouldn't it be a dev dependencies?

Cannot get installed/working possibly js/ts issue

Bug

88686803-5df01e00-d0ef-11ea-8de4-2ece6eb3852c

sample code
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} />,
  },
);

Environment info

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

Steps To Reproduce

Followed install steps, using JS, not typescript and navigation v4
reload app

Describe what you expected to happen:

  1. no error

Reproducible sample code

will try to add if needed

More control over item inner/outer space

Feature Request

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

Why it is needed

If you want a different ratio between X and Y padding for the icons

Possible implementation

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?

InactiveColor not apply on first load

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

Capture d’écran du 2020-09-10 02-58-41

but when I moving on other tab all working fine

Capture d’écran du 2020-09-10 02-59-36

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,
          }}
        />
      )}
    >
   ....

Badge

Feature Request

Why it is needed

Being able to indicate via a badge in the icon would allow you to suggest on any page that there are new updates.

Tapping on icons tabbar nothing happens (Android)

Bug

When tapping nothing happens

Environment info

OS: Android 10

Library Version
@gorhom/animated-tabbar 1.5.1
react-native 0.62.2
react-native-reanimated 1.8.0
react-native-gesture-handler 1.6.1
react-native-svg 12.1.0

Steps To Reproduce

GIF attached

On iOS all is working perfect.

Screen-Recording-2020-06-10-at-4 54 13-AM

TypeError: undefined is not an object (evaluating 'navigation.state')

Bug

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

Steps To Reproduce

  1. Usage - React Navigation v5 (TypeScript)

Describe what you expected to happen:

codigo

erro

Screenshot_20201027-181840

terminal

Reproducible sample code

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>
  );
}

Element type is invalid

Bug

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>
);

Environment info

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

Steps To Reproduce

maximum number of tabs?

There is a maximum number of tabs? add 6 tabs, but 2 come off the screen.
I attach the image of the current result,

menuoff1

and the desired result.

menuok1

Poor Performance when having more than 3 tabs

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>
  );
}

Add description for `Animated.addWhitelistedNativeProps`

Feature Request

It would be nice to explicitly add some information for
Animated.addWhitelistedNativeProps

Why it is needed

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!

Flashy: Custom icon component error

Here I am again :)

Bug

When I try to use a custom icon component, it simply gives me this error.

CleanShot 2020-06-13 at 23 53 08

Environment info

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

Steps To Reproduce

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:

  1. I would like to use custom icon component for flashy preset.

Bubble Preset effect animated transition

Feature Request

Why it is needed

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.

tabBarVisible not working

Bug

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

Environment info

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

Feature image

Feature Request

image

Why it is needed

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.

Icon animation

Feature Request

Why it is needed

In order to give a little dynamism to everything.

Check the render method of BubbleTabItemComponent

Bug

Schermata 2020-11-18 alle 16 29 34

Schermata 2020-11-18 alle 16 35 10

Environment info

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

Reproducible sample code

@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;

Future features

Feature Request

Hi @gorhom ,
I looked around it would be interesting to be able to have a complete module with the following features:

  • Image
    image

  • Shifting Tab Link


  • Full Tab


  • Icon Tab


  • Effect animated transition Link


JS version

Question

Hi, thanks for creating this. Could you provide a working JS example? I'm trying to convert but having problems left right centre!

Long press activates an effect

Feature Request

Linkedin:

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.

Why it is needed

To give a little originality to everything.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.