11import { clsx } from "clsx" ;
2+ import { ChevronDown } from "lucide-react" ;
3+ import { useState } from "react" ;
24import { Link , Outlet , useLocation } from "react-router-dom" ;
35import { Footer } from "../../components/Footer" ;
46import { Navbar } from "../../components/Navbar" ;
57
8+ const NAV_ITEMS = [
9+ { to : "/docs" , label : "Introduction" , path : "index" } ,
10+ { to : "/docs/paragraphs" , label : "Paragraphs" , path : "paragraphs" } ,
11+ { to : "/docs/tables" , label : "Tables" , path : "tables" } ,
12+ { to : "/docs/styles" , label : "Styles" , path : "styles" , disabled : true } ,
13+ { to : "/docs/creating-documents" , label : "Creating Documents" , path : "creating-documents" } ,
14+ { to : "/docs/common-gotchas" , label : "Common Gotchas" , path : "common-gotchas" } ,
15+ ] ;
16+
617export function DocsLayout ( ) {
718 const location = useLocation ( ) ;
819 const currentPath = location . pathname . replace ( "/docs/" , "" ) . replace ( "/docs" , "index" ) ;
20+ const [ navOpen , setNavOpen ] = useState ( false ) ;
21+
22+ const currentPage = NAV_ITEMS . find ( ( item ) => item . path === currentPath ) ;
923
1024 return (
1125 < div className = "min-h-screen bg-[var(--color-bg-primary)]" >
1226 < Navbar sticky />
1327
28+ { /* Mobile collapsible nav */ }
29+ < div className = "border-b border-[var(--color-border)] md:hidden" >
30+ < button
31+ type = "button"
32+ onClick = { ( ) => setNavOpen ( ! navOpen ) }
33+ className = "flex w-full items-center justify-between px-4 py-3"
34+ >
35+ < span className = "text-sm font-medium" > { currentPage ?. label || "Navigation" } </ span >
36+ < ChevronDown
37+ size = { 16 }
38+ className = { clsx (
39+ "text-[var(--color-text-muted)] transition-transform" ,
40+ navOpen && "rotate-180" ,
41+ ) }
42+ />
43+ </ button >
44+ { navOpen && (
45+ < nav className = "border-t border-[var(--color-border)] px-4 py-2" >
46+ < ul className = "space-y-1" >
47+ { NAV_ITEMS . map ( ( item ) => (
48+ < SidebarLink
49+ key = { item . to }
50+ to = { item . to }
51+ label = { item . label }
52+ active = { currentPath === item . path }
53+ disabled = { item . disabled }
54+ onClick = { ( ) => setNavOpen ( false ) }
55+ />
56+ ) ) }
57+ </ ul >
58+ </ nav >
59+ ) }
60+ </ div >
61+
1462 < div className = "flex" >
15- { /* Sidebar */ }
16- < aside className = "sticky top-[57px] h-[calc(100vh-57px)] w-64 overflow-y-auto border-r border-[var(--color-border)] bg-[var(--color-bg-secondary)] p-4" >
63+ { /* Desktop Sidebar */ }
64+ < aside className = "sticky top-[57px] hidden h-[calc(100vh-57px)] w-64 overflow-y-auto border-r border-[var(--color-border)] bg-[var(--color-bg-secondary)] p-4 md:block " >
1765 < nav className = "space-y-6" >
1866 { /* Getting Started */ }
1967 < div >
@@ -68,7 +116,7 @@ export function DocsLayout() {
68116 </ aside >
69117
70118 { /* Main content */ }
71- < main className = "flex-1 px-8 py-8" >
119+ < main className = "min-w-0 flex-1 px-4 py-6 sm:px-8 sm: py-8" >
72120 < div className = "mx-auto max-w-3xl" >
73121 < Outlet />
74122 </ div >
@@ -85,11 +133,13 @@ function SidebarLink({
85133 label,
86134 active,
87135 disabled,
136+ onClick,
88137} : {
89138 to : string ;
90139 label : string ;
91140 active : boolean ;
92141 disabled ?: boolean ;
142+ onClick ?: ( ) => void ;
93143} ) {
94144 if ( disabled ) {
95145 return (
@@ -110,6 +160,7 @@ function SidebarLink({
110160 < li >
111161 < Link
112162 to = { to }
163+ onClick = { onClick }
113164 className = { clsx (
114165 "block rounded px-3 py-1.5 text-sm transition" ,
115166 active
0 commit comments