Skip to content

Commit

Permalink
add navigation scrollspy
Browse files Browse the repository at this point in the history
  • Loading branch information
aryaniyaps committed Feb 2, 2025
1 parent babf835 commit 121676f
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 16 deletions.
2 changes: 1 addition & 1 deletion app/tag-data.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"tech-stack":1,"python":2,"http":1,"backend":2,"nextjs":1,"relay":2,"graphql":2,"typescript":1,"frontend":2,"fastapi":1,"strawberry-graphql":1,"react":1,"javascript":1}
{"nextjs":1,"relay":2,"graphql":2,"typescript":1,"frontend":2,"tech-stack":1,"python":2,"http":1,"backend":2,"fastapi":1,"strawberry-graphql":1,"react":1,"javascript":1}
28 changes: 14 additions & 14 deletions components/MDXComponents.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import TOCInline from 'pliny/ui/TOCInline'
import Pre from './Pre'
import BlogNewsletterForm from 'pliny/ui/BlogNewsletterForm'
import type { MDXComponents } from 'mdx/types'
import Image from './Image'
import CustomLink from './Link'
import TableWrapper from './TableWrapper'
import TOCInline from "./TOCInline";
import Pre from "./Pre";
import BlogNewsletterForm from "pliny/ui/BlogNewsletterForm";
import type { MDXComponents } from "mdx/types";
import Image from "./Image";
import CustomLink from "./Link";
import TableWrapper from "./TableWrapper";

export const components: MDXComponents = {
Image,
TOCInline,
a: CustomLink,
pre: Pre,
table: TableWrapper,
BlogNewsletterForm,
}
Image,
TOCInline,
a: CustomLink,
pre: Pre,
table: TableWrapper,
BlogNewsletterForm,
};
99 changes: 99 additions & 0 deletions components/TOCInline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"use client";

import type { TocItem } from "pliny/mdx-plugins/remark-toc-headings";
import type { NestedTocItem, TOCInlineProps } from "pliny/ui/TOCInline";
import ScrollSpy from "react-scrollspy-navigation";

const createNestedList = (items: TocItem[]): NestedTocItem[] => {
const nestedList: NestedTocItem[] = [];
const stack: NestedTocItem[] = [];

items.forEach((item) => {
const newItem: NestedTocItem = { ...item };

while (stack.length > 0 && stack[stack.length - 1].depth >= newItem.depth) {
stack.pop();
}

const parent = stack.length > 0 ? stack[stack.length - 1] : null;

if (parent) {
parent.children = parent.children || [];
parent.children.push(newItem);
} else {
nestedList.push(newItem);
}

stack.push(newItem);
});

return nestedList;
};

const TOCInline = ({
toc,
fromHeading = 1,
toHeading = 6,
asDisclosure = false,
exclude = "",
collapse = false,
ulClassName = "list-decimal",
liClassName = "",
}: TOCInlineProps) => {
const re = Array.isArray(exclude)
? new RegExp("^(" + exclude.join("|") + ")$", "i")
: new RegExp("^(" + exclude + ")$", "i");

const filteredToc = toc.filter(
(heading) =>
heading.depth >= fromHeading &&
heading.depth <= toHeading &&
!re.test(heading.value),
);

const createList = (items: NestedTocItem[] | undefined) => {
if (!items || items.length === 0) {
return <></>;
}

return (
<ul className={ulClassName}>
{items.map((item, index) => {
return (
<li key={index} className={liClassName}>
<a href={item.url} className="no-underline text-foreground">
{item.value}
</a>
{createList(item.children)}
</li>
);
})}
</ul>
);
};

const nestedList = createNestedList(filteredToc);

return (
<>
{asDisclosure ? (
<details open={!collapse}>
<summary className="ml-6 pb-2 pt-2 text-xl font-bold">
Table of Contents
</summary>
<div className="ml-6">
<ScrollSpy activeClass="font-bold">
<nav>{createList(nestedList)}</nav>
</ScrollSpy>
</div>
</details>
) : (
<ScrollSpy activeClass="font-bold">
<nav>{createList(nestedList)}</nav>
</ScrollSpy>
)}
</>
);
};

export default TOCInline;
2 changes: 1 addition & 1 deletion layouts/PostSimple.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import SectionContainer from "@/components/SectionContainer";
import siteMetadata from "@/data/siteMetadata";
import ScrollTopAndComment from "@/components/ScrollTopAndComment";
import { Divider } from "@nextui-org/react";
import TOCInline from "pliny/ui/TOCInline";
import TOCInline from "components/TOCInline";
import { MoveLeft } from "lucide-react";

interface LayoutProps {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"postcss": "^8.4.24",
"react": "rc",
"react-dom": "rc",
"react-scrollspy-navigation": "^2.0.6",
"reading-time": "1.5.0",
"rehype-autolink-headings": "^7.1.0",
"rehype-citation": "^2.0.0",
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12661,6 +12661,13 @@ react-dom@rc:
languageName: node
linkType: hard

"react-scrollspy-navigation@npm:^2.0.6":
version: 2.0.6
resolution: "react-scrollspy-navigation@npm:2.0.6"
checksum: 1d5334b611b30c30360cc17c93fab00fc40b6ec36258e99df00a0be7c906de82c8452bc83afb9b77519172c29395d0bd60d571a37fa9f63709fb0888f49edfff
languageName: node
linkType: hard

"react-style-singleton@npm:^2.2.1":
version: 2.2.1
resolution: "react-style-singleton@npm:2.2.1"
Expand Down Expand Up @@ -14321,6 +14328,7 @@ react@rc:
prettier-plugin-tailwindcss: ^0.5.11
react: rc
react-dom: rc
react-scrollspy-navigation: ^2.0.6
reading-time: 1.5.0
rehype-autolink-headings: ^7.1.0
rehype-citation: ^2.0.0
Expand Down

0 comments on commit 121676f

Please # to comment.