Skip to main content

createBottomTabNavigator

A simple tab bar on the bottom of the screen that lets you switch between different routes.

Submit feedback
github
import { createBottomTabNavigator } from '@uhg-abyss/mobile';

The most common style of navigation in mobile apps is tab-based navigation. A simple tab bar on the bottom of the screen lets you switch between different routes. Routes are lazily initialized -- their screen components are not mounted until they are first focused.

Calling the createBottomTabNavigator function creates a Tab object with Screen & Navigator properties. All tab screen must be wrapped around a Tab.Navigator object component. All screens must have a name and component passed in as props.

Example

const Tab = createBottomTabNavigator();
const Screen = ({ route }) => {
return (
<ScreenWrapper>
<Text>This is the {route.name} page</Text>
</ScreenWrapper>
);
};
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator initialRouteName="Home">
<Tab.Screen
name="Home"
component={Screen}
options={{
tabBarIcon: ({ active }) => (
<IconCustom
icon="home"
variant={active ? 'darkactive' : 'dark'}
maxFontSizeMultiplier={1.3}
/>
),
}}
/>
<Tab.Screen
name="My Plan"
component={Screen}
options={{
tabBarIcon: ({ active }) => (
<IconCustom
icon="my_plan"
variant={active ? 'darkactive' : 'dark'}
maxFontSizeMultiplier={1.3}
/>
),
}}
/>
<Tab.Screen
name="Find Care"
component={Screen}
options={{
tabBarIcon: ({ active }) => (
<IconCustom
icon="find_care"
variant={active ? 'darkactive' : 'dark'}
maxFontSizeMultiplier={1.3}
/>
),
}}
/>
<Tab.Screen
name="Menu"
component={Screen}
options={{
tabBarIcon: ({ active }) => (
<IconCustom
icon="menu"
variant={active ? 'darkactive' : 'dark'}
maxFontSizeMultiplier={1.3}
/>
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
() => {
const [page, setPage] = useState('home');
const Container = styled('View', {
flexGrow: 1,
});
const Header = styled('View', {
backgroundColor: '$app-bar.color.surface.container',
width: '100%',
paddingTop: 30,
});
const HeaderContent = styled('View', {
margin: '$semantic.spacing.sm',
flexDirection: 'row',
justifyContent: 'center',
});
const Title = styled('Text', {
color: '$app-bar.color.text.heading',
typography: '$semantic.typography.h.xxs-bold',
textTransform: 'capitalize',
});
const ContentArea = styled('View', {
flexGrow: 1,
alignItems: 'center',
justifyContent: 'center',
});
const TabBar = styled('View', {
backgroundColor: '$tab-bar.color.surface.container',
display: 'flex',
color: '$tab-bar.color.text.label.default',
paddingBottom: 24,
paddingTop: 8,
flexDirection: 'row',
borderTopLeftRadius: 12,
borderTopRightRadius: 12,
});
const TabBarItem = styled('Pressable', {
flex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
});
const ContentText = styled('Text', {});
const TabLabel = styled('Text', {
typography: '$semantic.typography.p.xs-med',
color: '$tab-bar.color.text.label.default',
variants: {
active: {
true: { fontWeight: '$core.font-weight.bold' },
},
},
});
return (
<Container>
<Header>
<HeaderContent>
<Title>{page.split('_').join(' ')}</Title>
</HeaderContent>
</Header>
<ContentArea>
{page === 'home' && <ContentText>This is the Home page</ContentText>}
{page === 'my_plan' && (
<ContentText>This is the My Plan page</ContentText>
)}
{page === 'find_care' && (
<ContentText>This is the Find Care page</ContentText>
)}
{page === 'menu' && <ContentText>This is the Menu page</ContentText>}
</ContentArea>
<TabBar>
<TabBarItem
role="button"
aria-current={page === 'home' ? 'page' : false}
onPressIn={() => setPage('home')}
>
{({ pressed }) => {
const active = page === 'home';
return (
<>
<IconCustom
icon="home"
variant={`dark${pressed || active ? 'active' : ''}`}
/>
<TabLabel active={active}>Home</TabLabel>
</>
);
}}
</TabBarItem>
<TabBarItem
role="button"
aria-current={page === 'my_plan' ? 'page' : false}
onPressIn={() => setPage('my_plan')}
>
{({ pressed }) => {
const active = page === 'my_plan';
return (
<>
<IconCustom
icon="my_plan"
variant={`dark${pressed || active ? 'active' : ''}`}
/>
<TabLabel active={active}>My Plan</TabLabel>
</>
);
}}
</TabBarItem>
<TabBarItem
role="button"
aria-current={page === 'find_care' ? 'page' : false}
onPressIn={() => setPage('find_care')}
>
{({ pressed }) => {
const active = page === 'find_care';
return (
<>
<IconCustom
icon="find_care"
variant={`dark${pressed || active ? 'active' : ''}`}
/>
<TabLabel active={active}>Find Care</TabLabel>
</>
);
}}
</TabBarItem>
<TabBarItem
role="button"
aria-current={page === 'menu' ? 'page' : false}
onPressIn={() => setPage('menu')}
>
{({ pressed }) => {
const active = page === 'menu';
return (
<>
<IconCustom
icon="menu"
variant={`dark${pressed || active ? 'active' : ''}`}
/>
<TabLabel active={active}>Menu</TabLabel>
</>
);
}}
</TabBarItem>
</TabBar>
</Container>
);
};

Props

The Tab.Navigator component accepts following props:

id

Optional unique ID for the navigator. This can be used with navigation.getParent to refer to this navigator in a child navigator.

initialRouteName

The name of the route to render on first load of the navigator.

screenOptions

Default options to use for the screens in the navigator.

backBehavior

This controls what happens when goBack is called in the navigator. This includes pressing the device's back button or back gesture on Android.

It supports the following values:

  • firstRoute - return to the first screen defined in the navigator (default)
  • initialRoute - return to initial screen passed in initialRouteName prop, if not passed, defaults to the first screen
  • order - return to screen defined before the focused screen
  • history - return to last visited screen in the navigator; if the same screen is visited multiple times, the older entries are dropped from the history
  • none - do not handle back button

detachInactiveScreens

Boolean used to indicate whether inactive screens should be detached from the view hierarchy to save memory. This enables integration with react-native-screens. Defaults to true.

sceneContainerStyle

Style object for the component wrapping the screen content.

tabBar

Function that returns a React element to display as the tab bar.

Note that you cannot use the useNavigation hook inside the tabBar since useNavigation is only available inside screens. You get a navigation prop for your tabBar which you can use instead:

Options

The following options can be used to configure the screens in the navigator. These can be specified under screenOptions prop of Tab.navigator or options prop of Tab.Screen.

title

Generic title that can be used as a fallback for headerTitle and tabBarLabel.

tabBarLabel

Title string of a tab displayed in the tab bar or a function that given { active: boolean, color: string } returns a React.Node, to display in tab bar. When undefined, scene title is used. To hide, see tabBarShowLabel.

tabBarShowLabel

Whether the tab label should be visible. Defaults to true.

tabBarLabelPosition

Whether the label is shown below the icon or beside the icon.

  • below-icon: the label is shown below the icon (typical for iPhones)
  • beside-icon the label is shown next to the icon (typical for iPad)

By default, the position is chosen automatically based on device width.

tabBarLabelStyle

Style object for the tab label.

tabBarIcon

React.ReactNode or a function that given { active: boolean } returns a React.ReactNode, to display in the tab bar.

showTabBarBadge

Whether or not the badge should be visible on the tab icon.

showTabBarBadgeOnActive

Whether or not the badge should be visible on the tab icon when it is active.

tabBarBadgeLabel

Text to show in a badge on the tab icon. Accepts a string or a number.

tabBarBadgeOffset

Offset for the badge on the tab icon.

tabBarAccessibilityLabel

Accessibility label for the tab button. This is read by the screen reader when the user taps the tab. It's recommended to set this if you don't have a label for the tab.

tabBarTestID

ID to locate this tab button in tests.

tabBarActiveTintColor

Color for the icon and label in the active tab.

tabBarInactiveTintColor

Color for the icon and label in the inactive tabs.

tabBarActiveBackgroundColor

Background color for the active tab.

tabBarInactiveBackgroundColor

Background color for the inactive tabs.

tabBarActiveLabelWeight

Font weight for the label in the active tab.

tabBarInactiveLabelWeight

Font weight for the label in the inactive tabs.

tabBarItemStyle

Style object for the tab item container.

tabBarStyle

Style object for the tab bar. You can configure styles such as background color here.

To show your screen under the tab bar, you can set the position style to absolute:

<Tab.Navigator
screenOptions={{
tabBarStyle: { position: 'absolute' },
}}
>

Dynamic Type

Text and icons scale to 3XL. Any additional text or icon passed in should set maxFontSizeMultiplier={1.3}.

Table of Contents