@ugurdemirel/landcraft 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,468 @@
1
+ import { useId, useState, type HTMLAttributes, type ReactNode } from "react";
2
+ import { cn } from "../utils/cn";
3
+ import { getContrastText } from "../utils/contrast";
4
+ import { ChevronDown, Menu, X } from "../icons";
5
+
6
+ export interface MegaMenuLink {
7
+ label: string;
8
+ href: string;
9
+ description?: string;
10
+ }
11
+
12
+ export interface MegaMenuColumn {
13
+ title?: string;
14
+ links: MegaMenuLink[];
15
+ }
16
+
17
+ export interface MegaMenuFeatured {
18
+ title: string;
19
+ description?: string;
20
+ href: string;
21
+ cta?: string;
22
+ /** Background color for the card; glyph text color is computed for contrast. */
23
+ accent?: string;
24
+ }
25
+
26
+ export interface MegaMenuItem {
27
+ label: string;
28
+ href?: string;
29
+ /** When set, the item becomes a trigger that opens a mega panel. */
30
+ columns?: MegaMenuColumn[];
31
+ /** Optional highlighted card pinned to the right side of the panel. */
32
+ featured?: MegaMenuFeatured;
33
+ /** Small pill rendered next to the trigger label. */
34
+ badge?: string;
35
+ }
36
+
37
+ export interface MegaMenuProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
38
+ variant?: "classic" | "floating" | "inverse";
39
+ /** Wordmark rendered when no logo is supplied. */
40
+ brand?: ReactNode;
41
+ /** Custom logo node (component, <img>, inline SVG…). Replaces the wordmark. */
42
+ logo?: ReactNode;
43
+ /** Quick logo image source. */
44
+ logoSrc?: string;
45
+ logoAlt?: string;
46
+ logoClassName?: string;
47
+ brandHref?: string;
48
+ items: MegaMenuItem[];
49
+ /** Rendered at the right side of the bar (desktop) and inside the mobile panel. */
50
+ actions?: ReactNode;
51
+ cta?: ReactNode;
52
+ sticky?: boolean;
53
+ }
54
+
55
+ const triggerStyles = {
56
+ classic: "text-muted-foreground hover:text-foreground hover:bg-surface",
57
+ floating: "text-muted-foreground hover:text-foreground hover:bg-surface",
58
+ inverse: "text-on-secondary/60 hover:text-on-secondary hover:bg-white/10",
59
+ };
60
+
61
+ export const MegaMenu = ({
62
+ className,
63
+ variant = "classic",
64
+ brand,
65
+ logo,
66
+ logoSrc,
67
+ logoAlt,
68
+ logoClassName,
69
+ brandHref = "#",
70
+ items,
71
+ actions,
72
+ cta,
73
+ sticky = true,
74
+ onKeyDown,
75
+ ...props
76
+ }: MegaMenuProps) => {
77
+ const ids = useId();
78
+ const [openIndex, setOpenIndex] = useState<number | null>(null);
79
+ const [mobileOpen, setMobileOpen] = useState(false);
80
+ const [mobileExpanded, setMobileExpanded] = useState<number | null>(null);
81
+
82
+ const inverse = variant === "inverse";
83
+
84
+ const closePanels = () => setOpenIndex(null);
85
+ const closeAll = () => {
86
+ setOpenIndex(null);
87
+ setMobileOpen(false);
88
+ setMobileExpanded(null);
89
+ };
90
+
91
+ const panelBackground = inverse
92
+ ? "border-white/10 bg-[#161616]"
93
+ : "border-border bg-surface shadow-raised";
94
+
95
+ const panelId = (i: number) => `${ids}-panel-${i}`;
96
+
97
+ const shell = cn(
98
+ "relative w-full transition-colors duration-200",
99
+ sticky && "sticky top-0 z-50",
100
+ variant === "classic" &&
101
+ "border-b border-border bg-background/85 backdrop-blur-md supports-[backdrop-filter]:bg-background/75",
102
+ variant === "inverse" && "border-b border-white/10 bg-[#101010]/85 backdrop-blur-md",
103
+ );
104
+
105
+ const bar = cn(
106
+ "relative flex h-16 w-full items-center justify-between gap-4 transition-colors duration-200",
107
+ variant === "floating" &&
108
+ "mx-auto mt-3 max-w-5xl rounded-xl border border-border bg-surface/90 px-5 shadow-soft backdrop-blur-md supports-[backdrop-filter]:bg-surface/70",
109
+ variant !== "floating" && "mx-auto max-w-6xl px-5 sm:px-8",
110
+ );
111
+
112
+ const logoNode =
113
+ logo ??
114
+ (logoSrc ? (
115
+ <img
116
+ src={logoSrc}
117
+ alt={logoAlt ?? (typeof brand === "string" ? brand : "Logo")}
118
+ className={cn("h-7 w-auto", logoClassName)}
119
+ />
120
+ ) : null);
121
+
122
+ const brandNode = logoNode ? (
123
+ <span className="flex items-center">{logoNode}</span>
124
+ ) : (
125
+ <span
126
+ className={cn(
127
+ "flex items-center gap-2 font-display text-[17px] font-bold tracking-tight",
128
+ inverse ? "text-on-secondary" : "text-foreground",
129
+ )}
130
+ >
131
+ <span
132
+ aria-hidden
133
+ className={cn(
134
+ "inline-block h-2.5 w-2.5 rounded-sm",
135
+ inverse ? "bg-on-secondary" : "bg-foreground",
136
+ )}
137
+ />
138
+ {brand}
139
+ </span>
140
+ );
141
+
142
+ const triggerClasses = cn(
143
+ "flex items-center gap-1.5 rounded-md px-3 py-2 text-sm font-medium transition-colors duration-150",
144
+ triggerStyles[variant],
145
+ );
146
+
147
+ const renderColumns = (item: MegaMenuItem) => (
148
+ <div
149
+ className={cn(
150
+ "grid gap-x-10 gap-y-8 sm:grid-cols-2",
151
+ item.featured ? "" : "lg:grid-cols-3",
152
+ )}
153
+ >
154
+ {item.columns?.map((column, ci) => (
155
+ <div key={column.title ?? ci}>
156
+ {column.title ? (
157
+ <h4
158
+ className={cn(
159
+ "text-xs font-semibold uppercase tracking-[0.14em]",
160
+ inverse ? "text-on-secondary/45" : "text-muted-foreground/70",
161
+ )}
162
+ >
163
+ {column.title}
164
+ </h4>
165
+ ) : null}
166
+ <ul className={cn(column.title && "mt-3", "space-y-0.5")}>
167
+ {column.links.map((link) => (
168
+ <li key={link.href}>
169
+ <a
170
+ href={link.href}
171
+ onClick={closeAll}
172
+ className={cn(
173
+ "-mx-2 block rounded-md px-2 py-2 transition-colors duration-150",
174
+ inverse
175
+ ? "hover:bg-white/10"
176
+ : "hover:bg-surface-strong",
177
+ )}
178
+ >
179
+ <span className="block text-sm font-medium text-foreground">
180
+ {link.label}
181
+ </span>
182
+ {link.description ? (
183
+ <span
184
+ className={cn(
185
+ "mt-0.5 block text-[13px] leading-snug",
186
+ inverse ? "text-on-secondary/50" : "text-muted-foreground",
187
+ )}
188
+ >
189
+ {link.description}
190
+ </span>
191
+ ) : null}
192
+ </a>
193
+ </li>
194
+ ))}
195
+ </ul>
196
+ </div>
197
+ ))}
198
+ </div>
199
+ );
200
+
201
+ const renderFeatured = (item: MegaMenuItem, mobile = false) => {
202
+ const featured = item.featured;
203
+ if (!featured) return null;
204
+ const featuredStyle = featured.accent
205
+ ? { backgroundColor: featured.accent, color: getContrastText(featured.accent) }
206
+ : undefined;
207
+
208
+ return (
209
+ <a
210
+ href={featured.href}
211
+ onClick={closeAll}
212
+ className={cn(
213
+ "group relative block overflow-hidden rounded-lg p-6 transition-transform duration-150 hover:-translate-y-0.5",
214
+ mobile && "mt-8",
215
+ !featured.accent && "bg-primary text-on-primary",
216
+ )}
217
+ style={featuredStyle}
218
+ >
219
+ <div className="flex h-full flex-col justify-between gap-4">
220
+ <div>
221
+ <h4 className="font-display text-base font-semibold tracking-tight">
222
+ {featured.title}
223
+ </h4>
224
+ {featured.description ? (
225
+ <p className="mt-1.5 text-[13px] leading-relaxed opacity-80">
226
+ {featured.description}
227
+ </p>
228
+ ) : null}
229
+ </div>
230
+ {featured.cta ? (
231
+ <span className="text-sm font-semibold underline decoration-1 underline-offset-4">
232
+ {featured.cta} →
233
+ </span>
234
+ ) : null}
235
+ </div>
236
+ <div
237
+ aria-hidden
238
+ className="pointer-events-none absolute -right-8 -top-8 h-28 w-28 rounded-full opacity-20 blur-2xl bg-black/40"
239
+ />
240
+ </a>
241
+ );
242
+ };
243
+
244
+ const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
245
+ if (event.key === "Escape") {
246
+ closeAll();
247
+ }
248
+ onKeyDown?.(event);
249
+ };
250
+
251
+ return (
252
+ <header
253
+ className={cn(shell, variant === "floating" && "px-3 sm:px-6", className)}
254
+ onKeyDown={handleKeyDown}
255
+ {...props}
256
+ >
257
+ <nav className={bar} onMouseLeave={closePanels} aria-label="Mega menu">
258
+ <a href={brandHref} className="shrink-0">
259
+ {brandNode}
260
+ </a>
261
+
262
+ <ul className="hidden items-center gap-1 lg:flex">
263
+ {items.map((item, i) => {
264
+ const hasPanel = Boolean(item.columns?.length || item.featured);
265
+ const open = openIndex === i;
266
+ return (
267
+ <li key={item.label} className="relative">
268
+ {hasPanel ? (
269
+ <button
270
+ type="button"
271
+ aria-haspopup="true"
272
+ aria-expanded={open}
273
+ aria-controls={panelId(i)}
274
+ onClick={() => setOpenIndex(open ? null : i)}
275
+ onMouseEnter={() => setOpenIndex(i)}
276
+ className={cn(
277
+ triggerClasses,
278
+ open &&
279
+ (inverse
280
+ ? "bg-white/10 text-on-secondary"
281
+ : "bg-surface text-foreground"),
282
+ )}
283
+ >
284
+ <span className="flex items-center gap-1.5">
285
+ {item.label}
286
+ {item.badge ? (
287
+ <span
288
+ className={cn(
289
+ "rounded-full px-1.5 py-0.5 text-[10px] font-semibold tracking-wide",
290
+ inverse
291
+ ? "bg-white/15 text-on-secondary"
292
+ : "bg-primary-soft text-primary",
293
+ )}
294
+ >
295
+ {item.badge}
296
+ </span>
297
+ ) : null}
298
+ </span>
299
+ <ChevronDown
300
+ className={cn(
301
+ "h-4 w-4 shrink-0 transition-transform duration-150",
302
+ open && "rotate-180",
303
+ )}
304
+ />
305
+ </button>
306
+ ) : (
307
+ <a href={item.href ?? "#"} className={triggerClasses}>
308
+ {item.label}
309
+ {item.badge ? (
310
+ <span className="rounded-full bg-primary-soft px-1.5 py-0.5 text-[10px] font-semibold tracking-wide text-primary">
311
+ {item.badge}
312
+ </span>
313
+ ) : null}
314
+ </a>
315
+ )}
316
+ </li>
317
+ );
318
+ })}
319
+ </ul>
320
+
321
+ <div className="hidden items-center gap-3 lg:flex">
322
+ {actions}
323
+ {cta}
324
+ </div>
325
+
326
+ <button
327
+ type="button"
328
+ aria-label={mobileOpen ? "Close menu" : "Open menu"}
329
+ aria-expanded={mobileOpen}
330
+ onClick={() => setMobileOpen((o) => !o)}
331
+ className={cn(
332
+ "inline-flex h-10 w-10 shrink-0 cursor-pointer items-center justify-center rounded-md lg:hidden",
333
+ "transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
334
+ inverse ? "text-on-secondary hover:bg-white/10" : "text-foreground hover:bg-surface",
335
+ )}
336
+ >
337
+ {mobileOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
338
+ </button>
339
+ </nav>
340
+
341
+ {/* Desktop mega panels */}
342
+ {items.map((item, i) => {
343
+ if (!item.columns?.length && !item.featured) return null;
344
+ const open = openIndex === i;
345
+ return (
346
+ <div
347
+ key={item.label}
348
+ id={panelId(i)}
349
+ role="region"
350
+ aria-label={`${item.label} menu`}
351
+ onMouseEnter={() => setOpenIndex(i)}
352
+ className={cn(
353
+ "absolute inset-x-0 top-full z-50 pt-2 transition-all duration-150",
354
+ open
355
+ ? "visible translate-y-0 opacity-100"
356
+ : "pointer-events-none invisible -translate-y-1 opacity-0",
357
+ )}
358
+ >
359
+ <div
360
+ className={cn(
361
+ "overflow-hidden rounded-xl border p-6 md:p-8",
362
+ panelBackground,
363
+ item.featured ? "lg:grid lg:grid-cols-[minmax(0,1fr)_auto] lg:gap-12" : "",
364
+ )}
365
+ >
366
+ {renderColumns(item)}
367
+ {item.featured && (
368
+ <div className={cn("mt-8 max-w-sm lg:mt-0 lg:w-64")}>
369
+ {renderFeatured(item)}
370
+ </div>
371
+ )}
372
+ </div>
373
+ </div>
374
+ );
375
+ })}
376
+
377
+ {/* Mobile accordion panel */}
378
+ <div
379
+ className={cn(
380
+ "grid transition-[grid-template-rows,opacity] duration-200 lg:hidden",
381
+ mobileOpen ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0",
382
+ inverse
383
+ ? "border-t border-white/10 bg-[#101010]"
384
+ : variant === "floating"
385
+ ? "mx-3 mb-3 max-w-5xl overflow-hidden rounded-b-xl border border-border bg-surface"
386
+ : "border-t border-border bg-background",
387
+ )}
388
+ >
389
+ <div className="min-h-0 overflow-hidden">
390
+ <ul className="flex flex-col py-4">
391
+ {items.map((item, i) =>
392
+ item.columns?.length || item.featured ? (
393
+ <li key={item.label} className="px-5">
394
+ <button
395
+ type="button"
396
+ aria-expanded={mobileExpanded === i}
397
+ onClick={() =>
398
+ setMobileExpanded((prev) => (prev === i ? null : i))
399
+ }
400
+ className={cn(
401
+ "flex w-full items-center justify-between rounded-md px-2 py-2.5 text-sm font-medium transition-colors duration-150",
402
+ inverse
403
+ ? "text-on-secondary hover:bg-white/10"
404
+ : "text-foreground hover:bg-surface",
405
+ )}
406
+ >
407
+ <span className="flex items-center gap-2">
408
+ {item.label}
409
+ {item.badge ? (
410
+ <span className="rounded-full bg-primary-soft px-1.5 py-0.5 text-[10px] font-semibold tracking-wide text-primary">
411
+ {item.badge}
412
+ </span>
413
+ ) : null}
414
+ </span>
415
+ <ChevronDown
416
+ className={cn(
417
+ "h-4 w-4 shrink-0 transition-transform duration-150",
418
+ mobileExpanded === i && "rotate-180",
419
+ )}
420
+ />
421
+ </button>
422
+ <div
423
+ className={cn(
424
+ "grid transition-[grid-template-rows,opacity] duration-200",
425
+ mobileExpanded === i
426
+ ? "grid-rows-[1fr] opacity-100"
427
+ : "grid-rows-[0fr] opacity-0",
428
+ )}
429
+ >
430
+ <div className="min-h-0 overflow-hidden">
431
+ <div className="py-2 pl-1">
432
+ {renderColumns(item)}
433
+ {item.featured ? (
434
+ <div className="max-w-sm">{renderFeatured(item, true)}</div>
435
+ ) : null}
436
+ </div>
437
+ </div>
438
+ </div>
439
+ </li>
440
+ ) : (
441
+ <li key={item.label} className="px-5">
442
+ <a
443
+ href={item.href ?? "#"}
444
+ onClick={() => setMobileOpen(false)}
445
+ className={cn(
446
+ "block rounded-md px-2 py-2.5 text-sm font-medium transition-colors duration-150",
447
+ inverse
448
+ ? "text-on-secondary/70 hover:bg-white/10 hover:text-on-secondary"
449
+ : "text-muted-foreground hover:bg-surface hover:text-foreground",
450
+ )}
451
+ >
452
+ {item.label}
453
+ </a>
454
+ </li>
455
+ ),
456
+ )}
457
+ {cta ? (
458
+ <li className="px-8 pb-2 pt-3">{cta}</li>
459
+ ) : actions ? (
460
+ <li className="mt-3 flex flex-wrap gap-3 px-8 pb-2">{actions}</li>
461
+ ) : null}
462
+ </ul>
463
+ </div>
464
+ </div>
465
+ </header>
466
+ );
467
+ };
468
+ MegaMenu.displayName = "MegaMenu";
@@ -0,0 +1,183 @@
1
+ import { useState, type HTMLAttributes, type ReactNode } from "react";
2
+ import { cn } from "../utils/cn";
3
+ import { Menu, X } from "../icons";
4
+
5
+ export interface NavLink {
6
+ label: string;
7
+ href: string;
8
+ }
9
+
10
+ export interface NavbarProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
11
+ variant?: "classic" | "floating" | "inverse";
12
+ /** Wordmark or fallback text rendered when no logo is supplied. */
13
+ brand?: ReactNode;
14
+ /** Custom logo node (component, <img>, inline SVG…). Replaces the wordmark. */
15
+ logo?: ReactNode;
16
+ /** Quick logo image source. */
17
+ logoSrc?: string;
18
+ logoAlt?: string;
19
+ /** Size / position tuning for logo images. Defaults to `h-7 w-auto`. */
20
+ logoClassName?: string;
21
+ brandHref?: string;
22
+ links: NavLink[];
23
+ actions?: ReactNode;
24
+ sticky?: boolean;
25
+ cta?: ReactNode;
26
+ }
27
+
28
+ const linkStyles = {
29
+ classic: "text-muted-foreground hover:text-foreground",
30
+ floating: "text-muted-foreground hover:text-foreground",
31
+ inverse: "text-on-secondary/60 hover:text-on-secondary",
32
+ };
33
+
34
+ export const Navbar = ({
35
+ className,
36
+ variant = "classic",
37
+ brand,
38
+ logo,
39
+ logoSrc,
40
+ logoAlt,
41
+ logoClassName,
42
+ brandHref = "#",
43
+ links,
44
+ actions,
45
+ cta,
46
+ sticky = true,
47
+ ...props
48
+ }: NavbarProps) => {
49
+ const [open, setOpen] = useState(false);
50
+ const inverse = variant === "inverse";
51
+
52
+ const shell = cn(
53
+ "w-full transition-colors duration-200",
54
+ sticky && "sticky top-0 z-50",
55
+ variant === "classic" &&
56
+ "border-b border-border bg-background/85 backdrop-blur-md supports-[backdrop-filter]:bg-background/75",
57
+ variant === "floating" && "px-0",
58
+ variant === "inverse" && "border-b border-white/10 bg-[#101010]/85 backdrop-blur-md",
59
+ );
60
+
61
+ const bar = cn(
62
+ "flex h-16 w-full items-center justify-between gap-4 transition-colors duration-200",
63
+ variant === "floating" &&
64
+ "mx-auto mt-3 max-w-5xl rounded-xl border border-border bg-surface/90 px-5 shadow-soft backdrop-blur-md supports-[backdrop-filter]:bg-surface/70",
65
+ variant === "classic" && "mx-auto max-w-6xl px-5 sm:px-8",
66
+ variant === "inverse" && "mx-auto max-w-6xl px-5 sm:px-8",
67
+ );
68
+
69
+ const logoNode =
70
+ logo ??
71
+ (logoSrc ? (
72
+ <img
73
+ src={logoSrc}
74
+ alt={logoAlt ?? (typeof brand === "string" ? brand : "Logo")}
75
+ className={cn("h-7 w-auto", logoClassName)}
76
+ />
77
+ ) : null);
78
+
79
+ const brandNode = logoNode ? (
80
+ <span className="flex items-center">{logoNode}</span>
81
+ ) : (
82
+ <span
83
+ className={cn(
84
+ "flex items-center gap-2 font-display text-[17px] font-bold tracking-tight",
85
+ inverse ? "text-on-secondary" : "text-foreground",
86
+ )}
87
+ >
88
+ <span
89
+ aria-hidden
90
+ className={cn(
91
+ "inline-block h-2.5 w-2.5 rounded-sm",
92
+ inverse ? "bg-on-secondary" : "bg-foreground",
93
+ )}
94
+ />
95
+ {brand}
96
+ </span>
97
+ );
98
+
99
+ return (
100
+ <header className={cn(shell, variant === "floating" && "px-3 sm:px-6", className)} {...props}>
101
+ <nav className={bar} aria-label="Main navigation">
102
+ <a href={brandHref} className="shrink-0">
103
+ {brandNode}
104
+ </a>
105
+
106
+ <ul className="hidden items-center gap-7 md:flex">
107
+ {links.map((link) => (
108
+ <li key={link.href}>
109
+ <a
110
+ href={link.href}
111
+ className={cn(
112
+ "text-sm font-medium transition-colors duration-150",
113
+ linkStyles[variant],
114
+ )}
115
+ >
116
+ {link.label}
117
+ </a>
118
+ </li>
119
+ ))}
120
+ </ul>
121
+
122
+ <div className="hidden items-center gap-3 md:flex">
123
+ {actions}
124
+ {cta}
125
+ </div>
126
+
127
+ <button
128
+ type="button"
129
+ aria-label={open ? "Close menu" : "Open menu"}
130
+ aria-expanded={open}
131
+ onClick={() => setOpen((o) => !o)}
132
+ className={cn(
133
+ "inline-flex h-10 w-10 shrink-0 cursor-pointer items-center justify-center rounded-md md:hidden",
134
+ "transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
135
+ inverse ? "text-on-secondary hover:bg-white/10" : "text-foreground hover:bg-surface",
136
+ )}
137
+ >
138
+ {open ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
139
+ </button>
140
+ </nav>
141
+
142
+ {/* Mobile panel */}
143
+ <div
144
+ className={cn(
145
+ "grid transition-[grid-template-rows,opacity] duration-200 md:hidden",
146
+ open ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0",
147
+ inverse
148
+ ? "border-t border-white/10 bg-[#101010]"
149
+ : variant === "floating"
150
+ ? "mx-3 mb-3 max-w-5xl overflow-hidden rounded-b-xl border border-border bg-surface"
151
+ : "border-t border-border bg-background",
152
+ )}
153
+ >
154
+ <div className="min-h-0 overflow-hidden">
155
+ <ul className={cn("flex flex-col py-4", variant !== "floating" && "px-5")}>
156
+ {links.map((link) => (
157
+ <li key={link.href}>
158
+ <a
159
+ href={link.href}
160
+ onClick={() => setOpen(false)}
161
+ className={cn(
162
+ "block rounded-md px-2 py-2.5 text-sm font-medium transition-colors duration-150",
163
+ inverse
164
+ ? "text-on-secondary/70 hover:bg-white/10 hover:text-on-secondary"
165
+ : "text-muted-foreground hover:bg-surface hover:text-foreground",
166
+ )}
167
+ >
168
+ {link.label}
169
+ </a>
170
+ </li>
171
+ ))}
172
+ {cta ? (
173
+ <li className="mt-3 px-2 pb-2">{cta}</li>
174
+ ) : actions ? (
175
+ <li className="mt-3 flex flex-wrap gap-3 px-2 pb-2">{actions}</li>
176
+ ) : null}
177
+ </ul>
178
+ </div>
179
+ </div>
180
+ </header>
181
+ );
182
+ };
183
+ Navbar.displayName = "Navbar";