spb/countryatlas
Public
TypeScript 57%
Python 38.6%
JavaScript 3.6%
CSS 0.6%
1'use client';2import { BarChart3, Globe2, Map, Scale, Search } from 'lucide-react';3import Link from 'next/link';4import { usePathname } from 'next/navigation';5import { t } from '@/i18n';6import { cn } from '@/lib/cn';7import { routes } from '@/lib/site';8import { isFullBleed } from './main-frame';9import { useOpenSearch } from './search-context';1011/**12 * Fixed bottom tab bar (< md): Explore · Countries · Compare · Rank · Search. Safe-area padding; the body13 * reserves space (`pb-[calc(56px+env(safe-area-inset-bottom))]`) so it never covers the footer. Hidden on the14 * full-viewport explorers, which carry their own bottom controls.15 */16export function MobileTabBar() {17 const pathname = usePathname();18 const openSearch = useOpenSearch();19 if (isFullBleed(pathname)) return null;20 const tabs = [21 { href: routes.explore(), label: t('nav.explore'), Icon: Map },22 { href: routes.countries(), label: t('nav.countries'), Icon: Globe2 },23 { href: routes.compare(), label: t('nav.compare'), Icon: Scale },24 { href: routes.rankings(), label: t('nav.rank'), Icon: BarChart3 },25 ];26 return (27 <nav aria-label={t('nav.primary')} className="fixed inset-x-0 bottom-0 z-30 border-t border-rule bg-paper/95 backdrop-blur supports-[backdrop-filter]:bg-paper/90 md:hidden safe-bottom">28 <ul className="grid h-14 grid-cols-5">29 {tabs.map(({ href, label, Icon }) => {30 const base = href.split('?')[0]!;31 const active = pathname === base || pathname.startsWith(`${base}/`);32 return (33 <li key={href} className="min-w-0">34 <Link href={href} aria-current={active ? 'page' : undefined} className={cn('flex h-full flex-col items-center justify-center gap-0.5 text-2xs', active ? 'text-accent' : 'text-ink-2')}>35 <Icon size={20} aria-hidden strokeWidth={active ? 2.25 : 1.75} />36 <span className="truncate">{label}</span>37 </Link>38 </li>39 );40 })}41 <li className="min-w-0">42 <button type="button" onClick={openSearch} className="flex h-full w-full flex-col items-center justify-center gap-0.5 text-2xs text-ink-2">43 <Search size={20} aria-hidden strokeWidth={1.75} />44 <span className="truncate">{t('nav.search')}</span>45 </button>46 </li>47 </ul>48 </nav>49 );50}51