diff options
author | 2021-05-27 09:16:14 -0500 | |
---|---|---|
committer | 2021-05-27 09:16:14 -0500 | |
commit | 5247a23cbe534d79cdf4abe4c200a351dddc5dc2 (patch) | |
tree | 343c54fb5471998b4e1a9150d15ba63028548928 /examples/doc/src/components/DocSidebar.tsx | |
parent | 19dc517b87c3b6ad90c97bd220fe96becf27b196 (diff) | |
download | astro-5247a23cbe534d79cdf4abe4c200a351dddc5dc2.tar.gz astro-5247a23cbe534d79cdf4abe4c200a351dddc5dc2.tar.zst astro-5247a23cbe534d79cdf4abe4c200a351dddc5dc2.zip |
Example: Docs template (#226)
* fix: markdown issues
* wip: add docs example
* example: update doc template
* chore: credit Steph for AvatarList
* chore: align footer to bottom viewport
* chore: feeback R1
* fix: font fallback in firefox
* fix merge conflicts
* fix: add default value to headers
* chore: fix doc example
Diffstat (limited to 'examples/doc/src/components/DocSidebar.tsx')
-rw-r--r-- | examples/doc/src/components/DocSidebar.tsx | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/examples/doc/src/components/DocSidebar.tsx b/examples/doc/src/components/DocSidebar.tsx new file mode 100644 index 000000000..e792851bc --- /dev/null +++ b/examples/doc/src/components/DocSidebar.tsx @@ -0,0 +1,55 @@ +import type { FunctionalComponent } from 'preact'; +import { h } from 'preact'; +import { useState, useEffect, useRef } from 'preact/hooks'; +import EditOnGithub from './EditOnGithub'; + +const DocSidebar: FunctionalComponent<{ headers: any[]; editHref: string; }> = ({ headers = [], editHref }) => { + const itemOffsets = useRef([]); + const [activeId, setActiveId] = useState<string>(undefined); + + useEffect(() => { + const getItemOffsets = () => { + const titles = document.querySelectorAll('article :is(h2, h3, h4)'); + itemOffsets.current = Array.from(titles).map(title => ({ + id: title.id, + topOffset: title.getBoundingClientRect().top + window.scrollY + })); + } + + const onScroll = () => { + const itemIndex = itemOffsets.current.findIndex(item => item.topOffset > window.scrollY + (window.innerHeight / 3)); + if (itemIndex === 0) { + setActiveId(undefined); + } else if (itemIndex === -1) { + setActiveId(itemOffsets.current[itemOffsets.current.length - 1].id) + } else { + setActiveId(itemOffsets.current[itemIndex - 1].id) + } + } + + getItemOffsets(); + window.addEventListener('resize', getItemOffsets); + window.addEventListener('scroll', onScroll); + + return () => { + window.removeEventListener('resize', getItemOffsets); + window.removeEventListener('scroll', onScroll); + } + }, []); + + return ( + <nav> + <div> + <h4>Contents</h4> + <ul> + {headers.filter(({ depth }) => depth > 1 && depth < 5).map(header => <li class={`header-link depth-${header.depth} ${activeId === header.slug ? 'active' : ''}`.trim()}><a href={`#${header.slug}`}>{header.text}</a></li>)} + </ul> + </div> + <div> + <EditOnGithub href={editHref} /> + </div> + </nav> + ); +} + +export default DocSidebar; |