54 lines
1.2 KiB
Text
54 lines
1.2 KiB
Text
---
|
|
import TableOfContentsHeading from "./TableOfContentsHeading.astro";
|
|
|
|
// https://kld.dev/building-table-of-contents/
|
|
const { headings } = Astro.props;
|
|
const toc = buildToc(headings);
|
|
|
|
export interface Heading {
|
|
depth: number;
|
|
slug: string;
|
|
text: string;
|
|
}
|
|
|
|
function buildToc(headings: Heading[]) {
|
|
const toc: Heading[] = [];
|
|
const parentHeadings = new Map();
|
|
headings.forEach((h) => {
|
|
const heading = { ...h, subheadings: [] };
|
|
parentHeadings.set(heading.depth, heading);
|
|
if (heading.depth === 2) {
|
|
toc.push(heading);
|
|
} else {
|
|
parentHeadings.get(heading.depth - 1).subheadings.push(heading);
|
|
}
|
|
});
|
|
return toc;
|
|
}
|
|
---
|
|
|
|
<details
|
|
open
|
|
class="animate rounded-lg border border-black/15 dark:border-white/20"
|
|
>
|
|
<summary>Table of Contents</summary>
|
|
<nav class="">
|
|
<ul class="py-3">
|
|
{toc.map((heading) => <TableOfContentsHeading heading={heading} />)}
|
|
</ul>
|
|
</nav>
|
|
</details>
|
|
|
|
<style>
|
|
summary {
|
|
@apply cursor-pointer rounded-t-lg px-3 py-1.5 font-medium transition-colors;
|
|
}
|
|
|
|
summary:hover {
|
|
@apply bg-black/5 dark:bg-white/5;
|
|
}
|
|
|
|
details[open] summary {
|
|
@apply bg-black/5 dark:bg-white/5;
|
|
}
|
|
</style>
|