import type { BottomTabNavigationOptions } from '@react-navigation/bottom-tabs'; import { GlassContainer, GlassView, isLiquidGlassAvailable } from 'expo-glass-effect'; import * as Haptics from 'expo-haptics'; import { Tabs, usePathname } from 'expo-router'; import React from 'react'; import { Text, TouchableOpacity, View, ViewStyle } from 'react-native'; import { IconSymbol } from '@/components/ui/IconSymbol'; import { Colors } from '@/constants/Colors'; import { ROUTES } from '@/constants/Routes'; import { TAB_BAR_BOTTOM_OFFSET, TAB_BAR_HEIGHT } from '@/constants/TabBar'; import { useColorScheme } from '@/hooks/useColorScheme'; // Tab configuration type TabConfig = { icon: string; title: string; }; const TAB_CONFIGS: Record = { statistics: { icon: 'chart.pie.fill', title: '健康' }, // explore: { icon: 'magnifyingglass.circle.fill', title: '发现' }, goals: { icon: 'flag.fill', title: '习惯' }, personal: { icon: 'person.fill', title: '个人' }, }; export default function TabLayout() { const theme = (useColorScheme() ?? 'light') as 'light' | 'dark'; const colorTokens = Colors[theme]; const pathname = usePathname(); const glassEffectAvailable = isLiquidGlassAvailable(); // Helper function to determine if a tab is selected const isTabSelected = (routeName: string): boolean => { const routeMap: Record = { explore: ROUTES.TAB_EXPLORE, goals: ROUTES.TAB_GOALS, statistics: ROUTES.TAB_STATISTICS, }; return routeMap[routeName] === pathname || pathname.includes(routeName); }; // Custom tab button component const createTabButton = (routeName: string) => (props: any) => { const { onPress } = props; const tabConfig = TAB_CONFIGS[routeName]; if (!tabConfig) return null; const isSelected = isTabSelected(routeName); const handlePress = (event: any) => { if (process.env.EXPO_OS === 'ios') { Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); } onPress?.(event); }; return ( {isSelected && ( {tabConfig.title} )} ); }; // Custom tab bar background component const TabBarBackground = () => { if (glassEffectAvailable) { return ( ); } return null; }; // Common screen options const getScreenOptions = (routeName: string): BottomTabNavigationOptions => ({ headerShown: false, tabBarActiveTintColor: colorTokens.tabIconSelected, tabBarButton: createTabButton(routeName), tabBarBackground: TabBarBackground, tabBarStyle: { position: 'absolute', bottom: TAB_BAR_BOTTOM_OFFSET, height: TAB_BAR_HEIGHT, borderRadius: 34, backgroundColor: glassEffectAvailable ? 'transparent' : colorTokens.tabBarBackground, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: glassEffectAvailable ? 0.1 : 0.2, shadowRadius: 10, elevation: 5, paddingHorizontal: 10, paddingTop: 0, paddingBottom: 0, marginHorizontal: 20, left: 20, right: 20, alignSelf: 'center', borderWidth: glassEffectAvailable ? 1 : 0, borderColor: glassEffectAvailable ? (theme === 'dark' ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)') : 'transparent', } as ViewStyle, tabBarItemStyle: { backgroundColor: 'transparent', height: TAB_BAR_HEIGHT, marginTop: 0, marginBottom: 0, paddingTop: 0, paddingBottom: 0, }, tabBarShowLabel: false, }); return ( getScreenOptions(route.name)} > ); }