Skip to content

Commit c584279

Browse files
netlify-coding[bot]netlify-botvLuckyyy
authored
GH-227 Redesign and optimize navbar for mobile responsiveness (#227)
* Redesign and optimize navbar and documentation navigation for mobile responsiveness (698923eb18e06390f29bcf61) * Fix. --------- Co-authored-by: netlify[bot] <noreply@netlify.com> Co-authored-by: Martin Sulikowski <vLuckyyy.biznes@gmail.com>
1 parent 270b3f8 commit c584279

5 files changed

Lines changed: 387 additions & 319 deletions

File tree

app/docs/(content)/layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ export default async function ContentLayout({ children }: { children: ReactNode
66
const sidebarStructure = await getSidebar();
77

88
return (
9-
<div className="relative z-10 mx-auto min-h-[calc(100vh-7rem)] max-w-[90rem] px-4 py-12 pt-32 md:pt-28">
10-
<div className="flex flex-col gap-8 lg:flex-row">
9+
<div className="relative z-10 mx-auto min-h-[calc(100vh-7rem)] max-w-[90rem] px-4 py-8 pt-28 sm:px-6 md:py-12 md:pt-28">
10+
<div className="flex flex-col gap-6 lg:flex-row lg:gap-8">
1111
<SidebarWrapper sidebarStructure={sidebarStructure} />
1212
<main className="flex min-w-0 flex-1 flex-col items-stretch">
1313
<div className="w-full" style={{ minHeight: "60vh" }}>

app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export default function RootLayout({
132132
<Navbar />
133133
</header>
134134

135-
<main id="main-content" tabIndex={-1}>
135+
<main className="pt-20" id="main-content" tabIndex={-1}>
136136
{children}
137137
</main>
138138

components/docs/sidebar/sidebar-wrapper.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const SidebarWrapper: FC<SidebarWrapperProps> = ({ sidebarStructure }) => {
6161
<>
6262
<SearchModal isOpen={isSearchOpen} onClose={() => setIsSearchOpen(false)} />
6363
<aside className="hidden w-72 shrink-0 lg:block">
64-
<div className="sticky top-32 flex h-[calc(100vh-8rem)] flex-col gap-4">
64+
<div className="sticky top-32 flex h-[calc(100vh-8rem)] flex-col gap-3">
6565
<SearchTrigger onClick={() => setIsSearchOpen(true)} />
6666
<div
6767
className="scrollbar-hide relative flex min-h-0 flex-1 flex-col overflow-auto overscroll-contain rounded-xl border border-gray-200 bg-white/90 shadow-lg backdrop-blur-md transition-shadow hover:shadow-xl dark:border-gray-800 dark:bg-gray-900/60"
@@ -72,7 +72,7 @@ const SidebarWrapper: FC<SidebarWrapperProps> = ({ sidebarStructure }) => {
7272
</div>
7373
</aside>
7474

75-
<div className="flex flex-col gap-4 lg:hidden">
75+
<div className="flex flex-col gap-3 lg:hidden">
7676
<SearchTrigger onClick={() => setIsSearchOpen(true)} />
7777
<DocSidebar sidebarStructure={sidebarStructure} />
7878
</div>
Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,70 @@
11
"use client";
22

3-
import { ArrowRight, Sparkles } from "lucide-react";
3+
import { AnimatePresence, motion } from "framer-motion";
4+
import { ArrowRight, Sparkles, X } from "lucide-react";
45
import Link from "next/link";
6+
import { useCallback, useEffect, useState } from "react";
7+
8+
const BANNER_DISMISS_KEY = "announcement-banner-dismissed-v1";
59

610
export default function AnnouncementBanner() {
11+
const [isVisible, setIsVisible] = useState(false);
12+
13+
useEffect(() => {
14+
const dismissed = sessionStorage.getItem(BANNER_DISMISS_KEY);
15+
if (!dismissed) {
16+
setIsVisible(true);
17+
}
18+
}, []);
19+
20+
const dismiss = useCallback(() => {
21+
setIsVisible(false);
22+
sessionStorage.setItem(BANNER_DISMISS_KEY, "1");
23+
}, []);
24+
725
return (
8-
<div className="relative isolate z-50 flex flex-col gap-2 overflow-hidden border-blue-100 border-b bg-gradient-to-r from-blue-50/80 via-white/80 to-blue-100/80 px-4 py-2.5 text-sm backdrop-blur-md md:flex-row md:items-center md:justify-center dark:border-blue-900/30 dark:from-blue-950/30 dark:via-gray-900/30 dark:to-blue-950/30">
9-
{/* Decorative gradients */}
10-
<div className="absolute inset-0 -z-10 bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-blue-400/20 via-transparent to-transparent dark:from-blue-500/10" />
11-
12-
{/* Content wrapper */}
13-
<div className="flex flex-wrap items-center justify-center gap-x-3 gap-y-1.5 text-center">
14-
<span className="inline-flex items-center gap-1.5 rounded-full bg-blue-100/80 px-2.5 py-0.5 font-semibold text-blue-700 text-xs ring-1 ring-blue-200 ring-inset dark:bg-blue-500/10 dark:text-blue-300 dark:ring-blue-500/20">
15-
<Sparkles className="h-3 w-3" />
16-
<span>New</span>
17-
</span>
18-
19-
<p className="text-gray-600 dark:text-gray-300">
20-
We just launched the new{" "}
21-
<span className="font-semibold text-gray-900 dark:text-white">
22-
Notification Generator
23-
</span>
24-
</p>
25-
26-
<Link
27-
className="group inline-flex items-center gap-1 font-medium text-blue-600 transition-colors hover:text-blue-500 dark:text-blue-400 dark:hover:text-blue-300"
28-
href="/notification-generator"
26+
<AnimatePresence>
27+
{!!isVisible && (
28+
<motion.div
29+
animate={{ height: "auto", opacity: 1 }}
30+
className="relative isolate overflow-hidden border-blue-200/60 border-b bg-gradient-to-r from-blue-600 via-indigo-600 to-blue-700 dark:border-blue-800/40 dark:from-blue-900/90 dark:via-indigo-900/90 dark:to-blue-900/90"
31+
exit={{ height: 0, opacity: 0 }}
32+
initial={{ height: "auto", opacity: 1 }}
33+
transition={{ duration: 0.2, ease: "easeInOut" }}
2934
>
30-
Check it out
31-
<ArrowRight className="h-3.5 w-3.5 transform-gpu transition-transform will-change-transform group-hover:translate-x-0.5" />
32-
</Link>
33-
</div>
34-
</div>
35+
<div className="absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iMjAiIGN5PSIyMCIgcj0iMSIgZmlsbD0icmdiYSgyNTUsMjU1LDI1NSwwLjA1KSIvPjwvc3ZnPg==')] opacity-50" />
36+
37+
<div className="relative mx-auto flex max-w-[90rem] items-center justify-center px-4 py-2">
38+
<div className="flex flex-wrap items-center justify-center gap-x-3 gap-y-1 text-center">
39+
<span className="inline-flex items-center gap-1 rounded-full bg-white/15 px-2 py-0.5 font-semibold text-white/95 text-xs backdrop-blur-sm">
40+
<Sparkles className="h-3 w-3" />
41+
New
42+
</span>
43+
44+
<p className="text-sm text-white/90">
45+
Explore the latest <span className="font-semibold text-white">stable</span> and <span className="font-semibold text-white">dev</span> builds using the <span className="font-semibold text-white">Build Explorer</span>.
46+
</p>
47+
48+
<Link
49+
className="group inline-flex items-center gap-1 font-medium text-sm text-white/95 underline decoration-white/30 underline-offset-2 transition-colors hover:decoration-white/60"
50+
href="/builds"
51+
>
52+
Check it out
53+
<ArrowRight className="h-3.5 w-3.5 transition-transform group-hover:translate-x-0.5" />
54+
</Link>
55+
</div>
56+
57+
<button
58+
aria-label="Dismiss announcement"
59+
className="absolute top-1/2 right-3 flex h-6 w-6 -translate-y-1/2 items-center justify-center rounded-full text-white/60 transition-colors hover:bg-white/10 hover:text-white"
60+
onClick={dismiss}
61+
type="button"
62+
>
63+
<X className="h-3.5 w-3.5" />
64+
</button>
65+
</div>
66+
</motion.div>
67+
)}
68+
</AnimatePresence>
3569
);
3670
}

0 commit comments

Comments
 (0)