Add generateToc utility and GSAP's ScrollTrigger library

A new utility function `generateToc` has been created in `src/utils/generateToc.ts` for generation of table of contents. The utility includes child component extraction and error handling for orphan headings. Additionally, GSAP's ScrollTrigger library has been included under `public/scripts/vendor/gsap/` to manage scroll-triggered animations.
This commit is contained in:
Emil Gulamov 2024-04-02 01:43:19 +04:00
parent 559569cf1c
commit 103b3cb75a
2 changed files with 62 additions and 0 deletions

File diff suppressed because one or more lines are too long

51
src/utils/generateToc.ts Normal file
View file

@ -0,0 +1,51 @@
// https://github.com/withastro/docs/blob/882e0b0a9d16d1c822cb8c230a62a4bfcd308605/src/util/generateToc.ts
import type { MarkdownHeading } from 'astro';
export interface TocItem extends MarkdownHeading {
children: TocItem[];
}
function diveChildren(item: TocItem, depth: number): TocItem[] {
if (depth === 1) {
return item.children;
} else {
// e.g., 2
return diveChildren(item.children[item.children.length - 1], depth - 1);
}
}
export default function generateToc(headings: MarkdownHeading[], title = 'Overview') {
const overview = { depth: 2, slug: 'overview', text: title };
headings = [overview, ...headings.filter(({ depth }) => depth > 1 && depth < 4)];
const toc: Array<TocItem> = [];
for (const heading of headings) {
if (toc.length === 0) {
toc.push({
...heading,
children: [],
});
} else {
const lastItemInToc = toc[toc.length - 1];
if (heading.depth < lastItemInToc.depth) {
throw new Error(`Orphan heading found: ${heading.text}.`);
}
if (heading.depth === lastItemInToc.depth) {
// same depth
toc.push({
...heading,
children: [],
});
} else {
// higher depth
// push into children, or children' children alike
const gap = heading.depth - lastItemInToc.depth;
const target = diveChildren(lastItemInToc, gap);
target.push({
...heading,
children: [],
});
}
}
}
return toc;
}