ExpoStartup

Tab Navigation

Tab Navigation implementation using Expo Router in the Expo Startup template

Tab Navigation

The Tab Navigation component provides a clean, animated bottom tab bar for navigating between the main sections of your app. It's built using Expo Router's Tab components with custom styling and animations.

Implementation

The tab navigation is implemented using two main components:

  1. (tabs)/_layout.tsx - Defines the tab bar structure
  2. TabButton.tsx - Custom tab button with animation and styling

Basic Usage

Here's a simple example of how to set up tab navigation with the custom TabButton component:

// In (tabs)/_layout.tsx
import { Tabs, TabList, TabTrigger, TabSlot } from 'expo-router/ui';
import { TabButton } from '@/components/TabButton';
 
export default function TabsLayout() {
  return (
    <Tabs>
      {/* This is where your screen content appears */}
      <TabSlot />
      
      {/* The bottom tab bar */}
      <TabList>
        <TabTrigger name="home" href="/" asChild>
          <TabButton icon="Home">Home</TabButton>
        </TabTrigger>
        
        <TabTrigger name="search" href="/search" asChild>
          <TabButton icon="Search">Search</TabButton>
        </TabTrigger>
        
        <TabTrigger name="profile" href="/profile" asChild>
          <TabButton icon="User">Profile</TabButton>
        </TabTrigger>
      </TabList>
    </Tabs>
  );
}

Features

  • Animated Labels - Tab labels fade in/out and animate position on selection
  • Indicator Line - Animated line shows the active tab
  • Icon Emphasis - Active tab has thicker stroke width for emphasis
  • Theme Support - Automatically adapts to light/dark mode
  • Custom Content - Support for custom content instead of the standard icon

Customization

Adding Animation to Labels

You can enable label animation for a smoother experience:

<TabTrigger name="home" href="/" asChild>
  <TabButton labelAnimated={true} icon="Home">Home</TabButton>
</TabTrigger>

Custom Tab Content

Instead of using an icon, you can provide custom content:

<TabTrigger name="profile" href="/profile" asChild>
  <TabButton customContent={
    <Avatar src="https://example.com/avatar.jpg" size="xxs" />
  }>
    Profile
  </TabButton>
</TabTrigger>

Drawer Navigation Integration

You can integrate a drawer toggle within your tab bar:

import { useDrawer } from '@/app/contexts/DrawerContext';
 
export default function Layout() {
  const { openDrawer } = useDrawer();
  
  // Add this to your TabList
  <TabButton icon="Menu" onPress={openDrawer}>
    Menu
  </TabButton>
}

Hidden Tab Items

You can hide tabs from the tab bar but keep them in navigation:

<TabTrigger name="hidden" href="/hidden" asChild style={{ display: 'none' }}>
  <TabButton icon="EyeOff">Hidden</TabButton>
</TabTrigger>

Best Practices

  1. Limit Tab Count - Keep to 5 or fewer tabs for best usability
  2. Consistent Icons - Use a cohesive icon set for all tabs
  3. Short Labels - Use short, clear labels (1-2 words maximum)
  4. Main Sections Only - Tabs should be used for top-level navigation only
  5. Responsive Design - Ensure tab bar works on various screen sizes
  6. Keyboard Handling - Enable tab bar to adjust when keyboard appears

On this page