TypeScript 97.4%
SQL 1%
JavaScript 0.9%
CSS 0.6%
1"use client";2import * as React from "react";3import Link from "next/link";4import { usePathname } from "next/navigation";5import { BarChart3, Boxes, MessageSquare, Swords, UserRound } from "lucide-react";6import { cn } from "@/lib/utils";78export const MOBILE_TABS = [9 { href: "/app/chat", label: "Chat", icon: MessageSquare, match: /^\/app\/(chat|projects|prompts|presets)/ },10 { href: "/app/arena", label: "Arena", icon: Swords, match: /^\/app\/arena/ },11 { href: "/app/models", label: "Models", icon: Boxes, match: /^\/app\/models/ },12 { href: "/app/usage", label: "Usage", icon: BarChart3, match: /^\/app\/usage/ },13 { href: "/app/settings/account", label: "Account", icon: UserRound, match: /^\/app\/settings/ },14] as const;1516/**17 * Persistent bottom navigation for phones. Hidden automatically while the on-screen keyboard is open18 * (`html[data-keyboard]`) so the composer sits directly above the keyboard.19 */20export function BottomNav({ className }: { className?: string }) {21 const pathname = usePathname();22 return (23 <nav24 aria-label="Primary"25 className={cn(26 "glass-strong fixed inset-x-0 bottom-0 z-30 border-t border-hairline md:hidden",27 "pb-[var(--sab)] transition-transform duration-200 ease-out [html[data-keyboard]_&]:translate-y-full",28 className,29 )}30 >31 <ul className="mx-auto grid h-[var(--bottom-nav-h)] max-w-lg grid-cols-5">32 {MOBILE_TABS.map((t) => {33 const active = t.match.test(pathname);34 return (35 <li key={t.href} className="min-w-0">36 <Link37 href={t.href}38 aria-current={active ? "page" : undefined}39 className={cn("flex h-full flex-col items-center justify-center gap-0.5 text-[10.5px] font-medium tracking-tight transition-colors", active ? "text-fg" : "text-fg-subtle active:text-fg-muted")}40 >41 <span className={cn("flex h-7 w-12 items-center justify-center rounded-full transition-[background-color,transform] duration-200", active ? "bg-accent-soft text-accent" : "")}>42 <t.icon className={cn("size-[21px]", active && "scale-105")} strokeWidth={active ? 2.2 : 1.8} />43 </span>44 {t.label}45 </Link>46 </li>47 );48 })}49 </ul>50 </nav>51 );52}53