@@ -9,8 +9,9 @@ import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMe
99import { useTheme } from "@/hooks/use-theme"
1010import { cn } from "@/utils"
1111import config from 'explainer.config'
12- import { FileCode2Icon , LaptopIcon , MoonIcon , SunIcon } from "lucide-react"
12+ import { FileCode2Icon , LaptopIcon , MenuIcon , MoonIcon , SunIcon } from "lucide-react"
1313import * as React from "react"
14+ import { Sheet , SheetContent , SheetFooter , SheetHeader , SheetTitle , SheetTrigger } from '../ui/sheet'
1415
1516const ListItem = React . forwardRef <
1617 React . ComponentRef < "a" > ,
@@ -45,14 +46,16 @@ export default function Navbar() {
4546 return (
4647 < div className = "sticky top-0 z-50 w-full p-2 py-3 border-b bg-background/60 backdrop-blur-sm" >
4748 < div className = "max-w-screen-xl mx-auto flex items-center justify-between" >
48- { /* Logo and brand */ }
49- < a href = "/" className = "flex items-center space-x-2" >
49+ < a href = "/" className = "flex sm:hidden items-center space-x-2" >
5050 < FileCode2Icon className = "size-5 text-primary" />
5151 < span className = "font-bold text-primary text-lg" > { config . meta . title } </ span >
5252 </ a >
5353
54- { /* Desktop Navigation */ }
55- < div className = "hidden lg:block" >
54+ < div className = "hidden lg:flex items-center justify-between w-full" >
55+ < a href = "/" className = "flex items-center space-x-2" >
56+ < FileCode2Icon className = "size-5 text-primary" />
57+ < span className = "font-bold text-primary text-lg" > { config . meta . title } </ span >
58+ </ a >
5659 < NavigationMenu >
5760 < NavigationMenuList >
5861 { config . navbar . map ( ( element ) => {
@@ -86,60 +89,131 @@ export default function Navbar() {
8689 } ) }
8790 </ NavigationMenuList >
8891 </ NavigationMenu >
89- </ div >
9092
91- { /* Search and theme toggle */ }
92- < div className = "flex items-center space-x-2" >
93- < button className = "p-2 rounded-md hover:bg-gray-100" >
94- < svg className = "h-5 w-5" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" >
95- < path d = "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" > </ path >
96- </ svg >
97- </ button >
93+ < div className = "flex items-center space-x-2" >
94+ < ThemeToggle />
95+
96+ { config . urls . github && (
97+ < a
98+ href = { config . urls . github }
99+ rel = "noopener noreferrer"
100+ target = "_blank"
101+ className = "rounded-[calc(var(--ui-radius)*1.5)] font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors px-2.5 py-1.5 text-sm gap-1.5 text-(--ui-text) hover:bg-(--ui-bg-elevated) focus:outline-none focus-visible:bg-(--ui-bg-elevated) hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent"
102+ >
103+ < svg
104+ xmlns = "http://www.w3.org/2000/svg"
105+ width = { 24 }
106+ height = { 24 }
107+ viewBox = "0 0 24 24"
108+ >
109+ < path fill = "currentColor" d = "M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" > </ path >
110+ </ svg >
111+ < span className = "sr-only" > { config . meta . title } on GitHub</ span >
112+ </ a >
113+ ) }
114+ </ div >
115+ </ div >
98116
99- < DropdownMenu open = { open } onOpenChange = { setOpen } >
100- < DropdownMenuTrigger asChild onClick = { ( ) => setOpen ( ! open ) } >
117+ < div className = "sm:hidden" >
118+ < Sheet >
119+ < SheetTrigger asChild >
101120 < Button variant = "ghost" size = "icon" >
102- { theme === 'light' ? < SunIcon className = "h-5 w-5" /> :
103- theme === 'dark' ? < MoonIcon className = "h-5 w-5" /> :
104- < LaptopIcon className = "h-5 w-5" /> }
121+ < MenuIcon className = "size-5 text-primary" />
105122 </ Button >
106- </ DropdownMenuTrigger >
107- < DropdownMenuContent align = "end" className = "w-56" >
108- < DropdownMenuItem onClick = { ( ) => setTheme ( 'light' ) } >
109- < SunIcon className = "mr-2 h-4 w-4" />
110- Light
111- </ DropdownMenuItem >
112- < DropdownMenuItem onClick = { ( ) => setTheme ( 'dark' ) } >
113- < MoonIcon className = "mr-2 h-4 w-4" />
114- Dark
115- </ DropdownMenuItem >
116- < DropdownMenuItem onClick = { ( ) => setTheme ( 'system' ) } >
117- < LaptopIcon className = "mr-2 h-4 w-4" />
118- System
119- </ DropdownMenuItem >
120- </ DropdownMenuContent >
121- </ DropdownMenu >
122-
123- { config . urls . github && (
124- < a
125- href = { config . urls . github }
126- rel = "noopener noreferrer"
127- target = "_blank"
128- className = "rounded-[calc(var(--ui-radius)*1.5)] font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors px-2.5 py-1.5 text-sm gap-1.5 text-(--ui-text) hover:bg-(--ui-bg-elevated) focus:outline-none focus-visible:bg-(--ui-bg-elevated) hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent"
123+ </ SheetTrigger >
124+ < SheetContent
125+ className = "flex flex-col justify-between gap-4"
126+ side = "left"
129127 >
130- < svg
131- xmlns = "http://www.w3.org/2000/svg"
132- width = { 24 }
133- height = { 24 }
134- viewBox = "0 0 24 24"
135- >
136- < path fill = "currentColor" d = "M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" > </ path >
137- </ svg >
138- < span className = "sr-only" > { config . meta . title } on GitHub</ span >
139- </ a >
140- ) }
128+ < div >
129+ < SheetHeader >
130+ < SheetTitle > { config . meta . title } </ SheetTitle >
131+ </ SheetHeader >
132+ < div className = "flex flex-col items-start gap-2" >
133+ < a href = "/" className = "pt-5 text-sm font-medium hover:bg-accent hover:text-accent-foreground rounded-md cursor-pointer" >
134+ Home
135+ </ a >
136+ { config . navbar . map ( ( element ) => {
137+ if ( element . href ) {
138+ return (
139+ < a href = { element . href } className = "text-sm font-medium hover:bg-accent hover:text-accent-foreground rounded-md cursor-pointer" >
140+ { element . label }
141+ </ a >
142+ )
143+ }
144+
145+ return (
146+ < div key = { element . label } >
147+ < p className = "text-sm font-medium" > { element . label } </ p >
148+ < ul className = "flex flex-col items-start gap-5 pt-2 pb-5" >
149+ { element . items ?. map ( ( item ) => (
150+ < a href = { item . href } className = "flex flex-col px-3 text-sm font-medium hover:bg-accent hover:text-accent-foreground rounded-md cursor-pointer" >
151+ < span > { item . label } </ span >
152+ < span className = "text-xs text-muted-foreground" > { item . description } </ span >
153+ </ a >
154+ ) ) }
155+ </ ul >
156+ </ div >
157+ )
158+ } ) }
159+ </ div >
160+ </ div >
161+ < SheetFooter >
162+ { config . urls . github && (
163+ < Button variant = "outline" asChild >
164+ < a
165+ href = { config . urls . github }
166+ rel = "noopener noreferrer"
167+ target = "_blank"
168+ className = "rounded-[calc(var(--ui-radius)*1.5)] font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors px-2.5 py-1.5 text-sm gap-1.5 text-(--ui-text) hover:bg-(--ui-bg-elevated) focus:outline-none focus-visible:bg-(--ui-bg-elevated) hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent"
169+ >
170+ < svg
171+ xmlns = "http://www.w3.org/2000/svg"
172+ width = { 24 }
173+ height = { 24 }
174+ viewBox = "0 0 24 24"
175+ >
176+ < path fill = "currentColor" d = "M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" > </ path >
177+ </ svg >
178+ < span className = "" > GitHub</ span >
179+ </ a >
180+ </ Button >
181+ ) }
182+ </ SheetFooter >
183+ </ SheetContent >
184+ </ Sheet >
141185 </ div >
142186 </ div >
143- </ div >
187+ </ div >
188+ )
189+ }
190+
191+ function ThemeToggle ( ) {
192+ const [ open , setOpen ] = React . useState ( false )
193+ const { theme, setTheme } = useTheme ( )
194+ return (
195+ < DropdownMenu open = { open } onOpenChange = { setOpen } >
196+ < DropdownMenuTrigger asChild onClick = { ( ) => setOpen ( ! open ) } >
197+ < Button variant = "ghost" size = "icon" >
198+ { theme === 'light' ? < SunIcon className = "h-5 w-5" /> :
199+ theme === 'dark' ? < MoonIcon className = "h-5 w-5" /> :
200+ < LaptopIcon className = "h-5 w-5" /> }
201+ </ Button >
202+ </ DropdownMenuTrigger >
203+ < DropdownMenuContent align = "end" className = "w-56" >
204+ < DropdownMenuItem onClick = { ( ) => setTheme ( 'light' ) } >
205+ < SunIcon className = "mr-2 h-4 w-4" />
206+ Light
207+ </ DropdownMenuItem >
208+ < DropdownMenuItem onClick = { ( ) => setTheme ( 'dark' ) } >
209+ < MoonIcon className = "mr-2 h-4 w-4" />
210+ Dark
211+ </ DropdownMenuItem >
212+ < DropdownMenuItem onClick = { ( ) => setTheme ( 'system' ) } >
213+ < LaptopIcon className = "mr-2 h-4 w-4" />
214+ System
215+ </ DropdownMenuItem >
216+ </ DropdownMenuContent >
217+ </ DropdownMenu >
144218 )
145219}
0 commit comments