Skip to content
This repository was archived by the owner on Jan 23, 2024. It is now read-only.

Commit 3fb0f71

Browse files
authored
feat: improve table of content (#1553)
1 parent 458480c commit 3fb0f71

File tree

4 files changed

+30
-18
lines changed

4 files changed

+30
-18
lines changed

src/components/page-container.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ function PageContainer(props: PageContainerProps) {
9292
</Badge>
9393
)}
9494
{children}
95-
<Box mt='40px'>
95+
<Box mt='40vh'>
9696
<Box>{editUrl && <EditPageLink href={editUrl} />}</Box>
9797
{pagination || null}
9898
</Box>

src/components/table-of-content.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function TableOfContent(props: TableOfContentProps) {
2121
const activeId = useScrollSpy(
2222
headings.map(({ id }) => `[id="${id}"]`),
2323
{
24-
rootMargin: '0% 0% -24% 0%',
24+
rootMargin: '-10% 0% -24% 0%',
2525
},
2626
)
2727
const linkColor = useColorModeValue('gray.600', 'gray.400')

src/hooks/use-scrollspy.ts

+25-13
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,34 @@ export function useScrollSpy(
66
) {
77
const [activeId, setActiveId] = React.useState<string>()
88
const observer = React.useRef<IntersectionObserver | null>(null)
9-
React.useEffect(() => {
10-
const elements = selectors.map((selector) =>
11-
document.querySelector(selector),
12-
)
13-
observer.current?.disconnect()
9+
const headerRef = React.useRef<{[key:string] : IntersectionObserverEntry}>({});
10+
11+
React.useEffect(() => {
12+
const elements = selectors.map((selector) => document.querySelector(`h2${selector}, h3${selector}`))
13+
14+
observer.current?.disconnect();
15+
1416
observer.current = new IntersectionObserver((entries) => {
15-
entries.forEach((entry) => {
16-
if (entry?.isIntersecting) {
17-
setActiveId(entry.target.getAttribute('id'))
18-
}
19-
})
20-
}, options)
17+
for (const entry of entries) {
18+
headerRef.current[entry.target.id] = entry;
19+
}
20+
21+
const topElement = Object.values(headerRef.current).find((entry) => entry.isIntersecting);
22+
23+
if (topElement) {
24+
setActiveId(topElement.target.id);
25+
}
26+
27+
}, options);
28+
2129
elements.forEach((el) => {
2230
if (el) observer.current?.observe(el)
23-
})
24-
return () => observer.current?.disconnect()
31+
});
32+
33+
return () => {
34+
observer.current?.disconnect()
35+
headerRef.current = {};
36+
}
2537
}, [selectors, options])
2638

2739
return activeId

src/utils/contentlayer-utils.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,21 @@ export function getComponentTabsData(slug: MixedArray) {
8181

8282
const data = [
8383
{
84-
id: 'usage',
84+
id: 'usage-wrapper',
8585
match: _slug.endsWith('/usage') || params.length === 2,
8686
href: { query: { slug: usageSlug.slice(1) } },
8787
label: 'Usage',
8888
doc: getDocDoc(getSlug('usage')),
8989
},
9090
{
91-
id: 'props',
91+
id: 'props-wrapper',
9292
match: _slug.endsWith('/props'),
9393
href: { query: { slug: propsSlug.slice(1) } },
9494
label: 'Props',
9595
doc: getDocDoc(getSlug('props')),
9696
},
9797
{
98-
id: 'theming',
98+
id: 'theming-wrapper',
9999
match: _slug.endsWith('/theming'),
100100
label: 'Theming',
101101
href: { query: { slug: themingSlug.slice(1) } },

0 commit comments

Comments
 (0)