diff --git a/package.json b/package.json
index febed57..3d99997 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"@mdx-js/mdx": "^2.1.2",
"@mdx-js/react": "^2.1.2",
"@mdx-js/rollup": "^2.0.0-rc.1",
+ "@stefanprobst/rehype-extract-toc": "^2.2.0",
"@vitejs/plugin-react": "^2.0.0",
"dayjs": "^1.10.6",
"express": "^4.17.1",
diff --git a/src/components/tropical/TableOfContents/TableOfContents.jsx b/src/components/tropical/TableOfContents/TableOfContents.jsx
new file mode 100644
index 0000000..fbdb6c2
--- /dev/null
+++ b/src/components/tropical/TableOfContents/TableOfContents.jsx
@@ -0,0 +1,16 @@
+export function TableOfContents({ tableOfContents }) {
+ return tableOfContents.length &&
+}
+
+function List({ list }) {
+ return (
+
+ {list.map(({ value, id, children }) => (
+ -
+ {value}
+ {children &&
}
+
+ ))}
+
+ )
+}
diff --git a/src/components/tropical/TableOfContents/TableOfContents.stories.jsx b/src/components/tropical/TableOfContents/TableOfContents.stories.jsx
new file mode 100644
index 0000000..94ea6f5
--- /dev/null
+++ b/src/components/tropical/TableOfContents/TableOfContents.stories.jsx
@@ -0,0 +1,6 @@
+import { TableOfContents } from './TableOfContents'
+import { tableOfContents } from './example.mdx'
+
+export default { title: 'tropical/TableOfContents' }
+
+export const Basic = () =>
diff --git a/src/components/tropical/TableOfContents/example.mdx b/src/components/tropical/TableOfContents/example.mdx
new file mode 100644
index 0000000..e11a239
--- /dev/null
+++ b/src/components/tropical/TableOfContents/example.mdx
@@ -0,0 +1,11 @@
+# Heading 1
+
+# Heading 2
+
+## Heading 2.1
+
+## Heading 2.2
+
+### Heading 2.2.1
+
+# Heading 3
diff --git a/src/components/tropical/TableOfContents/index.js b/src/components/tropical/TableOfContents/index.js
new file mode 100644
index 0000000..f3ffd40
--- /dev/null
+++ b/src/components/tropical/TableOfContents/index.js
@@ -0,0 +1 @@
+export * from './TableOfContents'
\ No newline at end of file
diff --git a/src/entry-server.jsx b/src/entry-server.jsx
index f90ba8e..00ec266 100644
--- a/src/entry-server.jsx
+++ b/src/entry-server.jsx
@@ -41,7 +41,11 @@ export class Renderer {
const headTags = []
const felaRenderer = createFelaRenderer()
cssReset(felaRenderer)
- const { Component, meta = {} } = this.pages[pathname] || this.pages['/404/']
+ const {
+ Component,
+ meta = {},
+ tableOfContents = []
+ } = this.pages[pathname] || this.pages['/404/']
const Layout = meta.Layout || DefaultLayout
const html = ReactDOMServer.renderToString(
@@ -59,8 +63,8 @@ export class Renderer {
{Object.entries(this.feeds).map(([pathname, { type }]) => (
))}
-
-
+
+
@@ -87,6 +91,7 @@ function gatherPages() {
pages[urlPath] = {
Component: page.default,
meta: page.meta,
+ tableOfContents: page.tableOfContents,
filePath,
modulePath,
urlPath
diff --git a/vite.config.js b/vite.config.js
index 414d1bf..4aa9ea7 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -2,6 +2,8 @@ import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import mdx from '@mdx-js/rollup'
import rehypeSlug from 'rehype-slug'
+import rehypeExtractToc from '@stefanprobst/rehype-extract-toc'
+import rehypeExtractTocMdx from '@stefanprobst/rehype-extract-toc/mdx'
import remarkGfm from 'remark-gfm'
import imagePresetsPlugin from 'vite-plugin-image-presets'
import imagePresetsConfig from './src/imagePresets'
@@ -9,7 +11,7 @@ import imagePresetsConfig from './src/imagePresets'
export const plugins = [
react(),
mdx({
- rehypePlugins: [rehypeSlug],
+ rehypePlugins: [rehypeSlug, rehypeExtractToc, rehypeExtractTocMdx],
remarkPlugins: [remarkGfm],
providerImportSource: '@mdx-js/react'
}),