1- import * as React from "react"
2- import { cn } from "@/utils"
3- import { Menu , X } from "lucide-react"
4- import { Button } from "../ui/button"
1+ import {
2+ Sheet ,
3+ SheetContent ,
4+ SheetDescription ,
5+ SheetHeader ,
6+ SheetTrigger
7+ } from "@/components/ui/sheet"
8+ import { Icon } from '@iconify/react'
9+ import clsx from 'clsx'
10+ import { Fragment , useState } from 'react'
11+ import config from '../../../../explainer.config'
512
6- interface SidebarItem {
7- title : string
8- href : string
9- icon ?: React . ReactNode
10- items ?: SidebarItem [ ]
13+ type Props = {
1114}
1215
13- interface DocsSidebarProps {
14- items : SidebarItem [ ]
15- className ?: string
16- }
16+ export function DocsSidebar ( props : Props ) {
17+ const [ isOpen , setIsOpen ] = useState ( false )
1718
18- const SidebarLink = ( { item } : { item : SidebarItem } ) => {
1919 return (
20- < li >
21- < a
22- href = { item . href }
23- className = "flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground rounded-md hover:bg-accent hover:text-accent-foreground"
24- >
25- { item . icon }
26- { item . title }
27- </ a >
28- { item . items && (
29- < ul className = "ml-4 mt-2 space-y-1" >
30- { item . items . map ( ( subItem ) => (
31- < SidebarLink key = { subItem . href } item = { subItem } />
32- ) ) }
33- </ ul >
34- ) }
35- </ li >
20+ < div >
21+ < div >
22+ < SidebarRenderer />
23+ </ div >
24+ < Sheet open = { isOpen } onOpenChange = { setIsOpen } >
25+ < SheetTrigger >
26+ < Icon
27+ icon = { isOpen ? 'lucide:chevron-up' : 'lucide:chevron-down' }
28+ className = "size-5"
29+ />
30+ </ SheetTrigger >
31+ < SheetContent side = "left" >
32+ < SheetHeader >
33+ < SheetDescription />
34+ < SidebarRenderer />
35+ </ SheetHeader >
36+ </ SheetContent >
37+ </ Sheet >
38+ </ div >
3639 )
3740}
3841
39- export function DocsSidebar ( { items, className } : DocsSidebarProps ) {
40- const [ isOpen , setIsOpen ] = React . useState ( false )
41-
42+ function SidebarRenderer ( ) {
4243 return (
43- < >
44- { /* Mobile toggle */ }
45- < Button
46- variant = "ghost"
47- size = "icon"
48- className = "fixed top-4 left-4 z-40 lg:hidden"
49- onClick = { ( ) => setIsOpen ( ! isOpen ) }
50- >
51- { isOpen ? < X className = "h-6 w-6" /> : < Menu className = "h-6 w-6" /> }
52- </ Button >
44+ < Fragment >
45+ < nav >
46+ < div className = "space-y-3 mb-3 lg:mb-6 -mx-1 lg:mx-0" >
47+ {
48+ Object . entries ( config . docs ) . map ( ( [ key , element ] ) => (
49+ < a
50+ className = "flex items-center gap-2 group text-primary font-medium"
51+ href = { element . href }
52+ >
53+ < div
54+ className = { clsx (
55+ "rounded-sm p-1 inline-flex ring-inset ring-1" ,
56+ window . location . pathname . startsWith ( element . baseUrl )
57+ ? "bg-primary ring-primary text-white"
58+ : "bg-gray-50 dark:bg-gray-800 ring-gray-200 dark:ring-gray-700 text-muted-foreground" ,
59+ ) }
60+ >
61+ < Icon
62+ icon = { element . icon }
63+ className = "size-4"
64+ />
65+ </ div >
66+ < span
67+ className = { clsx (
68+ "text-sm relative" ,
69+ window . location . pathname . startsWith ( element . baseUrl )
70+ ? "text-primary"
71+ : "text-muted-foreground" ,
72+ ) }
73+ >
74+ { element . label }
75+ </ span >
76+ </ a >
77+ ) )
78+ }
79+ </ div >
80+ </ nav >
5381
54- { /* Backdrop */ }
55- { isOpen && (
56- < div
57- className = "fixed inset-0 z-30 bg-background/80 backdrop-blur-sm lg:hidden"
58- onClick = { ( ) => setIsOpen ( false ) }
59- />
60- ) }
82+ < hr
83+ className = "my-5 border-dashed border-gray-200 dark:border-gray-700"
84+ />
6185
62- { /* Sidebar */ }
63- < aside
64- className = { cn (
65- "fixed top-0 left-0 z-30 h-screen w-72 border-r bg-background transition-transform lg:translate-x-0 lg:relative" ,
66- isOpen ? "translate-x-0" : "-translate-x-full" ,
67- className
68- ) }
69- >
70- < div className = "sticky top-0 overflow-y-auto h-full p-6 pt-16 lg:pt-6" >
71- < nav >
72- < ul className = "space-y-2" >
73- { items . map ( ( item ) => (
74- < SidebarLink key = { item . href } item = { item } />
75- ) ) }
76- </ ul >
77- </ nav >
78- </ div >
79- </ aside >
80- </ >
86+ < div className = "space-y-1" >
87+ {
88+ currentCollectionItems . map ( ( item ) => (
89+ < a
90+ href = { item . href }
91+ className = "group block py-1.5 px-1.5 text-sm rounded-md transition-colors hover:text-primary"
92+ >
93+ < div className = "flex items-center gap-2" >
94+ { item . icon ? (
95+ < Icon
96+ client :only
97+ icon = { item . icon }
98+ className = { clsx (
99+ "text-gray-500 dark:text-gray-400 group-hover:text-primary size-5" ,
100+ Astro . url . pathname . startsWith ( item . href )
101+ ? "text-primary"
102+ : "text-muted-foreground" ,
103+ ) }
104+ />
105+ ) : (
106+ < div className = "size-5" />
107+ ) }
108+ < span
109+ className = { clsx (
110+ "text-sm group-hover:text-primary" ,
111+ Astro . url . pathname . startsWith ( item . href )
112+ ? "text-primary"
113+ : "text-muted-foreground" ,
114+ ) }
115+ >
116+ { item . label }
117+ </ span >
118+ </ div >
119+ </ a >
120+ ) )
121+ }
122+ </ div >
123+ </ Fragment >
81124 )
82- }
125+ }
0 commit comments