diff options
author | 2021-08-14 00:58:00 +0000 | |
---|---|---|
committer | 2021-08-26 12:15:33 -0700 | |
commit | b7ada11ddbabe4dd2f0798e140e5b280de4d6952 (patch) | |
tree | c01ff3eee4f770fc108c19d126dce31d9cbe5e51 /examples/docs/src/components/RightSidebar/TableOfContents.tsx | |
parent | 59cc62f7bd53dbcb6ad8051fa501b7b797614178 (diff) | |
download | astro-b7ada11ddbabe4dd2f0798e140e5b280de4d6952.tar.gz astro-b7ada11ddbabe4dd2f0798e140e5b280de4d6952.tar.zst astro-b7ada11ddbabe4dd2f0798e140e5b280de4d6952.zip |
WIP update examples/docs/
Diffstat (limited to 'examples/docs/src/components/RightSidebar/TableOfContents.tsx')
-rw-r--r-- | examples/docs/src/components/RightSidebar/TableOfContents.tsx | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/examples/docs/src/components/RightSidebar/TableOfContents.tsx b/examples/docs/src/components/RightSidebar/TableOfContents.tsx new file mode 100644 index 000000000..d8ea998d4 --- /dev/null +++ b/examples/docs/src/components/RightSidebar/TableOfContents.tsx @@ -0,0 +1,45 @@ +import type { FunctionalComponent } from 'preact'; +import { h, Fragment } from 'preact'; +import { useState, useEffect, useRef } from 'preact/hooks'; + +const TableOfContents: FunctionalComponent<{ headers: any[] }> = ({ headers = [] }) => { + const itemOffsets = useRef([]); + const [activeId, setActiveId] = useState<string>(undefined); + + useEffect(() => { + const getItemOffsets = () => { + const titles = document.querySelectorAll('article :is(h1, h2, h3, h4)'); + itemOffsets.current = Array.from(titles).map((title) => ({ + id: title.id, + topOffset: title.getBoundingClientRect().top + window.scrollY, + })); + }; + + getItemOffsets(); + window.addEventListener('resize', getItemOffsets); + + return () => { + window.removeEventListener('resize', getItemOffsets); + }; + }, []); + + return ( + <> + <h2 class="heading">On this page</h2> + <ul> + <li class={`header-link depth-2 ${activeId === 'overview' ? 'active' : ''}`.trim()}> + <a href="#overview">Overview</a> + </li> + {headers + .filter(({ depth }) => depth > 1 && depth < 4) + .map((header) => ( + <li class={`header-link depth-${header.depth} ${activeId === header.slug ? 'active' : ''}`.trim()}> + <a href={`#${header.slug}`}>{header.text}</a> + </li> + ))} + </ul> + </> + ); +}; + +export default TableOfContents; |