SPB Git

spb/rareindex

Public
2.6 KB · 57 lines tsx
1'use client';23import Link from 'next/link';4import { useEffect, useState } from 'react';5import { usePathname } from 'next/navigation';6import { Menu, X } from 'lucide-react';7import type { NavItem } from '@/config/nav';89export function MobileNav({ items, groups }: { items: NavItem[]; groups: Array<{ id: NavItem['group']; label: string }> }) {10  const [open, setOpen] = useState(false);11  const pathname = usePathname();12  useEffect(() => setOpen(false), [pathname]);13  useEffect(() => {14    document.body.style.overflow = open ? 'hidden' : '';15    return () => {16      document.body.style.overflow = '';17    };18  }, [open]);19  return (20    <div className="lg:hidden">21      <button type="button" aria-label="Open menu" aria-expanded={open} className="inline-flex h-8 w-8 items-center justify-center rounded-md text-muted hover:bg-inset hover:text-fg" onClick={() => setOpen(true)}>22        <Menu className="h-5 w-5" />23      </button>24      {open ? (25        <div className="fixed inset-0 z-50 flex" role="dialog" aria-modal="true">26          <div className="absolute inset-0 bg-black/40" onClick={() => setOpen(false)} />27          <div className="relative flex h-[100dvh] w-[86vw] max-w-sm flex-col overflow-y-auto bg-elevated shadow-pop safe-bottom">28            <div className="flex h-14 items-center justify-between border-b border-border px-4">29              <span className="text-sm font-semibold">Menu</span>30              <button type="button" aria-label="Close menu" className="inline-flex h-8 w-8 items-center justify-center rounded-md text-muted hover:bg-inset" onClick={() => setOpen(false)}>31                <X className="h-5 w-5" />32              </button>33            </div>34            <nav className="flex-1 px-2 py-3">35              {groups.map((g) => (36                <div key={g.id} className="mb-3">37                  <p className="px-2 pb-1 text-[10px] font-semibold uppercase tracking-wider text-subtle">{g.label}</p>38                  {items39                    .filter((n) => n.group === g.id)40                    .map((n) => (41                      <Link key={n.href} href={n.href} className={`block rounded-md px-2 py-2 text-[15px] ${pathname === n.href ? 'bg-inset font-medium text-fg' : 'text-muted'}`}>42                        {n.label}43                      </Link>44                    ))}45                </div>46              ))}47              <Link href="/account" className="mt-2 block rounded-md border border-border px-3 py-2 text-center text-sm font-medium">48                Sign in49              </Link>50            </nav>51          </div>52        </div>53      ) : null}54    </div>55  );56}57
Files · d4cbf87a4d6431f74690ca22ffff043c6ca7da5d
Menu

Theme