Files
MealQuest/web/src/shell/BottomBar.tsx
T
dev_agentandClaude Opus 5.5 93e209c302
CI / ci (pull_request) Successful in 1m31s
CI / ci (push) Successful in 1m32s
Add responsive app shell, routes and navigation
Replace the catch-all placeholder with an AppShell that renders one
primary nav per breakpoint (chosen with matchMedia via useBreakpoint):
a dark pill bottom bar below 768 px, a 96 px rail with the "M" mark at
768-1199 px, and a 208 px sidebar with the MealQuest wordmark and the
"Our kitchen / Shared household" card at 1200 px and up. Nav order is
Home, Plan, Discover, Quick, Settings; NavLink marks the active item
aria-current="page", with nested Plan and Settings paths keeping their
parent current. The mobile scroll area reserves 100 px plus the safe
area beneath its content.

Register every handoff route plus /settings/household,
/settings/regulars and /settings/calendar, each with a placeholder
heading. Remove the default body margin so the shell fills the viewport.

Tests force each breakpoint with a matchMedia mock and assert the
routes, nav order, each layout's structure, aria-current and the
mobile bottom padding from the stylesheet.

Maestro task: 42a4695a-6bd0-49a1-925e-387858dbee48

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 18:33:09 -04:00

24 lines
881 B
TypeScript

import { NavLink } from 'react-router'
import { Icon } from '../ui/Icon.tsx'
import { navItems } from './navItems.ts'
import styles from './BottomBar.module.css'
// Mobile nav: a dark pill bar floating over the bottom of the screen. Inactive
// items show only their icon; the active item adds its label on a grape pill.
export function BottomBar() {
return (
<nav aria-label="Primary" className={styles.bar}>
{navItems.map((item) => (
<NavLink key={item.to} to={item.to} end={item.end} className={styles.item}>
{({ isActive }) => (
<span className={isActive ? `${styles.pill} ${styles.active}` : styles.pill}>
<Icon icon={item.icon} size="nav" />
<span className={isActive ? styles.label : styles.hiddenLabel}>{item.label}</span>
</span>
)}
</NavLink>
))}
</nav>
)
}