apps/eclipse/content/design-system/components/inlinetoc.mdx
import { InlineTOC } from "@prisma/eclipse";
Basic Inline TOC
The InlineTOC component displays a collapsible table of contents within your content. It automatically tracks the active section as users scroll.
import { InlineTOC } from "@prisma/eclipse";
export default function Page({ toc }) {
return (
<article>
<InlineTOC items={toc}>
Table of Contents
</InlineTOC>
</article>
);
}
Live Example:
<InlineTOC items={[ { title: "Usage", url: "#usage", depth: 2 }, { title: "InlineTOC Props", url: "#inlinetoc-props", depth: 2 }, { title: "TOC Item Type", url: "#toc-item-type", depth: 2 }, { title: "Features", url: "#features", depth: 2 }, { title: "Best Practices", url: "#best-practices", depth: 2 }, ]}
On this page </InlineTOC>
Default Open
You can set the TOC to be open by default:
import { InlineTOC } from "@prisma/eclipse";
export default function Page({ toc }) {
return (
<InlineTOC items={toc} defaultOpen>
Table of Contents
</InlineTOC>
);
}
Live Example:
<InlineTOC items={[ { title: "Introduction", url: "#introduction", depth: 2 }, { title: "Getting Started", url: "#getting-started", depth: 2 }, { title: "Advanced Usage", url: "#advanced-usage", depth: 2 }, ]} defaultOpen
Contents </InlineTOC>
With Nested Items
The component supports nested headings for sub-sections:
import { InlineTOC } from "@prisma/eclipse";
const tocItems = [
{
title: "Getting Started",
url: "#getting-started",
depth: 2,
items: [
{ title: "Installation", url: "#installation", depth: 3 },
{ title: "Configuration", url: "#configuration", depth: 3 },
],
},
{
title: "API Reference",
url: "#api-reference",
depth: 2,
items: [
{ title: "Components", url: "#components", depth: 3 },
{ title: "Hooks", url: "#hooks", depth: 3 },
],
},
];
export default function Page() {
return (
<InlineTOC items={tocItems}>
On this page
</InlineTOC>
);
}
Live Example:
<InlineTOC items={[ { title: "Getting Started", url: "#getting-started", depth: 2, items: [ { title: "Installation", url: "#installation", depth: 3 }, { title: "Configuration", url: "#configuration", depth: 3 }, ], }, { title: "API Reference", url: "#api-reference", depth: 2, items: [ { title: "Components", url: "#components", depth: 3 }, { title: "Hooks", url: "#hooks", depth: 3 }, ], }, ]}
On this page </InlineTOC>
Controlled State
You can control the open/closed state programmatically:
import { InlineTOC } from "@prisma/eclipse";
import { useState } from "react";
export default function Page({ toc }) {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<button onClick={() => setIsOpen(!isOpen)}>
Toggle TOC
</button>
<InlineTOC
items={toc}
open={isOpen}
onOpenChange={setIsOpen}
>
Table of Contents
</InlineTOC>
</>
);
}
In MDX Content
You can use InlineTOC directly in your MDX files:
---
title: My Document
---
import { InlineTOC } from "@prisma/eclipse";
<InlineTOC items={toc}>
Table of Contents
</InlineTOC>
## Section 1
Content here...
## Section 2
More content...
Adding to All Pages
You can add InlineTOC to every documentation page automatically:
// page.tsx
import { DocsPage } from "fumadocs-ui/layouts/docs/page";
import { InlineTOC } from "@prisma/eclipse";
export default function Page({ params }) {
const page = getPage(params.slug);
return (
<DocsPage toc={page.data.toc}>
<InlineTOC items={page.data.toc}>
On this page
</InlineTOC>
<page.data.body />
</DocsPage>
);
}
items - Array of table of contents items (TOCItem[], required)defaultOpen - Whether the TOC is open by default (boolean, default: false)open - Controlled open state (boolean, optional)disabled - Whether the TOC is disabled (boolean, default: false)onOpenChange - Callback when open state changes ((open: boolean) => void, optional)asChild - Whether to use the child element as the trigger (boolean, default: false)children - The trigger content, usually "Table of Contents" or similar (ReactNode, optional)className - Additional CSS classes (optional)Each item in the items array should have:
title - The title of the heading (string, required)url - The URL/hash to link to (string, required)depth - The depth/level of the heading (number, required)items - Nested items for sub-headings (TOCItem[], optional)defaultOpen to true for shorter pages where the TOC is always relevantThe InlineTOC component works seamlessly with Fumadocs' automatic TOC generation:
import { getPage } from "@/lib/source";
import { InlineTOC } from "@prisma/eclipse";
export default function Page({ params }) {
const page = getPage(params.slug);
// page.data.toc is automatically generated by Fumadocs
return (
<>
<InlineTOC items={page.data.toc}>
On this page
</InlineTOC>
<page.data.body />
</>
);
}