mirror of
https://github.com/jimeh/commonflow.org.git
synced 2026-02-19 05:46:40 +00:00
wip: DRY up things
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
---
|
||||
import VersionSelector from "./VersionSelector.astro";
|
||||
import ThemeToggle from "./ThemeToggle.astro";
|
||||
import GitHubIcon from "./icons/GitHubIcon.astro";
|
||||
import { config } from "../config";
|
||||
|
||||
interface Props {
|
||||
@@ -8,6 +9,12 @@ interface Props {
|
||||
}
|
||||
|
||||
const { version } = Astro.props;
|
||||
|
||||
const navItems = [
|
||||
{ id: "about", label: "About" },
|
||||
{ id: "spec", label: "Spec" },
|
||||
{ id: "faq", label: "FAQ" },
|
||||
];
|
||||
---
|
||||
|
||||
<header
|
||||
@@ -41,42 +48,22 @@ const { version } = Astro.props;
|
||||
|
||||
<!-- Desktop Navigation -->
|
||||
<nav class="hidden md:flex items-center gap-1">
|
||||
<a
|
||||
href="#about"
|
||||
class="nav-link inline-flex items-center px-4 py-2 text-sm font-medium
|
||||
rounded-lg transition-colors cursor-pointer
|
||||
text-gray-600 dark:text-neutral-400
|
||||
hover:bg-gray-100 hover:text-gray-950
|
||||
dark:hover:bg-neutral-800 dark:hover:text-neutral-50"
|
||||
data-nav-link
|
||||
data-section-id="about"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="#spec"
|
||||
class="nav-link inline-flex items-center px-4 py-2 text-sm font-medium
|
||||
rounded-lg transition-colors cursor-pointer
|
||||
text-gray-600 dark:text-neutral-400
|
||||
hover:bg-gray-100 hover:text-gray-950
|
||||
dark:hover:bg-neutral-800 dark:hover:text-neutral-50"
|
||||
data-nav-link
|
||||
data-section-id="spec"
|
||||
>
|
||||
Spec
|
||||
</a>
|
||||
<a
|
||||
href="#faq"
|
||||
class="nav-link inline-flex items-center px-4 py-2 text-sm font-medium
|
||||
rounded-lg transition-colors cursor-pointer
|
||||
text-gray-600 dark:text-neutral-400
|
||||
hover:bg-gray-100 hover:text-gray-950
|
||||
dark:hover:bg-neutral-800 dark:hover:text-neutral-50"
|
||||
data-nav-link
|
||||
data-section-id="faq"
|
||||
>
|
||||
FAQ
|
||||
</a>
|
||||
{
|
||||
navItems.map((item) => (
|
||||
<a
|
||||
href={`#${item.id}`}
|
||||
class="nav-link inline-flex items-center px-4 py-2 text-sm font-medium
|
||||
rounded-lg transition-colors cursor-pointer
|
||||
text-gray-600 dark:text-neutral-400
|
||||
hover:bg-gray-100 hover:text-gray-950
|
||||
dark:hover:bg-neutral-800 dark:hover:text-neutral-50"
|
||||
data-nav-link
|
||||
data-section-id={item.id}
|
||||
>
|
||||
{item.label}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</nav>
|
||||
|
||||
<!-- Right side: Theme, GitHub -->
|
||||
@@ -93,12 +80,7 @@ const { version } = Astro.props;
|
||||
hover:bg-gray-100 dark:hover:bg-neutral-800"
|
||||
aria-label="View on GitHub"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
|
||||
clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
<GitHubIcon />
|
||||
</a>
|
||||
|
||||
<!-- Mobile menu button -->
|
||||
@@ -137,38 +119,26 @@ const { version } = Astro.props;
|
||||
versions={Array.from(config.versions)}
|
||||
/>
|
||||
</div>
|
||||
<a
|
||||
href="#about"
|
||||
class="nav-link block py-2 text-gray-600 dark:text-neutral-400
|
||||
hover:text-sky-600"
|
||||
data-nav-link
|
||||
data-section-id="about"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="#spec"
|
||||
class="nav-link block py-2 text-gray-600 dark:text-neutral-400
|
||||
hover:text-sky-600"
|
||||
data-nav-link
|
||||
data-section-id="spec"
|
||||
>
|
||||
Spec
|
||||
</a>
|
||||
<a
|
||||
href="#faq"
|
||||
class="nav-link block py-2 text-gray-600 dark:text-neutral-400
|
||||
hover:text-sky-600"
|
||||
data-nav-link
|
||||
data-section-id="faq"
|
||||
>
|
||||
FAQ
|
||||
</a>
|
||||
{
|
||||
navItems.map((item) => (
|
||||
<a
|
||||
href={`#${item.id}`}
|
||||
class="nav-link block py-2 text-gray-600 dark:text-neutral-400
|
||||
hover:text-sky-600"
|
||||
data-nav-link
|
||||
data-section-id={item.id}
|
||||
>
|
||||
{item.label}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<script>
|
||||
import { initActiveSectionTracker } from "../scripts/activeSectionTracker";
|
||||
|
||||
function initHeader() {
|
||||
const header = document.getElementById("site-header");
|
||||
const hero = document.getElementById("hero");
|
||||
@@ -212,51 +182,10 @@ const { version } = Astro.props;
|
||||
}
|
||||
|
||||
// Active section tracking for nav links
|
||||
const navLinks = document.querySelectorAll("[data-nav-link]");
|
||||
const sections: { id: string; element: Element }[] = [];
|
||||
|
||||
// Collect unique section IDs
|
||||
const seenIds = new Set<string>();
|
||||
navLinks.forEach((link) => {
|
||||
const id = link.getAttribute("data-section-id");
|
||||
if (id && !seenIds.has(id)) {
|
||||
seenIds.add(id);
|
||||
const section = document.getElementById(id);
|
||||
if (section) {
|
||||
sections.push({ id, element: section });
|
||||
}
|
||||
}
|
||||
initActiveSectionTracker({
|
||||
linkSelector: "[data-nav-link]",
|
||||
defaultToFirst: false,
|
||||
});
|
||||
|
||||
function updateActiveNavSection() {
|
||||
const headerOffset = 100;
|
||||
let activeId: string | null = null;
|
||||
|
||||
for (const { id, element } of sections) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
if (rect.top <= headerOffset) {
|
||||
activeId = id;
|
||||
}
|
||||
}
|
||||
|
||||
navLinks.forEach((link) => {
|
||||
const linkId = link.getAttribute("data-section-id");
|
||||
link.classList.toggle("active", linkId === activeId);
|
||||
});
|
||||
}
|
||||
|
||||
let ticking = false;
|
||||
window.addEventListener("scroll", () => {
|
||||
if (!ticking) {
|
||||
requestAnimationFrame(() => {
|
||||
updateActiveNavSection();
|
||||
ticking = false;
|
||||
});
|
||||
ticking = true;
|
||||
}
|
||||
});
|
||||
|
||||
updateActiveNavSection();
|
||||
}
|
||||
|
||||
// Initialize on load
|
||||
|
||||
Reference in New Issue
Block a user