Spaces:
Sleeping
Sleeping
| /** Bottom nav: Home | Plan | gold FAB Log | Daily | Settings. | |
| History stays reachable from Home (“See all”). Log FAB remains one tap. | |
| */ | |
| import { CalendarClock, CalendarDays, House, Plus, Settings } from "lucide-preact"; | |
| import { Pressable } from "./Pressable"; | |
| import { navigate, type Route } from "../router"; | |
| type TabName = "home" | "plan" | "daily" | "settings"; | |
| const TABS: { | |
| name: TabName; | |
| label: string; | |
| path: string; | |
| Icon: typeof House; | |
| }[] = [ | |
| { name: "home", label: "Home", path: "/", Icon: House }, | |
| { name: "plan", label: "Plan", path: "/plan", Icon: CalendarClock }, | |
| { name: "daily", label: "Daily", path: "/daily", Icon: CalendarDays }, | |
| { name: "settings", label: "Settings", path: "/settings", Icon: Settings }, | |
| ]; | |
| export function TabBar({ route }: { route: Route }) { | |
| const left = TABS.slice(0, 2); | |
| const right = TABS.slice(2); | |
| return ( | |
| <nav class="tab-bar" aria-label="Main"> | |
| <div class="tab-bar-inner"> | |
| {left.map((tab) => { | |
| const active = route.name === tab.name; | |
| const Icon = tab.Icon; | |
| return ( | |
| <Pressable | |
| key={tab.name} | |
| className={`tab-item ${active ? "active" : ""}`.trim()} | |
| ariaLabel={tab.label} | |
| onClick={() => navigate(tab.path)} | |
| > | |
| <Icon size={22} strokeWidth={active ? 2.4 : 2} aria-hidden="true" /> | |
| <span aria-current={active ? "page" : undefined}>{tab.label}</span> | |
| </Pressable> | |
| ); | |
| })} | |
| <div class="tab-fab-slot" aria-hidden="true" /> | |
| {right.map((tab) => { | |
| const active = route.name === tab.name; | |
| const Icon = tab.Icon; | |
| return ( | |
| <Pressable | |
| key={tab.name} | |
| className={`tab-item ${active ? "active" : ""}`.trim()} | |
| ariaLabel={tab.label} | |
| onClick={() => navigate(tab.path)} | |
| > | |
| <Icon size={22} strokeWidth={active ? 2.4 : 2} aria-hidden="true" /> | |
| <span aria-current={active ? "page" : undefined}>{tab.label}</span> | |
| </Pressable> | |
| ); | |
| })} | |
| </div> | |
| <Pressable className="tab-fab" ariaLabel="Log" onClick={() => navigate("/log")}> | |
| <Plus size={28} strokeWidth={2.5} color="#202020" aria-hidden="true" /> | |
| </Pressable> | |
| </nav> | |
| ); | |
| } | |