Skip to content

Commit

Permalink
toc fix
Browse files Browse the repository at this point in the history
  • Loading branch information
abernier committed Aug 9, 2024
1 parent fc7566b commit 6d69477
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 290 deletions.
2 changes: 1 addition & 1 deletion src/app/[[...slug]]/DocsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type Doc = {
nav: number
title: string
description: string
content: string
content: ReactNode
boxes: string[]
tableOfContents: DocToC[]
}
Expand Down
9 changes: 4 additions & 5 deletions src/app/[[...slug]]/Menu.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use client'

import clsx from 'clsx'
import * as React from 'react'
import Toc from '@/components/Toc'
import clsx from 'clsx'
import { useLockBodyScroll } from '@/hooks/useLockBodyScroll'
import { useDocs } from './DocsContext'
import { useMenu } from './MenuContext'
Expand All @@ -12,11 +11,13 @@ export function Menu({
header,
nav,
children,
aside,
footer,
}: {
header: React.ReactNode
nav: React.ReactNode
children: React.ReactNode
aside: React.ReactNode
footer: React.ReactNode
}) {
const { doc } = useDocs()
Expand Down Expand Up @@ -80,9 +81,7 @@ export function Menu({
<footer>{footer}</footer>
</main>

<aside className="flex-none hidden w-64 pl-8 pr-8 xl:text-sm xl:block">
{doc?.tableOfContents?.length ? <Toc toc={doc.tableOfContents} /> : null}
</aside>
<aside className="flex-none hidden w-64 pl-8 pr-8 xl:text-sm xl:block">{aside}</aside>
</div>
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions src/app/[[...slug]]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import Nav from '@/components/Nav'
import Link from 'next/link'
import Search from '@/components/Search'
import ToggleTheme from '@/components/ToggleTheme'
import Toc from '@/components/Toc'

export type Props = {
params: { slug: string[] }
children: React.ReactNode
}

export default async function Layout({ params, children }: Props) {
console.log('layout', params)

const slug = params.slug
const { docs, doc } = await getData(...slug)

Expand Down Expand Up @@ -56,6 +59,7 @@ export default async function Layout({ params, children }: Props) {
<Nav docs={docs} asPath={asPath} />
</>
}
aside={<Toc toc={doc.tableOfContents} />}
footer={
<>
{!!currentPage && (
Expand Down
2 changes: 1 addition & 1 deletion src/app/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export async function generateStaticParams() {
const MDX = process.env.MDX
if (!MDX) throw new Error('MDX env var not set')

const docs = await getDocs(MDX)
const docs = await getDocs(MDX, null, true)
const paths = docs.map(({ slug }) => ({ slug }))
// console.log('paths', paths)
return paths
Expand Down
155 changes: 1 addition & 154 deletions src/components/Post.tsx
Original file line number Diff line number Diff line change
@@ -1,158 +1,5 @@
import * as React from 'react'
import Codesandbox from '@/components/Codesandbox'
import { MDXRemote } from 'next-mdx-remote/rsc'
import { MARKDOWN_REGEX } from '@/utils/docs'
import { fetchCSB } from '@/components/Codesandbox'

import remarkGFM from 'remark-gfm'
import rehypePrismPlus from 'rehype-prism-plus'
import { codesandbox, toc } from '@/utils/rehype'
import { Doc } from '@/app/[[...slug]]/DocsContext'

const components = {
Hint: ({ children }: { children: React.ReactNode }) => (
<div className="hint shadow overflow-hidden bg-yellow-100 border-b border-gray-200 sm:rounded-lg px-6 py-4 mb-6 dark:text-gray-500">
{children}
</div>
),
Grid: ({ children, cols = 4 }: { children: React.ReactNode; cols?: number }) => (
<ul
className={`grid sm:grid-cols-2 ${
cols === 4
? 'md:grid-cols-4'
: cols === 3
? 'md:grid-cols-3'
: cols === 2
? 'md:grid-cols-2'
: 'md:grid-cols-1'
} gap-4 text-sm text-gray-700 grid-list`}
style={{ marginBottom: '1rem' }}
>
{children}
</ul>
),
h2: ({ children, id }: { children: React.ReactNode; id: string }) => (
<a href={`#${id}`} className="heading text-3xl mb-6 mt-8 tracking-light">
<h2 id={id}>{children}</h2>
</a>
),
h3: ({ children, id }: { children: React.ReactNode; id: string }) => (
<a href={`#${id}`} className="heading text-xl mb-4 mt-6 tracking-light">
<h3 id={id}>{children}</h3>
</a>
),
h4: ({ children, id }: { children: React.ReactNode; id: string }) => (
<a href={`#${id}`} className="heading text-base mb-4 mt-4 tracking-light">
<h4 id={id}>{children}</h4>
</a>
),
ul: ({ children }: { children: React.ReactNode }) => <ul className="px-4 mb-8">{children}</ul>,
ol: ({ children }: { children: React.ReactNode }) => <ol className="px-4 mb-8">{children}</ol>,
li: ({ children }: { children: React.ReactNode }) => (
<li className="mb-4 text-base leading-6 text-gray-700 dark:text-gray-400">{children}</li>
),
p: ({ children }: { children: React.ReactNode }) => (
<p className="mb-4 text-base text-gray-700 dark:text-gray-400">{children}</p>
),
blockquote: ({ children }: { children: React.ReactNode }) => (
<blockquote className="mb-8 text-base pl-4 border-l-4 border-gray-600">{children}</blockquote>
),
table: ({ children }: { children: React.ReactNode }) => (
<div className="flex flex-col my-6">
<div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="py-6 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div className="shadow-lg overflow-hidden border-b border-gray-200 sm:rounded-lg dark:border-gray-700">
<table className="divide-y divide-gray-200 w-full dark:divide-gray-700">
{children}
</table>
</div>
</div>
</div>
</div>
),
a: ({
href,
target,
rel,
children,
}: {
href: string
target?: string
rel?: string
children: React.ReactNode
}) => {
const isAnchor = href.startsWith('https://')
target = isAnchor ? '_blank' : target
rel = isAnchor ? 'noopener noreferrer' : rel
href = isAnchor ? href : href.replace(MARKDOWN_REGEX, '')
return (
<a href={href} target={target} rel={rel}>
{children}
</a>
)
},
img: ({
src,
alt,
width,
height,
...rest
}: {
src: string
alt: string
width: number
height: number
}) => (
// eslint-disable-next-line @next/next/no-img-element
<img
src={src}
decoding="async"
loading="lazy"
alt={alt}
width={width}
height={height}
{...rest}
/>
),
}

export default async function Post({ doc }: { doc: Doc }) {
const { content, url, title } = doc

return (
<MDXRemote
source={content}
components={
{
...components,
Codesandbox: async (props: React.ComponentProps<typeof Codesandbox>) => {
const ids = doc.boxes // populated from 1.
// console.log('ids', ids)

//
// Batch fetch all CSBs of the page
//
const boxes = await fetchCSB(...ids)
// console.log('boxes', boxes)
const data = boxes[props.id]
// console.log('data', data)

// Merge initial props with data
const merged = { ...props, ...data }
return <Codesandbox {...merged} />
},
} as React.ComponentProps<typeof MDXRemote>['components']
}
options={{
mdxOptions: {
remarkPlugins: [remarkGFM],
rehypePlugins: [
rehypePrismPlus,
codesandbox(doc.boxes), // 1. put all Codesandbox[id] into `doc.boxes`
toc(doc.tableOfContents, url, title, content), // 2. will populate `doc.tableOfContents`
],
},
}}
/>
)
return <>{doc.content}</>
}
1 change: 1 addition & 0 deletions src/components/Toc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface ToCProps {
}

function Toc({ toc }: ToCProps) {
// console.log('toc', toc)
const [activeIndex, setActiveIndex] = React.useState(0)

React.useEffect(() => {
Expand Down
129 changes: 0 additions & 129 deletions src/utils/docs.ts

This file was deleted.

Loading

0 comments on commit 6d69477

Please sign in to comment.