Bottom tab navigator following iOS design guidelines for React Navigation
—
Utility functions and React hooks for accessing tab bar dimensions, managing contexts, and integrating with the tab navigation system.
Access the current height of the bottom tab bar for layout calculations and positioning.
/**
* Hook to get the current height of the bottom tab bar.
* Must be used within a Bottom Tab Navigator.
* @returns The height of the tab bar in pixels
* @throws Error if used outside of a Bottom Tab Navigator
*/
function useBottomTabBarHeight(): number;Usage Examples:
import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs";
import { View, Text, StyleSheet } from "react-native";
function ScreenContent() {
const tabBarHeight = useBottomTabBarHeight();
return (
<View style={[styles.container, { paddingBottom: tabBarHeight }]}>
<Text>Content with proper tab bar spacing</Text>
<Text>Tab bar height: {tabBarHeight}px</Text>
</View>
);
}
// Usage with absolute positioned elements
function FloatingButton() {
const tabBarHeight = useBottomTabBarHeight();
return (
<TouchableOpacity
style={[
styles.floatingButton,
{ bottom: tabBarHeight + 20 }
]}
>
<Text>Floating Action</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
floatingButton: {
position: 'absolute',
right: 20,
backgroundColor: 'blue',
padding: 15,
borderRadius: 30,
},
});React context that provides the bottom tab bar height value.
/**
* React context that provides the bottom tab bar height.
* The value is undefined when not within a Bottom Tab Navigator.
*/
const BottomTabBarHeightContext: React.Context<number | undefined>;Usage Examples:
import React from 'react';
import { BottomTabBarHeightContext } from "@react-navigation/bottom-tabs";
function CustomComponent() {
const tabBarHeight = React.useContext(BottomTabBarHeightContext);
if (tabBarHeight === undefined) {
return <Text>Not in a tab navigator</Text>;
}
return (
<View style={{ paddingBottom: tabBarHeight }}>
<Text>Custom component with tab bar awareness</Text>
</View>
);
}
// Higher-order component usage
function withTabBarHeight<P extends object>(
Component: React.ComponentType<P & { tabBarHeight?: number }>
) {
return function WrappedComponent(props: P) {
const tabBarHeight = React.useContext(BottomTabBarHeightContext);
return <Component {...props} tabBarHeight={tabBarHeight} />;
};
}
const EnhancedComponent = withTabBarHeight(MyComponent);React context that provides a callback function to update the tab bar height.
/**
* React context that provides a callback to update the tab bar height.
* Used internally by the tab bar component to notify height changes.
* The value is undefined when not within a Bottom Tab Navigator.
*/
const BottomTabBarHeightCallbackContext: React.Context<
((height: number) => void) | undefined
>;Usage Examples:
import React from 'react';
import { BottomTabBarHeightCallbackContext } from "@react-navigation/bottom-tabs";
function CustomTabBar({ children }) {
const setTabBarHeight = React.useContext(BottomTabBarHeightCallbackContext);
const [height, setHeight] = React.useState(0);
const onLayout = (event) => {
const { height: measuredHeight } = event.nativeEvent.layout;
setHeight(measuredHeight);
// Notify the context about height changes
if (setTabBarHeight) {
setTabBarHeight(measuredHeight);
}
};
return (
<View onLayout={onLayout}>
{children}
<Text>Tab bar height: {height}</Text>
</View>
);
}The main view component that renders tab content and manages screen transitions.
interface BottomTabViewProps {
state: TabNavigationState<ParamListBase>;
navigation: NavigationHelpers<ParamListBase, BottomTabNavigationEventMap>;
descriptors: BottomTabDescriptorMap;
tabBar?: (props: BottomTabBarProps) => React.ReactNode;
safeAreaInsets?: {
top?: number;
right?: number;
bottom?: number;
left?: number;
};
detachInactiveScreens?: boolean;
}
const BottomTabView: React.ComponentType<BottomTabViewProps>;Usage Examples:
import { BottomTabView } from "@react-navigation/bottom-tabs";
function CustomNavigator(props) {
// Custom tab bar component
const renderTabBar = (tabBarProps) => (
<CustomTabBar {...tabBarProps} />
);
return (
<BottomTabView
{...props}
tabBar={renderTabBar}
safeAreaInsets={{ bottom: 20 }}
detachInactiveScreens={true}
/>
);
}Access navigation helpers for programmatic navigation within the tab system.
interface BottomTabNavigationHelpers extends NavigationHelpers<
ParamListBase,
BottomTabNavigationEventMap
>, TabActionHelpers<ParamListBase> {
/**
* Navigate to a tab
*/
navigate<RouteName extends keyof ParamListBase>(
name: RouteName,
params?: ParamListBase[RouteName]
): void;
/**
* Jump to a tab
*/
jumpTo<RouteName extends keyof ParamListBase>(
name: RouteName,
params?: ParamListBase[RouteName]
): void;
/**
* Emit a navigation event
*/
emit<EventName extends keyof BottomTabNavigationEventMap>(
event: EventName,
data?: BottomTabNavigationEventMap[EventName]['data']
): void;
}Usage Examples:
function NavigationUtility({ navigation }) {
const handleTabPress = (tabName) => {
// Emit custom event before navigation
navigation.emit('tabPress', undefined);
// Navigate to tab
navigation.jumpTo(tabName);
};
return (
<View>
<Button
title="Go to Home"
onPress={() => handleTabPress('Home')}
/>
</View>
);
}Helper types for working with bottom tab navigation TypeScript integration.
/**
* Extract screen props type for a specific route
*/
type BottomTabScreenProps<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = keyof ParamList,
NavigatorID extends string | undefined = undefined
> = {
navigation: BottomTabNavigationProp<ParamList, RouteName, NavigatorID>;
route: RouteProp<ParamList, RouteName>;
};
/**
* Extract navigation prop type for a specific route
*/
type BottomTabNavigationProp<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = keyof ParamList,
NavigatorID extends string | undefined = undefined
> = NavigationProp<
ParamList,
RouteName,
NavigatorID,
TabNavigationState<ParamList>,
BottomTabNavigationOptions,
BottomTabNavigationEventMap
> & TabActionHelpers<ParamList>;
/**
* Options arguments for screen configuration functions
*/
type BottomTabOptionsArgs<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = keyof ParamList,
NavigatorID extends string | undefined = undefined
> = BottomTabScreenProps<ParamList, RouteName, NavigatorID> & {
theme: Theme;
};Usage Examples:
// Define your param list
type RootTabParamList = {
Home: undefined;
Profile: { userId: string };
Settings: { section?: string };
};
// Use type utilities for component props
type HomeScreenProps = BottomTabScreenProps<RootTabParamList, 'Home'>;
type ProfileScreenProps = BottomTabScreenProps<RootTabParamList, 'Profile'>;
function HomeScreen({ navigation, route }: HomeScreenProps) {
// navigation and route are properly typed
return <View />;
}
function ProfileScreen({ navigation, route }: ProfileScreenProps) {
// route.params is typed as { userId: string }
const { userId } = route.params;
return <View />;
}
// Navigation prop type for use in hooks or utilities
type HomeNavigationProp = BottomTabNavigationProp<RootTabParamList, 'Home'>;
function useHomeNavigation(): HomeNavigationProp {
return useNavigation<HomeNavigationProp>();
}Utilities for working with layout dimensions and safe areas.
/**
* Layout dimensions type
*/
type Layout = {
width: number;
height: number;
};
/**
* Safe area insets type for tab bar positioning
*/
interface SafeAreaInsets {
top: number;
right: number;
bottom: number;
left: number;
}Usage Examples:
import { useSafeAreaInsets } from 'react-native-safe-area-context';
function ResponsiveTabContent() {
const insets = useSafeAreaInsets();
const tabBarHeight = useBottomTabBarHeight();
const contentStyle = {
paddingTop: insets.top,
paddingBottom: Math.max(insets.bottom, tabBarHeight),
paddingLeft: insets.left,
paddingRight: insets.right,
};
return (
<ScrollView style={contentStyle}>
<Text>Responsive content with proper safe area handling</Text>
</ScrollView>
);
}type ParamListBase = Record<string, object | undefined>;
interface TabNavigationState<ParamList extends ParamListBase> extends Omit<NavigationState<ParamList>, 'history'> {
type: 'tab';
history: { type: 'route'; key: string; params?: object | undefined }[];
preloadedRouteKeys: string[];
}
interface NavigationState<ParamList extends ParamListBase = ParamListBase> {
key: string;
index: number;
routeNames: Extract<keyof ParamList, string>[];
history?: unknown[];
routes: NavigationRoute<ParamList, keyof ParamList>[];
type: string;
stale: false;
}
interface BottomTabDescriptorMap {
[key: string]: BottomTabDescriptor;
}
interface BottomTabDescriptor {
render(): React.ReactNode;
options: BottomTabNavigationOptions;
navigation: BottomTabNavigationProp<ParamListBase>;
route: RouteProp<ParamListBase>;
}Install with Tessl CLI
npx tessl i tessl/npm-react-navigation--bottom-tabs