SPB Git

Repository Public

TabBar.tsx 1.8 KB 32 lines tsx

1"use client";23import Link from "next/link";4import { usePathname } from "next/navigation";56const ICON: Record<string, string> = {7  home: "M4 11l8-6.5 8 6.5M6 9.8V19h4.2v-5h3.6v5H18V9.8",8  feed: "M6.5 4.5h11a1.5 1.5 0 0 1 1.5 1.5v12a1.5 1.5 0 0 1-1.5 1.5h-11A1.5 1.5 0 0 1 5 18V6a1.5 1.5 0 0 1 1.5-1.5zM10.2 9v6l5-3z",9  explore: "M12 3.5a8.5 8.5 0 1 0 0 17 8.5 8.5 0 0 0 0-17zM15.2 8.8l-1.7 4.7-4.7 1.7 1.7-4.7z",10  series: "M4.5 6.5h15M4.5 12h15M4.5 17.5h9",11  search: "M11 4.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13zM16 16l4 4",12};1314/** Bottom tab bar on phones: the primary navigation, always within thumb reach. */15export function TabBar({ base, labels, dark = false }: { base: string; labels: { home: string; feed: string; explore: string; series: string; search: string }; dark?: boolean }) {16  const path = usePathname().replace(/^\/(en|fr)(?=\/|$)/, "") || "/";17  const items: [keyof typeof ICON, string, string][] = [["home", "/", labels.home], ["feed", "/feed", labels.feed], ["explore", "/explore", labels.explore], ["series", "/series", labels.series], ["search", "/search", labels.search]];18  return (19    <nav aria-label="Tabs" className={`tabbar flex ${dark ? "tabbar-dark" : ""} glass`} style={dark ? { background: "rgba(9,9,11,0.72)" } : undefined}>20      {items.map(([key, href, label]) => {21        const active = href === "/" ? path === "/" : path.startsWith(href);22        return (23          <Link key={key} href={`${base}${href === "/" ? (base ? "" : "/") : href}`} aria-current={active ? "page" : undefined} className="tab">24            <svg width="23" height="23" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={active ? 2.2 : 1.7} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d={ICON[key]} /></svg>25            <span>{label}</span>26          </Link>27        );28      })}29    </nav>30  );31}32
Files main
Menu

Theme