/** * NavBar — нижний бар на 5 иконок без подписей. * * Активный таб: * - иконка заполненная (Ionicons variant без `-outline`) * - вокруг иконки subtle highlight-блок (чуть светлее bg), радиус 14 * - текст/бейдж остаются как у inactive * * Inactive: * - outline-иконка, цвет #6b6b6b * - soon-таб дополнительно dimmed и показывает чип SOON * * Роутинг через expo-router `router.replace` — без стекa, каждый tab это * полная страница без "back" концепции. */ import React from 'react'; import { View, Pressable, Text } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { useRouter, usePathname } from 'expo-router'; type IoniconName = React.ComponentProps['name']; interface Item { key: string; href: string; icon: IoniconName; iconActive: IoniconName; badge?: number; soon?: boolean; } export interface NavBarProps { bottomInset?: number; requestCount?: number; notifCount?: number; } export function NavBar({ bottomInset = 0, requestCount = 0, notifCount = 0 }: NavBarProps) { const router = useRouter(); const pathname = usePathname(); const items: Item[] = [ { key: 'home', href: '/(app)/chats', icon: 'home-outline', iconActive: 'home', badge: requestCount }, { key: 'add', href: '/(app)/new-contact', icon: 'search-outline', iconActive: 'search' }, { key: 'feed', href: '/(app)/feed', icon: 'newspaper-outline', iconActive: 'newspaper' }, { key: 'notif', href: '/(app)/requests', icon: 'notifications-outline', iconActive: 'notifications', badge: notifCount }, { key: 'wallet', href: '/(app)/wallet', icon: 'wallet-outline', iconActive: 'wallet' }, ]; // NavBar active-matching: путь может начинаться с "/chats" ИЛИ с href // напрямую. Вариант `/chats/xyz` тоже считается active для home. const isActive = (href: string) => { // Нормализуем /(app)/chats → /chats const norm = href.replace(/^\/\(app\)/, ''); return pathname === norm || pathname.startsWith(norm + '/'); }; return ( {items.map((it) => { const active = isActive(it.href); return ( { if (it.soon) return; router.replace(it.href as never); }} hitSlop={6} style={({ pressed }) => ({ flex: 1, alignItems: 'center', justifyContent: 'center', paddingVertical: 4, opacity: pressed ? 0.65 : 1, })} > {it.badge && it.badge > 0 ? ( {it.badge > 99 ? '99+' : it.badge} ) : null} {it.soon && ( SOON )} ); })} ); }