managarten/apps/picture/packages/mobile-ui/components/navigation/TabBarIcon
Wuesteon d36b321d9d style: auto-format codebase with Prettier
Applied formatting to 1487+ files using pnpm format:write
  - TypeScript/JavaScript files
  - Svelte components
  - Astro pages
  - JSON configs
  - Markdown docs

  13 files still need manual review (Astro JSX comments)
2025-11-27 18:33:16 +01:00
..
index.ts refactor: restructure 2025-11-26 03:03:24 +01:00
README.md refactor: restructure 2025-11-26 03:03:24 +01:00
TabBarIcon.tsx style: auto-format codebase with Prettier 2025-11-27 18:33:16 +01:00

TabBarIcon

Icon component optimized for tab bar usage.

Features

  • Optimized for tab bars
  • Optical alignment (negative margin)
  • Color and size customization
  • Focused state support
  • Cross-platform icons

Installation

npx @memoro/ui add tab-bar-icon

Dependencies: icon

Usage

Basic TabBarIcon

import { TabBarIcon } from '@/components/navigation/TabBarIcon';

<TabBarIcon
  name="home"
  color="#3B82F6"
/>

With Expo Router

import { Tabs } from 'expo-router';
import { TabBarIcon } from '@/components/navigation/TabBarIcon';

export default function TabLayout() {
  return (
    <Tabs
      screenOptions={{
        tabBarActiveTintColor: '#3B82F6',
      }}
    >
      <Tabs.Screen
        name="index"
        options={{
          title: 'Home',
          tabBarIcon: ({ color }) => <TabBarIcon name="home" color={color} />,
        }}
      />
      <Tabs.Screen
        name="profile"
        options={{
          title: 'Profile',
          tabBarIcon: ({ color }) => <TabBarIcon name="person" color={color} />,
        }}
      />
    </Tabs>
  );
}

With React Navigation

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { TabBarIcon } from '@/components/navigation/TabBarIcon';

const Tab = createBottomTabNavigator();

function MyTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen
        name="Home"
        component={HomeScreen}
        options={{
          tabBarIcon: ({ color, focused }) => (
            <TabBarIcon name="home" color={color} focused={focused} />
          ),
        }}
      />
      <Tab.Screen
        name="Settings"
        component={SettingsScreen}
        options={{
          tabBarIcon: ({ color, focused }) => (
            <TabBarIcon name="settings" color={color} focused={focused} />
          ),
        }}
      />
    </Tab.Navigator>
  );
}

Custom Size

<TabBarIcon
  name="heart"
  color="#EF4444"
  size={32}
/>

Focused/Unfocused Icons

<TabBarIcon
  name={focused ? 'heart' : 'heart-outline'}
  color={focused ? '#EF4444' : '#6B7280'}
  focused={focused}
/>

Props

Prop Type Default Description
name string - Required - Icon name
color string - Required - Icon color
size number 28 Icon size in pixels
focused boolean false Is the tab focused
style ViewStyle - Additional styles

Default Styling

  • Icon Size: 28px (standard tab bar size)
  • Margin Bottom: -3px (optical alignment)
  • Color: Passed from tab bar

Examples

Home Tab

<TabBarIcon
  name={focused ? 'home' : 'home-outline'}
  color={color}
  focused={focused}
/>

Search Tab

<TabBarIcon
  name={focused ? 'search' : 'search-outline'}
  color={color}
  focused={focused}
/>

Profile Tab

<TabBarIcon
  name={focused ? 'person' : 'person-outline'}
  color={color}
  focused={focused}
/>

Settings Tab

<TabBarIcon
  name={focused ? 'settings' : 'settings-outline'}
  color={color}
  focused={focused}
/>

Notifications Tab

<TabBarIcon
  name={focused ? 'notifications' : 'notifications-outline'}
  color={color}
  focused={focused}
/>

Cart Tab

<TabBarIcon
  name={focused ? 'cart' : 'cart-outline'}
  color={color}
  focused={focused}
/>

Messages Tab

<TabBarIcon
  name={focused ? 'chatbubble' : 'chatbubble-outline'}
  color={color}
  focused={focused}
/>

Full Tab Bar Example

import { Tabs } from 'expo-router';
import { TabBarIcon } from '@/components/navigation/TabBarIcon';

export default function TabLayout() {
  return (
    <Tabs
      screenOptions={{
        tabBarActiveTintColor: '#3B82F6',
        tabBarInactiveTintColor: '#6B7280',
        headerShown: false,
      }}
    >
      <Tabs.Screen
        name="index"
        options={{
          title: 'Home',
          tabBarIcon: ({ color, focused }) => (
            <TabBarIcon
              name={focused ? 'home' : 'home-outline'}
              color={color}
              focused={focused}
            />
          ),
        }}
      />
      <Tabs.Screen
        name="search"
        options={{
          title: 'Search',
          tabBarIcon: ({ color, focused }) => (
            <TabBarIcon
              name={focused ? 'search' : 'search-outline'}
              color={color}
              focused={focused}
            />
          ),
        }}
      />
      <Tabs.Screen
        name="favorites"
        options={{
          title: 'Favorites',
          tabBarIcon: ({ color, focused }) => (
            <TabBarIcon
              name={focused ? 'heart' : 'heart-outline'}
              color={color}
              focused={focused}
            />
          ),
        }}
      />
      <Tabs.Screen
        name="profile"
        options={{
          title: 'Profile',
          tabBarIcon: ({ color, focused }) => (
            <TabBarIcon
              name={focused ? 'person' : 'person-outline'}
              color={color}
              focused={focused}
            />
          ),
        }}
      />
    </Tabs>
  );
}

Icon Naming Pattern

For better UX, use filled icons when focused and outline variants when unfocused:

// Good
name={focused ? 'home' : 'home-outline'}

// Also good (if no outline variant exists)
name="home"

// Avoid (no visual difference)
name="home" // same for focused and unfocused

Common Icon Choices

Navigation

  • home / home-outline
  • compass / compass-outline
  • map / map-outline
  • location / location-outline

Content

  • grid / grid-outline
  • list / list-outline
  • images / images-outline
  • videocam / videocam-outline

Social

  • chatbubble / chatbubble-outline
  • notifications / notifications-outline
  • people / people-outline
  • mail / mail-outline

Shopping

  • cart / cart-outline
  • bag / bag-outline
  • pricetag / pricetag-outline
  • card / card-outline

Media

  • play-circle / play-circle-outline
  • musical-notes / musical-notes-outline
  • camera / camera-outline
  • mic / mic-outline

Utility

  • settings / settings-outline
  • bookmark / bookmark-outline
  • heart / heart-outline
  • star / star-outline

Optical Alignment

The default -3px bottom margin provides optical alignment for most tab bars. Adjust if needed:

<TabBarIcon
  name="home"
  color={color}
  style={{ marginBottom: -5 }} // Custom alignment
/>

Notes

  • Perfect for bottom tab navigation
  • Works with Expo Router and React Navigation
  • Use outline/filled variants for better UX
  • Default size (28px) matches standard tab bars
  • Negative margin provides optical centering
  • Color is typically provided by navigation library
  • Consider focused state for better visual feedback