import type { DocSection } from "@/services/DocCache"; import type { Data } from "@/pages/+data"; import { createSignal, createEffect, For } from "solid-js"; import { useData } from "vike-solid/useData"; import { Link } from "@/components/Link"; import clsx from "clsx"; export function TableOfContents() { const data = useData(); if (!data.sections) return null; const [currentSection, setCurrentSection] = createSignal( data.sections[0]?.hash, ); const getHeadings = () => { return data.sections .flatMap((section) => [section, ...section.children]) .map((section) => { if (!section.hash) return null; const el = document.getElementById(section.hash); console.log(section.hash, el); if (!el) return null; const style = window.getComputedStyle(el); const scrollMt = Number.parseFloat(style.scrollMarginTop); const top = window.scrollY + el.getBoundingClientRect().top - scrollMt; return { id: section.hash, top, level: section.level }; }) .filter( (x): x is { id: string; top: number; level: number } => x !== null, ); }; createEffect(() => { if (data.sections.length === 0) return; const headings = getHeadings(); function onScroll() { const top = window.scrollY; let current = headings[0]?.id; for (const heading of headings) { if (top < heading.top - 10) break; current = heading.id; } setCurrentSection(current); } window.addEventListener("scroll", onScroll, { passive: true }); onScroll(); return () => { window.removeEventListener("scroll", onScroll); }; }, [getHeadings, data.sections]); function isActive(section: DocSection) { if (section.hash === currentSection()) return true; if (!section.children) return false; return ( section.children.findIndex((child) => { console.log(child.hash, currentSection()); return child.hash === currentSection(); }) !== -1 ); } return ( ); }