Cross-platform Tab View component for React Native applications with swipeable, scrollable tab interfaces and smooth animations
—
The TabBar component is the default tab bar implementation that provides scrollable tabs with an animated indicator. It handles tab press events, supports customization of colors and styling, and provides accessibility features.
Default tab bar component with scrollable tabs, animated indicator, and comprehensive customization options.
/**
* Default TabBar component for rendering tab navigation
* @param props - TabBar configuration and styling options
* @returns JSX element containing the tab bar interface
*/
function TabBar<T extends Route>(props: Props<T>): JSX.Element;
interface Props<T extends Route> extends SceneRendererProps {
/** Required navigation state */
navigationState: NavigationState<T>;
/** Enable horizontal scrolling when tabs exceed container width */
scrollEnabled?: boolean;
/** Enable bouncing effect on scroll (iOS) */
bounces?: boolean;
/** Active tab text color */
activeColor?: string;
/** Inactive tab text color */
inactiveColor?: string;
/** Tab press ripple color (Android) */
pressColor?: string;
/** Tab press opacity effect */
pressOpacity?: number;
/** Per-route tab configuration options */
options?: Record<string, TabDescriptor<T>>;
/** Custom indicator renderer */
renderIndicator?: (props: IndicatorProps<T>) => React.ReactNode;
/** Custom tab item renderer */
renderTabBarItem?: (props: TabBarItemProps<T> & { key: string }) => React.ReactElement;
/** Tab press event handler */
onTabPress?: (scene: Scene<T> & Event) => void;
/** Tab long press event handler */
onTabLongPress?: (scene: Scene<T>) => void;
/** Individual tab styling */
tabStyle?: StyleProp<ViewStyle>;
/** Indicator styling */
indicatorStyle?: StyleProp<ViewStyle>;
/** Indicator container styling */
indicatorContainerStyle?: StyleProp<ViewStyle>;
/** Content container styling */
contentContainerStyle?: StyleProp<ViewStyle>;
/** Tab bar container styling */
style?: StyleProp<ViewStyle>;
/** Text direction - 'ltr' or 'rtl' */
direction?: LocaleDirection;
/** Space between tabs in pixels */
gap?: number;
/** Test identifier */
testID?: string;
/** Android ripple configuration */
android_ripple?: PressableAndroidRippleConfig;
}Usage Examples:
import React, { useState } from 'react';
import { TabView, TabBar, NavigationState, Route } from 'react-native-tab-view';
// Basic custom TabBar
const BasicTabBarExample = () => {
const [index, setIndex] = useState(0);
const [routes] = useState([
{ key: 'home', title: 'Home' },
{ key: 'profile', title: 'Profile' },
]);
const renderTabBar = (props) => (
<TabBar
{...props}
activeColor="#ffffff"
inactiveColor="#cccccc"
style={{ backgroundColor: '#2196f3' }}
indicatorStyle={{ backgroundColor: '#ffeb3b' }}
/>
);
return (
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
renderTabBar={renderTabBar}
onIndexChange={setIndex}
/>
);
};
// Advanced TabBar with custom styling and events
const AdvancedTabBarExample = () => {
const [index, setIndex] = useState(0);
const [routes] = useState([
{ key: 'feed', title: 'Feed' },
{ key: 'search', title: 'Search' },
{ key: 'notifications', title: 'Notifications' },
{ key: 'profile', title: 'Profile' },
]);
const handleTabPress = (scene) => {
console.log('Tab pressed:', scene.route.key);
// Can prevent default navigation by calling scene.preventDefault()
};
const renderTabBar = (props) => (
<TabBar
{...props}
scrollEnabled
activeColor="#1976d2"
inactiveColor="#757575"
pressColor="#e3f2fd"
pressOpacity={0.8}
onTabPress={handleTabPress}
gap={16}
style={{
backgroundColor: '#ffffff',
elevation: 4,
shadowOpacity: 0.1,
}}
tabStyle={{
minWidth: 120,
}}
indicatorStyle={{
backgroundColor: '#2196f3',
height: 3,
}}
contentContainerStyle={{
paddingHorizontal: 16,
}}
/>
);
return (
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
renderTabBar={renderTabBar}
onIndexChange={setIndex}
/>
);
};The TabBar includes an animated indicator that shows the active tab position.
/**
* Props for the TabBarIndicator component
*/
interface IndicatorProps<T extends Route> extends SceneRendererProps {
/** Navigation state */
navigationState: NavigationState<T>;
/** Indicator width configuration */
width: 'auto' | `${number}%` | number;
/** Function to get tab width by index */
getTabWidth: (index: number) => number;
/** Text direction */
direction: LocaleDirection;
/** Indicator styling */
style?: StyleProp<ViewStyle>;
/** Space between tabs */
gap?: number;
/** Child components */
children?: React.ReactNode;
}Individual tab rendering with support for labels, icons, and badges.
/**
* Props for individual TabBarItem components
*/
interface TabBarItemProps<T extends Route> extends TabDescriptor<T> {
/** Animated position value */
position: Animated.AnimatedInterpolation<number>;
/** Route object */
route: T;
/** Navigation state */
navigationState: NavigationState<T>;
/** Active tab color */
activeColor?: string;
/** Inactive tab color */
inactiveColor?: string;
/** Press ripple color */
pressColor?: string;
/** Press opacity effect */
pressOpacity?: number;
/** Layout event handler */
onLayout?: (event: LayoutChangeEvent) => void;
/** Press event handler */
onPress: () => void;
/** Long press event handler */
onLongPress: () => void;
/** Default tab width */
defaultTabWidth?: number;
/** Tab styling */
style: StyleProp<ViewStyle>;
/** Android ripple configuration */
android_ripple?: PressableAndroidRippleConfig;
}TabBar supports extensive customization through styling and render functions.
/**
* TabDescriptor interface for tab configuration
*/
interface TabDescriptor<T extends Route> {
/** Override accessibility label */
accessibilityLabel?: string;
/** Override accessibility enabled flag */
accessible?: boolean;
/** Test identifier */
testID?: string;
/** Override tab label text */
labelText?: string;
/** Allow font scaling */
labelAllowFontScaling?: boolean;
/** Web navigation href */
href?: string;
/** Custom label renderer */
label?: (props: {
route: T;
labelText?: string;
focused: boolean;
color: string;
allowFontScaling?: boolean;
style?: StyleProp<TextStyle>;
}) => React.ReactNode;
/** Label text styling */
labelStyle?: StyleProp<TextStyle>;
/** Custom icon renderer */
icon?: (props: {
route: T;
focused: boolean;
color: string;
size: number;
}) => React.ReactNode;
/** Custom badge renderer */
badge?: (props: { route: T }) => React.ReactElement;
/** Scene container styling */
sceneStyle?: StyleProp<ViewStyle>;
}Custom Rendering Examples:
// Custom tab with icon and badge
const renderTabBar = (props) => (
<TabBar
{...props}
renderTabBarItem={({ route, ...itemProps }) => (
<TabBarItem
{...itemProps}
route={route}
icon={({ focused, color }) => (
<Icon
name={getIconName(route.key)}
color={color}
size={24}
/>
)}
badge={({ route }) =>
getBadgeCount(route.key) > 0 ? (
<Badge count={getBadgeCount(route.key)} />
) : null
}
/>
)}
/>
);
// Custom indicator
const renderTabBar = (props) => (
<TabBar
{...props}
renderIndicator={(indicatorProps) => (
<TabBarIndicator
{...indicatorProps}
style={{ backgroundColor: 'red', height: 4 }}
/>
)}
/>
);Handle tab interactions with custom logic and event prevention.
/**
* Event object for tab press interactions
*/
interface Event {
/** Whether default navigation has been prevented */
defaultPrevented: boolean;
/** Function to prevent default navigation */
preventDefault(): void;
}
/**
* Scene context for event handlers
*/
interface Scene<T extends Route> {
/** The route being interacted with */
route: T;
}Event Handling Examples:
const handleTabPress = (scene: Scene<Route> & Event) => {
// Custom logic before navigation
if (scene.route.key === 'protected' && !isAuthenticated) {
scene.preventDefault();
showLoginModal();
return;
}
// Allow default navigation
console.log('Navigating to:', scene.route.key);
};
const renderTabBar = (props) => (
<TabBar
{...props}
onTabPress={handleTabPress}
onTabLongPress={(scene) => {
showTabContextMenu(scene.route);
}}
/>
);TabBar provides comprehensive accessibility support.
/**
* Accessibility configuration through TabDescriptor
*/
interface AccessibilityProps {
/** Whether the tab is accessible */
accessible?: boolean;
/** Accessibility label for screen readers */
accessibilityLabel?: string;
/** Test identifier for automated testing */
testID?: string;
/** Allow font scaling for better accessibility */
labelAllowFontScaling?: boolean;
}Control TabBar appearance through comprehensive styling options.
/**
* Layout and styling interfaces
*/
interface StyleProps {
/** Main tab bar container style */
style?: StyleProp<ViewStyle>;
/** Individual tab styling */
tabStyle?: StyleProp<ViewStyle>;
/** Content container styling */
contentContainerStyle?: StyleProp<ViewStyle>;
/** Indicator styling */
indicatorStyle?: StyleProp<ViewStyle>;
/** Indicator container styling */
indicatorContainerStyle?: StyleProp<ViewStyle>;
}
/**
* Android-specific ripple configuration
*/
interface PressableAndroidRippleConfig {
/** Ripple color */
color?: string;
/** Whether ripple extends beyond bounds */
borderless?: boolean;
/** Ripple radius */
radius?: number;
}Install with Tessl CLI
npx tessl i tessl/npm-react-native-tab-view