diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-01-11 15:28:08 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-01-11 15:33:04 +0100 |
| commit | 99014e5634c6216173bf90117750f95172924134 (patch) | |
| tree | a1e53640de7ecc7af4cfe4b29e3c78516504d485 | |
| parent | 1a74d19cf4ad080e822e84472288c701ce001e60 (diff) | |
fix(toc): render on each route change and exclude aside titles
On subject pages for example, the table of contents was not updated on
route change. So I added router.asPath as dependency of useEffect.
I also changed the query to exclude all titles in aside (ToC, widgets).
| -rw-r--r-- | src/components/ToC/ToC.tsx | 3 | ||||
| -rw-r--r-- | src/utils/hooks/useHeadingsTree.tsx | 27 |
2 files changed, 20 insertions, 10 deletions
diff --git a/src/components/ToC/ToC.tsx b/src/components/ToC/ToC.tsx index 3ab482c..b172b3a 100644 --- a/src/components/ToC/ToC.tsx +++ b/src/components/ToC/ToC.tsx @@ -1,6 +1,5 @@ import { t } from '@lingui/macro'; import { Heading } from '@ts/types/app'; -import { slugify } from '@utils/helpers/slugify'; import useHeadingsTree from '@utils/hooks/useHeadingsTree'; import styles from './ToC.module.scss'; @@ -10,8 +9,6 @@ const ToC = () => { const getItems = (headings: Heading[]) => { return headings.map((heading) => { - if (heading.id === slugify(title)) return; - return ( <li key={heading.id}> <a href={`#${heading.id}`}>{heading.title}</a> diff --git a/src/utils/hooks/useHeadingsTree.tsx b/src/utils/hooks/useHeadingsTree.tsx index 745ba23..267e97d 100644 --- a/src/utils/hooks/useHeadingsTree.tsx +++ b/src/utils/hooks/useHeadingsTree.tsx @@ -1,10 +1,24 @@ import { Heading } from '@ts/types/app'; import { slugify } from '@utils/helpers/slugify'; +import { useRouter } from 'next/router'; import { useCallback, useEffect, useMemo, useState } from 'react'; const useHeadingsTree = (wrapper: string) => { - const [headingsTree, setHeadingsTree] = useState<Heading[]>([]); + const router = useRouter(); const depths = useMemo(() => ['h2', 'h3', 'h4', 'h5', 'h6'], []); + const [allHeadings, setAllHeadings] = + useState<NodeListOf<HTMLHeadingElement>>(); + + useEffect(() => { + const query = depths + .map((depth) => `${wrapper} > *:not(aside) ${depth}`) + .join(', '); + const result: NodeListOf<HTMLHeadingElement> = + document.querySelectorAll(query); + setAllHeadings(result); + }, [depths, wrapper, router.asPath]); + + const [headingsTree, setHeadingsTree] = useState<Heading[]>([]); const getElementDepth = useCallback( (el: HTMLHeadingElement) => { @@ -78,12 +92,11 @@ const useHeadingsTree = (wrapper: string) => { ); useEffect(() => { - const query = depths.map((depth) => `${wrapper} ${depth}`).join(', '); - const headings: NodeListOf<HTMLHeadingElement> = - document.querySelectorAll(query); - const headingsList = getHeadingsList(headings); - setHeadingsTree(headingsList); - }, [depths, wrapper, getHeadingsList]); + if (allHeadings) { + const headingsList = getHeadingsList(allHeadings); + setHeadingsTree(headingsList); + } + }, [allHeadings, getHeadingsList]); return headingsTree; }; |
