React Native Bottom Tabs with Native Components

Description:

React Native Bottom Tabs is a UI component that provides bottom tab navigation using native platform components.

The component supports iOS, Android, iPadOS, visionOS, tvOS, and macOS with automatic adaptation to each platform’s navigation patterns. It integrates with React Navigation as a drop-in replacement for JavaScript-based tabs.

Features

  • 🌐 Native Components: Uses SwiftUI TabView on Apple platforms and BottomNavigationView on Android.
  • 🔄 Platform Adaptation: Automatically adjusts tab placement for iPadOS, visionOS, tvOS, and macOS.
  • 🎬 System Animations: Tab transitions and scroll behaviors are handled by native platform APIs.
  • 📱 Haptic Feedback: Built-in tactile feedback for tab interactions on supported devices.
  • 🔄 Scroll Management: Automatic scroll-to-top behavior when tapping active tabs.
  • 🎯 Sidebar Conversion: Tabs transform into sidebar navigation on larger screens.
  • 🚫 PIP Avoidance: System automatically avoids picture-in-picture overlays.

See It In Action

Basic Usage

1. To start a new project with React Native Bottom Tabs, you can use the official template.

npx create-expo-app@latest NativeTabs --template @bottom-tabs/expo-template

2. For existing projects, install the necessary packages.

npm install react-native-bottom-tabs
npm install @bottom-tabs/react-navigation

3. If you are using Expo, add the plugin to your app.json file.

{
  "expo": {
    "plugins": ["react-native-bottom-tabs"]
  }
}

4. Here is a simple example of how to implement a tab view.

import * in React from 'react';
import { View, Text } from 'react-native';
import TabView, { SceneMap } from 'react-native-bottom-tabs';
const FirstScreen = () => (
  <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
    <Text>First Screen</Text>
  </View>
);
const SecondScreen = () => (
  <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
    <Text>Second Screen</Text>
  </View>
);
const renderScene = SceneMap({
  first: FirstScreen,
  second: SecondScreen,
});
export default function App() {
  const [index, setIndex] = React.useState(0);
  const [routes] = React.useState([
    { key: 'first', title: 'First', focusedIcon: { sfSymbol: 'star' } },
    { key: 'second', title: 'Second', focusedIcon: { sfSymbol: 'circle' } },
  ]);
  return (
    <TabView
      navigationState={{ index, routes }}
      renderScene={renderScene}
      onIndexChange={setIndex}
    />
  );
}

5. Available props.

  • navigationState: An object that holds the current state of the tab view. It must contain routes (an array of route objects) and index (the index of the currently active tab).
  • renderScene: A function responsible for rendering the component for the active tab.
  • onIndexChange: A callback function that is invoked whenever the user switches to a different tab.
  • labeled: A boolean that determines if text labels are shown below the tab icons. Defaults to true.
  • sidebarAdaptable: A boolean that allows the tab bar to automatically convert into a sidebar on platforms like iPadOS, macOS, and tvOS.
  • disablePageAnimations: A boolean to turn off animations when swiping between tabs.
  • hapticFeedbackEnabled: A boolean that enables haptic feedback when a tab is pressed. Defaults to false.
  • tabLabelStyle: A style object to customize the font family, size, and weight of the tab labels.
  • scrollEdgeAppearance: Defines the tab bar’s appearance when scrolled to the edge of the content. It can be default, opaque, or transparent.
  • minimizeBehavior: Controls how the tab bar reacts to scrolling on iOS 16+. Options include automatic, onScrollDown, onScrollUp, and never.
  • tabBarActiveTintColor: Sets the color for the icon and label of the active tab.
  • tabBarInactiveTintColor: Sets the color for the icons and labels of inactive tabs.
  • tabBarStyle: A style object for the tab bar, allowing you to set properties like backgroundColor.
  • translucent: A boolean that makes the tab bar semi-transparent.
  • activeIndicatorColor: Defines the color of the indicator on the active tab.

6. Route configurations. These properties are configured within each object in the routes array.

  • key: A unique string to identify the route.
  • title: The text displayed for the tab.
  • focusedIcon: The icon shown when the tab is active.
  • unfocusedIcon: The icon shown when the tab is inactive.
  • badge: Text to display in a notification badge on the tab.
  • activeTintColor: A specific active tint color for an individual tab.
  • lazy: A boolean to enable lazy loading for the tab’s content.
  • freezeOnBlur: A boolean that freezes a tab’s state when it is not focused.
  • role: Defines the tab’s purpose for accessibility.
  • style: A style object applied to the screen’s container.
  • preventsDefault: A boolean that stops the default tab-switching action when pressed.

7. These are functions that allow you to dynamically override default behaviors for individual tabs.

  • getLazy: Function to determine if a screen should be lazy-loaded.
  • getLabelText: Function to retrieve the label text for a tab.
  • getBadge: Function to get the badge text for a tab.
  • getActiveTintColor: Function to determine the active tint color for a tab.
  • getIcon: Function to get the icon for a tab.
  • getHidden: Function to determine if a tab should be hidden.
  • getTestID: Function to assign a test ID to a tab item.
  • getRole: Function to get the accessibility role for a tab item.
  • getSceneStyle: Function to get the style for a tab’s scene.
  • getPreventsDefault: Function to determine if a tab should prevent the default switch behavior.

Related Resources

  • React Navigation: The official documentation for the most popular navigation library in React Native.
  • React Native: The official website for the React Native framework.

FAQs

Q: How does this differ from React Navigation’s bottom tabs?
A: React Navigation uses JavaScript implementations while this library uses native platform components. The native approach provides system animations, automatic platform adaptation, and better performance.

Q: Which platforms support sidebar conversion?
A: iPadOS, tvOS, and macOS automatically convert bottom tabs to sidebar navigation. This occurs when using the sidebarAdaptable prop on larger screen devices.

Q: Can I use custom icons in the tab bar?
A: The library supports SF Symbols on Apple platforms and icon resources on Android. Custom React components are not supported in the native tab bar.

Q: Does this work with Expo?
A: The library works in Expo development builds but not in Expo Go. You must add the plugin to app.json and create a new build.

Q: How do I add haptic feedback to tab presses?
A: Enable the hapticFeedbackEnabled prop. The library handles the appropriate feedback type for each platform automatically.

Add Comment