expo-duooomi-app/app/(tabs)/_layout.tsx

67 lines
2.6 KiB
TypeScript

import React from 'react'
import { Tabs } from 'expo-router'
import { Text, Block } from '@share/components'
import { Colors } from '@/constants/theme'
import { Ionicons } from '@expo/vector-icons'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
interface BottomNavProps {
currentRoute: string
onRouteChange: (route: string) => void
theme?: 'light' | 'dark'
}
const navItems = [
{ id: 'index', label: '探索', iconName: 'compass-outline' },
{ id: 'generate', label: '生成', iconName: 'image-outline' },
{ id: 'sync', label: '同步', iconName: 'refresh' },
{ id: 'explore', label: '蓝牙调试', iconName: 'person-outline' },
]
function renderNavItem(item: (typeof navItems)[0], isActive: boolean, onRouteChange: (route: string) => void) {
const { id, label, iconName } = item
return (
<Block
key={id}
onClick={() => onRouteChange(id)}
className={`relative h-[48px] flex-1 flex-row items-center justify-center rounded-[9999px] ${isActive ? 'flex-[1.4]' : ''}`}
>
{isActive && <Block className="absolute inset-0 rounded-[9999px] border-[2px] border-black bg-accent shadow-[2px_2px_0px_rgba(0,0,0,1)]" />}
<Block className="relative z-[10] flex-row items-center justify-center gap-[4px]">
<Ionicons name={iconName as any} size={isActive ? 20 : 24} color={isActive ? Colors.light.text : '#9CA3AF'} />
{isActive && (
<Text className="text-[12px] font-[900] italic text-black" numberOfLines={1}>
{label}
</Text>
)}
</Block>
</Block>
)
}
export const BottomNav: React.FC<BottomNavProps> = ({ currentRoute, onRouteChange }) => {
const insets = useSafeAreaInsets()
return (
<Block className="absolute left-[16px] right-[16px] z-[50]" style={{ bottom: 24, paddingBottom: insets.bottom }}>
<Block className="relative flex-row items-center justify-between overflow-hidden rounded-[9999px] border-[3px] border-black bg-fg px-[8px] py-[8px] shadow-[5px_5px_0px_rgba(0,0,0,1)]">
{navItems.map((item) => renderNavItem(item, currentRoute === item.id, onRouteChange))}
</Block>
</Block>
)
}
function CustomTabBar(props: any) {
const routes = props.state.routes
const activeIndex: number = props.state.index
const activeRouteName = routes[activeIndex]?.name || 'index'
const handleChange = (route: string) => {
props.navigation.navigate(route)
}
return <BottomNav currentRoute={activeRouteName} onRouteChange={handleChange} />
}
export default function Layout() {
return <Tabs tabBar={(props: any) => <CustomTabBar {...props} />} screenOptions={{ headerShown: false }}></Tabs>
}