Use useSafeAreaInsets() to dynamically calculate tab bar height and bottom padding instead of hardcoded values. This ensures the tab bar properly accounts for Android navigation buttons (Samsung) and iOS home indicator. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
101 lines
2.8 KiB
TypeScript
101 lines
2.8 KiB
TypeScript
import { Tabs } from 'expo-router';
|
|
import React from 'react';
|
|
import { Feather } from '@expo/vector-icons';
|
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
|
import { HapticTab } from '@/components/haptic-tab';
|
|
import { AppColors } from '@/constants/theme';
|
|
import { useColorScheme } from '@/hooks/use-color-scheme';
|
|
|
|
export default function TabLayout() {
|
|
const colorScheme = useColorScheme();
|
|
const isDark = colorScheme === 'dark';
|
|
const insets = useSafeAreaInsets();
|
|
|
|
// Calculate tab bar height based on safe area
|
|
// On Android with navigation buttons (Samsung), insets.bottom is the nav bar height
|
|
// On iOS with home indicator, insets.bottom is ~34px
|
|
// Minimum padding of 10px for devices without safe area
|
|
const bottomPadding = Math.max(insets.bottom, 10);
|
|
const tabBarHeight = 60 + bottomPadding; // 60px for content + safe area padding
|
|
|
|
return (
|
|
<Tabs
|
|
screenOptions={{
|
|
tabBarActiveTintColor: AppColors.primary,
|
|
tabBarInactiveTintColor: isDark ? '#9BA1A6' : '#687076',
|
|
tabBarStyle: {
|
|
backgroundColor: isDark ? '#151718' : AppColors.background,
|
|
borderTopColor: isDark ? '#2D3135' : AppColors.border,
|
|
height: tabBarHeight,
|
|
paddingBottom: bottomPadding,
|
|
paddingTop: 10,
|
|
},
|
|
tabBarLabelStyle: {
|
|
fontSize: 11,
|
|
fontWeight: '500',
|
|
},
|
|
headerShown: false,
|
|
tabBarButton: HapticTab,
|
|
}}
|
|
>
|
|
<Tabs.Screen
|
|
name="index"
|
|
options={{
|
|
title: 'Dashboard',
|
|
tabBarIcon: ({ color, size }) => (
|
|
<Feather name="grid" size={22} color={color} />
|
|
),
|
|
}}
|
|
/>
|
|
{/* Hide old dashboard - now index shows WebView dashboard */}
|
|
<Tabs.Screen
|
|
name="dashboard"
|
|
options={{
|
|
href: null,
|
|
}}
|
|
/>
|
|
{/* Chat with Julia AI */}
|
|
<Tabs.Screen
|
|
name="chat"
|
|
options={{
|
|
title: 'Julia',
|
|
tabBarIcon: ({ color, size }) => (
|
|
<Feather name="message-circle" size={22} color={color} />
|
|
),
|
|
}}
|
|
/>
|
|
{/* Voice tab - HIDDEN (calls go through Julia tab chat screen) */}
|
|
<Tabs.Screen
|
|
name="voice"
|
|
options={{
|
|
href: null,
|
|
}}
|
|
/>
|
|
<Tabs.Screen
|
|
name="profile"
|
|
options={{
|
|
title: 'Profile',
|
|
tabBarIcon: ({ color, size }) => (
|
|
<Feather name="user" size={22} color={color} />
|
|
),
|
|
}}
|
|
/>
|
|
{/* Hide explore tab */}
|
|
<Tabs.Screen
|
|
name="explore"
|
|
options={{
|
|
href: null,
|
|
}}
|
|
/>
|
|
{/* Beneficiaries - hidden from tab bar but keeps tab bar visible */}
|
|
<Tabs.Screen
|
|
name="beneficiaries"
|
|
options={{
|
|
href: null,
|
|
}}
|
|
/>
|
|
</Tabs>
|
|
);
|
|
}
|