diff --git a/app/partials/TableOfContents.tsx b/app/partials/TableOfContents.tsx index 4eeb1df..c3d297d 100644 --- a/app/partials/TableOfContents.tsx +++ b/app/partials/TableOfContents.tsx @@ -16,19 +16,23 @@ export function TableOfContents() { 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 }; + return { id: section.hash, top, level: section.level }; }) - .filter((x): x is { id: string; top: number } => x !== null); + .filter( + (x): x is { id: string; top: number; level: number } => x !== null, + ); }; createEffect(() => { @@ -46,8 +50,11 @@ export function TableOfContents() { } setCurrentSection(current); } + window.addEventListener("scroll", onScroll, { passive: true }); + onScroll(); + return () => { window.removeEventListener("scroll", onScroll); }; @@ -55,10 +62,14 @@ export function TableOfContents() { function isActive(section: DocSection) { if (section.hash === currentSection()) return true; - return false; - // if (!section.children) return false; + if (!section.children) return false; - // return section.children.findIndex(isActive) > -1; + return ( + section.children.findIndex((child) => { + console.log(child.hash, currentSection()); + return child.hash === currentSection(); + }) !== -1 + ); } return ( @@ -87,6 +98,26 @@ export function TableOfContents() { {section.content} + {section.children.length > 0 && ( +
    + + {(subsection) => ( +
  1. + + {subsection.content} + +
  2. + )} +
    +
+ )} )} diff --git a/app/services/DocCache.ts b/app/services/DocCache.ts index 99646ed..e1c71e5 100644 --- a/app/services/DocCache.ts +++ b/app/services/DocCache.ts @@ -22,6 +22,7 @@ export type DocSection = { content: string; hash?: string; subsections: string[]; + children: DocSection[]; level?: number; }; @@ -98,15 +99,32 @@ class DocCache { if (["heading", "paragraph"].includes(node.type)) { const content = this.nodeToString(node).trim(); - if (node.type === "heading" && node.attributes?.level <= 2) { + if (node.type === "heading" && node.attributes?.level <= 3) { const hash = (node.attributes?.id as string) ?? this.slugify(content); const subsections: string[] = []; - sections.push({ - content, - hash, - subsections, - level: node.attributes?.level, - }); + + if (node.attributes?.level === 2) { + sections.push({ + content, + hash, + subsections, + children: [], + level: node.attributes?.level, + }); + } else if (node.attributes?.level === 3) { + const lastSection = sections.at(-1); + + if (lastSection) { + lastSection.subsections.push(hash); + lastSection.children.push({ + content, + hash, + subsections, + children: [], + level: node.attributes?.level, + }); + } + } } else { sections.at(-1)?.subsections.push(content); } diff --git a/temp.json b/temp.json new file mode 100644 index 0000000..9049d0b --- /dev/null +++ b/temp.json @@ -0,0 +1 @@ +[{"content":"qu-est-ce-que-le-hook-use-reducer","hash":"qu-est-ce-que-le-hook-use-reducer","level":2,"subsections":[{"content":"quand-utiliser-use-reducer","hash":"quand-utiliser-use-reducer","level":3,"subsections":[{"content":"a-quoi-ressemble-un-reducer","hash":"a-quoi-ressemble-un-reducer","level":2,"subsections":[{"content":"comment-utiliser-use-reducer","hash":"comment-utiliser-use-reducer","level":2,"subsections":[{"content":"on-nettoie-tout-ca","hash":"on-nettoie-tout-ca","level":2,"subsections":[{"content":"typage-des-actions","hash":"typage-des-actions","level":3,"subsections":[{"content":"action-creators","hash":"action-creators","level":3,"subsections":[{"content":"les-fichiers-complets","hash":"les-fichiers-complets","level":2,"subsections":[{"content":"fichier-counter-jsx-ou-counter-tsx","hash":"fichier-counter-jsx-ou-counter-tsx","level":3,"subsections":[{"content":"c-est-l-heure-des-questions","hash":"c-est-l-heure-des-questions","level":2,"subsections":[{"content":"conclusion","hash":"conclusion","level":2,"subsections":[]}]}]}]}]}]}]}]}]}]}]}] \ No newline at end of file