-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTableOfContents.astro
More file actions
60 lines (56 loc) · 1.54 KB
/
Copy pathTableOfContents.astro
File metadata and controls
60 lines (56 loc) · 1.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
---
interface Heading {
depth: number;
slug: string;
text: string;
}
const { headings = [] } = Astro.props as { headings: Heading[] };
// Split into h2 sections with their h3+ children
const sections: { heading: Heading; children: Heading[] }[] = [];
for (const h of headings) {
if (h.depth === 2) {
sections.push({ heading: h, children: [] });
} else if (sections.length > 0) {
sections[sections.length - 1].children.push(h);
}
}
---
{sections.length > 0 && (
<aside class="sidebar-toc">
<div class="sidebar-toc-title">Table of contents</div>
<ul>
{sections.map((s) =>
s.children.length === 0 ? (
<li>
<a href={`#${s.heading.slug}`}>{s.heading.text}</a>
</li>
) : (
<li>
<details class="toc-details">
<summary>
<a href={`#${s.heading.slug}`} class="toc-section-link">{s.heading.text}</a>
</summary>
<ul>
{s.children.map((c) => (
<li style={c.depth > 3 ? `padding-left: ${(c.depth - 3) * 0.75}rem` : ""}>
<a href={`#${c.slug}`}>{c.text}</a>
</li>
))}
</ul>
</details>
</li>
)
)}
</ul>
</aside>
)}
<script>
document.querySelectorAll('.toc-section-link').forEach((link) => {
link.addEventListener('click', (e) => {
const details = link.closest('details');
if (details && !details.open) {
details.open = true;
}
});
});
</script>