feat: enhance header and mobile navigation with smooth scrolling and active link highlighting
This commit is contained in:
@@ -16,9 +16,49 @@ const { title = 'Talk Pro — One User. Multiple Worlds.' } = Astro.props
|
||||
<title>{title}</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
</head>
|
||||
<body class="bg-surface font-sans overflow-x-hidden">
|
||||
<slot />
|
||||
<script>
|
||||
(() => {
|
||||
const header = document.getElementById('site-header');
|
||||
const getOffset = () => header ? header.offsetHeight : 0;
|
||||
|
||||
// Smooth scroll with header offset
|
||||
document.querySelectorAll('a[href^="#"]').forEach(link => {
|
||||
link.addEventListener('click', e => {
|
||||
const href = link.getAttribute('href');
|
||||
if (!href || href === '#') return;
|
||||
const target = document.querySelector(href);
|
||||
if (!target) return;
|
||||
e.preventDefault();
|
||||
const top = target.getBoundingClientRect().top + window.scrollY - getOffset();
|
||||
window.scrollTo({ top, behavior: 'smooth' });
|
||||
});
|
||||
});
|
||||
|
||||
// Active nav highlighting via IntersectionObserver
|
||||
const navLinks = document.querySelectorAll('[data-nav-link]');
|
||||
const sections = Array.from(navLinks)
|
||||
.map(l => document.querySelector(l.getAttribute('href') ?? ''))
|
||||
.filter(Boolean) as Element[];
|
||||
|
||||
if ('IntersectionObserver' in window && sections.length) {
|
||||
const observer = new IntersectionObserver(entries => {
|
||||
const visible = entries
|
||||
.filter(e => e.isIntersecting)
|
||||
.sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0];
|
||||
if (!visible) return;
|
||||
navLinks.forEach(link => {
|
||||
const active = link.getAttribute('href') === `#${visible.target.id}`;
|
||||
link.classList.toggle('!text-[#f28a4b]', active);
|
||||
link.classList.toggle('text-[#7a726d]', !active);
|
||||
});
|
||||
}, { rootMargin: '-30% 0px -60% 0px', threshold: 0 });
|
||||
sections.forEach(s => observer.observe(s));
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user