Skip to content

Commit

Permalink
Get table of content from the client instead of server
Browse files Browse the repository at this point in the history
  • Loading branch information
cdedreuille committed Jun 19, 2024
1 parent b1c78af commit db61ba8
Show file tree
Hide file tree
Showing 5 changed files with 2,001 additions and 6,597 deletions.
2 changes: 1 addition & 1 deletion apps/frontpage/app/docs/[[...slug]]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default async function Layout({
<NavDocs activeVersion={activeVersion} tree={tree} />
</Sidebar>
{children}
<TableOfContent headings={page?.headings} />
<TableOfContent />
</main>
</Container>
<Footer />
Expand Down
40 changes: 25 additions & 15 deletions apps/frontpage/components/docs/table-of-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,37 @@ import type { Dispatch, FC, SetStateAction } from 'react';
import { useEffect, useState } from 'react';
import { useScrollDirection } from 'react-use-scroll-direction';
import { ScrollArea } from '../ui/scroll-area';
import { useDocs } from '../../app/docs/provider';

interface Heading {
id: number;
slug: string;
id: string;
title: string;
level: number;
}

interface TableOfContentProps {
headings?: Heading[];
}

interface ElementProps {
heading: Heading;
isInView: string[];
setIsInView: Dispatch<SetStateAction<string[]>>;
}

export const TableOfContent: FC<TableOfContentProps> = ({ headings }) => {
export const TableOfContent: FC = () => {
const { activeRenderer } = useDocs();
const [isInView, setIsInView] = useState<string[]>([]);
const [headings, setHeadings] = useState<Heading[]>([]);

useEffect(() => {
const selectors = document.querySelectorAll(
'h2, h3, h4',
) as NodeListOf<HTMLHeadingElement>;

const elements = Array.from(selectors).map((elem) => ({
id: elem.id,
title: elem.innerText,
level: Number(elem.nodeName.charAt(1)),
}));
setHeadings(elements);
}, [activeRenderer]);

return (
<nav className="sticky top-[72px] hidden w-[228px] self-start xl:block">
Expand Down Expand Up @@ -57,24 +68,23 @@ const Element: FC<ElementProps> = ({ heading, isInView, setIsInView }) => {
// This is quite a dirty solution that don't always work.
// TODO: Find a better solution.
useEffect(() => {
const box = document.getElementById(heading.slug) as ElementOrSelector;
const box = document.getElementById(heading.id) as ElementOrSelector;

inView(box, () => {
const isInArray = isInView.includes(heading.slug);
const isInArray = isInView.includes(heading.id);
!isInArray && isScrollingUp
? setIsInView((value) => [...new Set([heading.slug, ...value])])
: setIsInView((value) => [...new Set([...value, heading.slug])]);
? setIsInView((value) => [...new Set([heading.id, ...value])])
: setIsInView((value) => [...new Set([...value, heading.id])]);

return () => {
setIsInView((value) => value.filter((slug) => slug !== heading.slug));
setIsInView((value) => value.filter((slug) => slug !== heading.id));
};
});

// eslint-disable-next-line react-hooks/exhaustive-deps -- This is intentional
}, [isScrollingUp]);

const active =
isInView.length > 0 ? isInView[0].includes(heading.slug) : false;
const active = isInView.length > 0 ? isInView[0].includes(heading.id) : false;

return (
<li key={heading.id}>
Expand All @@ -84,7 +94,7 @@ const Element: FC<ElementProps> = ({ heading, isInView, setIsInView }) => {
heading.level > 2 && 'ml-5',
active && 'text-blue-500',
)}
href={`#${heading.slug}`}
href={`#${heading.id}`}
>
{heading.title}
</a>
Expand Down
4 changes: 0 additions & 4 deletions apps/frontpage/lib/get-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import remarkGfm from 'remark-gfm';
import { compileMDX } from 'next-mdx-remote/rsc';
import rehypeSlug from 'rehype-slug';
import type { DocsVersion } from '@repo/utils';
import { extractHeadings } from 'extract-md-headings';
import { visit } from 'unist-util-visit';
import {
CodeSnippets,
Expand Down Expand Up @@ -168,8 +167,6 @@ export const getPageData = async (
},
});

const headings = extractHeadings(`${process.cwd()}/${newPath}`);

// Get Tabs
const pathToFiles = isLink
? `${rootPath}/${pathString}`.split('/').slice(0, -1).join('/')
Expand All @@ -187,6 +184,5 @@ export const getPageData = async (
...frontmatter,
tabs: index?.isTab ? parent : [],
content,
headings,
};
};
1 change: 0 additions & 1 deletion apps/frontpage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"date-fns": "^2.0.0",
"date-fns-tz": "^2.0.0",
"dedent": "^1.5.3",
"extract-md-headings": "^0.2.7",
"framer-motion": "^11.2.6",
"fs-extra": "^11.2.0",
"gray-matter": "^4.0.3",
Expand Down

0 comments on commit db61ba8

Please sign in to comment.