mirror of
https://github.com/jimeh/commonflow.org.git
synced 2026-02-19 05:46:40 +00:00
wip: getting closer
This commit is contained in:
@@ -43,31 +43,37 @@ const { version } = Astro.props;
|
||||
<nav class="hidden md:flex items-center gap-1">
|
||||
<a
|
||||
href="#about"
|
||||
class="inline-flex items-center px-4 py-2 text-sm font-medium rounded-lg
|
||||
transition-colors cursor-pointer
|
||||
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-slate-400
|
||||
hover:bg-gray-100 hover:text-gray-950
|
||||
dark:hover:bg-slate-800 dark:hover:text-slate-50"
|
||||
data-nav-link
|
||||
data-section-id="about"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="#spec"
|
||||
class="inline-flex items-center px-4 py-2 text-sm font-medium rounded-lg
|
||||
transition-colors cursor-pointer
|
||||
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-slate-400
|
||||
hover:bg-gray-100 hover:text-gray-950
|
||||
dark:hover:bg-slate-800 dark:hover:text-slate-50"
|
||||
data-nav-link
|
||||
data-section-id="spec"
|
||||
>
|
||||
Spec
|
||||
</a>
|
||||
<a
|
||||
href="#faq"
|
||||
class="inline-flex items-center px-4 py-2 text-sm font-medium rounded-lg
|
||||
transition-colors cursor-pointer
|
||||
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-slate-400
|
||||
hover:bg-gray-100 hover:text-gray-950
|
||||
dark:hover:bg-slate-800 dark:hover:text-slate-50"
|
||||
data-nav-link
|
||||
data-section-id="faq"
|
||||
>
|
||||
FAQ
|
||||
</a>
|
||||
@@ -133,19 +139,28 @@ const { version } = Astro.props;
|
||||
</div>
|
||||
<a
|
||||
href="#about"
|
||||
class="block py-2 text-gray-600 dark:text-slate-400 hover:text-sky-600"
|
||||
class="nav-link block py-2 text-gray-600 dark:text-slate-400
|
||||
hover:text-sky-600"
|
||||
data-nav-link
|
||||
data-section-id="about"
|
||||
>
|
||||
About
|
||||
</a>
|
||||
<a
|
||||
href="#spec"
|
||||
class="block py-2 text-gray-600 dark:text-slate-400 hover:text-sky-600"
|
||||
class="nav-link block py-2 text-gray-600 dark:text-slate-400
|
||||
hover:text-sky-600"
|
||||
data-nav-link
|
||||
data-section-id="spec"
|
||||
>
|
||||
Spec
|
||||
</a>
|
||||
<a
|
||||
href="#faq"
|
||||
class="block py-2 text-gray-600 dark:text-slate-400 hover:text-sky-600"
|
||||
class="nav-link block py-2 text-gray-600 dark:text-slate-400
|
||||
hover:text-sky-600"
|
||||
data-nav-link
|
||||
data-section-id="faq"
|
||||
>
|
||||
FAQ
|
||||
</a>
|
||||
@@ -162,23 +177,22 @@ const { version } = Astro.props;
|
||||
|
||||
if (!header || !hero) return;
|
||||
|
||||
// Show/hide header based on scroll past hero
|
||||
// Show header when top half of hero is above the fold
|
||||
const topMargin = Math.floor(window.innerHeight / 2);
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (entry.isIntersecting) {
|
||||
header.classList.add("translate-y-[-100%]");
|
||||
header.classList.remove("border-gray-200", "dark:border-slate-800");
|
||||
} else {
|
||||
header.classList.remove("translate-y-[-100%]");
|
||||
header.classList.add("border-gray-200", "dark:border-slate-800");
|
||||
}
|
||||
},
|
||||
{ threshold: 0, rootMargin: `-${topMargin}px 0px 0px 0px` }
|
||||
);
|
||||
// Show/hide header based on scroll position
|
||||
// Show header once scrolled down by the navbar height (64px)
|
||||
const navbarHeight = 64;
|
||||
|
||||
observer.observe(hero);
|
||||
function updateHeaderVisibility() {
|
||||
if (window.scrollY >= navbarHeight) {
|
||||
header.classList.remove("translate-y-[-100%]");
|
||||
header.classList.add("border-gray-200", "dark:border-slate-800");
|
||||
} else {
|
||||
header.classList.add("translate-y-[-100%]");
|
||||
header.classList.remove("border-gray-200", "dark:border-slate-800");
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", updateHeaderVisibility, { passive: true });
|
||||
updateHeaderVisibility();
|
||||
|
||||
// Mobile menu toggle
|
||||
if (mobileMenuBtn && mobileNav) {
|
||||
@@ -193,6 +207,53 @@ 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 });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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