blog.z0x.ca/src/components/TableOfContentsHeading.astro
2024-09-10 17:51:46 -07:00

53 lines
1.4 KiB
Text

---
import type { Heading } from './TableOfContents.astro'
import Link from './Link.astro'
const { heading } = Astro.props
---
<li
class="list-inside list-disc px-6 py-1.5 text-sm text-foreground/60 xl:list-none xl:p-0"
>
<Link href={'#' + heading.slug} class="toc-link" data-heading={heading.slug}>
{heading.text}
</Link>
{
heading.subheadings.length > 0 && (
<ul class="translate-x-3 xl:ml-4 xl:mt-2 xl:translate-x-0 xl:space-y-2">
{heading.subheadings.map((subheading: Heading) => (
<Astro.self heading={subheading} />
))}
</ul>
)
}
</li>
<script>
function updateActiveHeading() {
const headings = document.querySelectorAll('h2, h3, h4, h5, h6')
const tocLinks = document.querySelectorAll('.toc-link')
let currentHeading = ''
headings.forEach((heading) => {
const top = heading.getBoundingClientRect().top
if (top < 200) {
currentHeading = heading.id
}
})
tocLinks.forEach((link) => {
const headingSlug = link.getAttribute('data-heading')
if (headingSlug === currentHeading) {
link.classList.add('underline')
link.classList.add('text-foreground')
} else {
link.classList.remove('underline')
link.classList.remove('text-foreground')
}
})
}
window.addEventListener('scroll', updateActiveHeading)
window.addEventListener('load', updateActiveHeading)
</script>