import { createFileRoute, Link, Outlet } from "@tanstack/react-router"; import { Menu, X } from "lucide-react"; import { useCallback, useState } from "react"; import { type Doc, getDocs } from "~/docs"; import "~/styles.css"; export const Route = createFileRoute("/docs")({ component: DocsLayout, }); const ACTIVE_OPTIONS_EXACT = { exact: true }; const MOBILE_ACTIVE_PROPS = { className: "text-foreground" }; const DESKTOP_ACTIVE_PROPS = { className: "bg-muted text-foreground" }; interface NavItem { name: string; href: string; } interface NavGroup { name: string | null; items: NavItem[]; } const GROUP_LABELS: Record = { alternatives: "Alternatives", }; function groupKey(doc: Doc): string | null { const idx = doc.slug.indexOf("/"); return idx === -1 ? null : doc.slug.slice(0, idx); } function buildNavigation(): NavGroup[] { const groups = new Map(); for (const doc of getDocs()) { const key = groupKey(doc); const items = groups.get(key) ?? []; items.push({ name: doc.frontmatter.nav, href: doc.href }); groups.set(key, items); } const ordered: NavGroup[] = []; if (groups.has(null)) ordered.push({ name: null, items: groups.get(null)! }); for (const [key, items] of groups) { if (key === null) continue; ordered.push({ name: GROUP_LABELS[key] ?? key, items }); } return ordered; } function DocsLayout() { const groups = buildNavigation(); const [mobileNavOpen, setMobileNavOpen] = useState(false); const toggleMobileNav = useCallback(() => setMobileNavOpen((v) => !v), []); const closeMobileNav = useCallback(() => setMobileNavOpen(false), []); return (
{/* Mobile header */}
Paseo Paseo
{mobileNavOpen && ( )}
{/* Desktop sidebar */}
); }