8

I need to add an indicator for the active tab I tried to add a borderBottom with tabStyle but we can't check focused with that.

Using react-navigation v5 and createBottomTabNavigator for bottom tabs.

Here's the output image

Here's my code:

<BottomTab.Navigator
      tabBarOptions={{
        activeTintColor: colors.brown,
        labelPosition: 'below-icon',
      }}>
      <BottomTab.Screen
        name="Home"
        component={HomeTabNav}
        options={{
          tabBarLabel: 'Home',
          tabBarIcon: ({focused}) => {
            return focused ? (
              <HomeSelectedIcon height={ms(24)} width={ms(24)} />
            ) : (
              <HomeIcon height={ms(24)} width={ms(24)} />
            );
          },
        }}
      />
     ...
    </BottomTab.Navigator>
  );
};

Thanks in advance!

Rajendran Nadar
  • 4,962
  • 3
  • 30
  • 51
sakshya73
  • 5,570
  • 5
  • 22
  • 41

3 Answers3

7

I figured it out myself by making a custom tabbar icon if someone needs to achieve this using the bottom-tab bar only.

Here's the code.

<BottomTab.Navigator
      tabBarOptions={{
        activeTintColor: colors.brown,
        showLabel: false,
        tabStyle: styles.tabStyle,
        style: styles.tabContainerStyle,
      }}>
      <BottomTab.Screen
        name="Home"
        component={HomeTabNav}
        options={{
          tabBarLabel: 'Home',
          tabBarIcon: ({focused}) => {
            return focused ? (
              <View style={styles.labelFocusedContainer}>
                <HomeSelectedIcon height={24} width={24} />
                <Text style={styles.labelFocusedStyle}>Home</Text>
              </View>
            ) : (
              <View style={styles.labelContainer}>
                <HomeIcon height={24} width={24} />
                <Text style={styles.labelStyle}>Home</Text>
              </View>
            );
          },
        }}
      />
   ...
</BottomTab.Navigator>

const styles = StyleSheet.create({
  labelContainer: {
    alignItems: 'center',
    width: '100%',
  },
  labelFocusedContainer: {
    alignItems: 'center',
    width: '100%',
    borderBottomWidth: 3,
    borderBottomColor: colors.brown,
  },
  labelFocusedStyle: {
    textAlign: 'center',
    marginVertical: 8,
    color: colors.brown,
    backgroundColor: 'transparent',
    fontSize: 10,
  },
  labelStyle: {
    textAlign: 'center',
    marginVertical: 8,
    color: colors.veryDarkgray,
    backgroundColor: 'transparent',
    fontSize: 10,
  },
});


But the best and easy way to do this is by using createMaterialTopTabNavigator and using these props.

tabBarPosition="bottom"
      tabBarOptions={{
        showIcon: true,
        pressOpacity: 1,
        iconStyle: styles.iconStyle,
        showLabel: true,
        activeTintColor: colors.brown,
        indicatorStyle: {
          borderWidth: 2,
          borderColor: colors.brown,
        },
sakshya73
  • 5,570
  • 5
  • 22
  • 41
2

This does not seem to be possible / easily achievable with bottom-tabs, but you could use the material version - @react-navigation/material-top-tabs and configure it to match your needs, specifically using tabBarPosition="bottom" and tabBarOptions={{ indicatorStyle: { backgroundColor } }}.

You can check more options in the docs: https://reactnavigation.org/docs/material-top-tab-navigator/#tabbaroptions

import * as React from 'react';
import { Text, View } from 'react-native';

import { NavigationContainer } from '@react-navigation/native';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';

const Tabs = createMaterialTopTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Tabs.Navigator tabBarPosition="bottom" tabBarOptions={{ indicatorStyle: { backgroundColor: 'red' } }}>
        <Tabs.Screen name="screen 1" component={View} />
        <Tabs.Screen name="screen 2" component={View} />
      </Tabs.Navigator>
    </NavigationContainer>
  );
}
Marek Lisik
  • 2,003
  • 1
  • 8
  • 17
2

The best answer would be to use the tabBarButton prop to override and add your own custom styles to the container of the tab button.

https://reactnavigation.org/docs/bottom-tab-navigator#tabbarbutton

const CustomTabButton = (props) => (
    <Pressable
        {...props}
        style={
            props.accessibilityState.selected
                ? [props.style, styles.activeTab]
                : props.style
        }
    />
)

styles.activeTab is the custom style you want to add, be careful to spread the props.style to get the default styles from the library like width, padding, height etc

props.accessibilityState.selected will add styles according to condition if you want styles for all the tabs you can remove the condition.

Inside screeenOptions prop on navigator or the option props of each screen.

tabBarButton: CustomTabButton

Using material top tab is not a good solution because it does not support well with a keyboard. But bottom tabs do work well with the keyboard.

Rajendran Nadar
  • 4,962
  • 3
  • 30
  • 51