diff --git a/fresh.gen.ts b/fresh.gen.ts index a162a81..c1205e2 100644 --- a/fresh.gen.ts +++ b/fresh.gen.ts @@ -11,6 +11,8 @@ import * as $post_slug_ from "./routes/post/[slug].tsx"; import * as $posts from "./routes/posts.tsx"; import * as $projects from "./routes/projects.tsx"; import * as $Example from "./islands/Example.tsx"; +import * as $NavigationBar from "./islands/NavigationBar.tsx"; +import * as $ScrollUpButton from "./islands/ScrollUpButton.tsx"; import type { Manifest } from "$fresh/server.ts"; const manifest = { @@ -26,6 +28,8 @@ const manifest = { }, islands: { "./islands/Example.tsx": $Example, + "./islands/NavigationBar.tsx": $NavigationBar, + "./islands/ScrollUpButton.tsx": $ScrollUpButton, }, baseUrl: import.meta.url, } satisfies Manifest; diff --git a/islands/NavigationBar.tsx b/islands/NavigationBar.tsx new file mode 100644 index 0000000..9287c1b --- /dev/null +++ b/islands/NavigationBar.tsx @@ -0,0 +1,83 @@ +// islands/NavigationBar.tsx +import { useComputed, useSignal } from "@preact/signals"; +import { useEffect } from "preact/hooks"; +import { LuCodeXml, LuHouse, LuNotebookPen } from "@preact-icons/lu"; + +interface NavigationBarProps { + currentPath: string; +} + +export default function NavigationBar({ currentPath }: NavigationBarProps) { + const isScrolling = useSignal(false); + const prevScrollPos = useSignal(0); + const isVisible = useComputed(() => { + if (prevScrollPos.value < 50) return true; + + const currentPos = typeof window !== "undefined" ? globalThis.scrollY : 0; + return prevScrollPos.value > currentPos; + }); + + const isPostsPath = (path: string) => { + return path.startsWith("/posts") || path.startsWith("/post/"); + }; + + useEffect(() => { + let scrollTimer: number | undefined; + + const handleScroll = () => { + isScrolling.value = true; + prevScrollPos.value = globalThis.scrollY; + + if (scrollTimer) clearTimeout(scrollTimer); + + scrollTimer = setTimeout(() => { + isScrolling.value = false; + }, 200); + }; + + globalThis.addEventListener("scroll", handleScroll); + + return () => { + globalThis.removeEventListener("scroll", handleScroll); + if (scrollTimer) clearTimeout(scrollTimer); + }; + }, []); + + return ( +