Leaflet Blog in Deno Fresh
1import { Footer } from "../components/footer.tsx";
2import type { ComponentChildren } from "preact";
3import { useEffect, useState } from "preact/hooks";
4
5export function Layout({ children }: { children: ComponentChildren }) {
6 const [isScrolled, setIsScrolled] = useState(false);
7
8 // Get current path to determine active nav item
9 const path = typeof window !== "undefined" ? window.location.pathname : "";
10 const isActive = (href: string) => {
11 if (href === "/") {
12 return path === "/" || path.startsWith("/post/");
13 }
14 return path === href;
15 };
16
17 useEffect(() => {
18 const handleScroll = () => {
19 setIsScrolled(window.scrollY > 0);
20 };
21
22 window.addEventListener("scroll", handleScroll);
23 handleScroll(); // Check initial scroll position
24
25 return () => window.removeEventListener("scroll", handleScroll);
26 }, []);
27
28 return (
29 <div class="flex flex-col min-h-dvh">
30 <nav class="w-full sticky top-0 z-50 backdrop-blur-sm bg-white/80 dark:bg-black/80 transition-[padding,border-color] duration-200">
31 <div class="relative">
32 <div
33 class="absolute inset-x-0 bottom-0 h-2 diagonal-pattern opacity-0 transition-opacity duration-300"
34 style={{ opacity: isScrolled ? 0.25 : 0 }}
35 />
36 <div class="max-w-screen-2xl mx-auto px-8 py-5 flex justify-between items-center">
37 <div class="flex items-center gap-7">
38 <a href="/" class="font-serif text-xl">
39 knotbin
40 </a>
41 <div class="h-4 w-px bg-slate-200 dark:bg-slate-700"></div>
42 <div class="text-base flex items-center gap-7">
43 <a href="/" class="relative group" data-current={isActive("/")}>
44 <span class="opacity-50 group-hover:opacity-100 group-data-[current=true]:opacity-100 transition-opacity">
45 blog
46 </span>
47 <div class="absolute bottom-0 left-0 w-full h-px bg-current origin-left scale-x-0 group-hover:scale-x-100 group-data-[current=true]:scale-x-100 transition-transform duration-300 ease-in-out" />
48 </a>
49 <a
50 href="/about"
51 class="relative group"
52 data-current={isActive("/about")}
53 >
54 <span class="opacity-50 group-hover:opacity-100 group-data-[current=true]:opacity-100 transition-opacity">
55 about
56 </span>
57 <div class="absolute bottom-0 left-0 w-full h-px bg-current origin-left scale-x-0 group-hover:scale-x-100 group-data-[current=true]:scale-x-100 transition-transform duration-300 ease-in-out" />
58 </a>
59 </div>
60 </div>
61 </div>
62 </div>
63 </nav>
64
65 <main class="flex-1">{children}</main>
66
67 <Footer />
68 </div>
69 );
70}