Inline TOC

A collapsible table of contents component for displaying page headings inline with your content.

Usage

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-docs/eclipse";

export default function Page({ toc }) {
  return (
    <article>
      <InlineTOC items={toc}>
        Table of Contents
      </InlineTOC>
      
      {/* Your page content */}
    </article>
  );
}

Live Example:

Default Open

You can set the TOC to be open by default:

import { InlineTOC } from "@prisma-docs/eclipse";

export default function Page({ toc }) {
  return (
    <InlineTOC items={toc} defaultOpen>
      Table of Contents
    </InlineTOC>
  );
}

Live Example:

With Nested Items

The component supports nested headings for sub-sections:

import { InlineTOC } from "@prisma-docs/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:

Controlled State

You can control the open/closed state programmatically:

import { InlineTOC } from "@prisma-docs/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-docs/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-docs/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>
  );
}

InlineTOC Props

  • 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)

TOC Item Type

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)

Features

  • ✅ Collapsible interface to save space
  • ✅ Automatic active section tracking on scroll
  • ✅ Support for nested headings
  • ✅ Smooth scrolling to sections
  • ✅ Controlled and uncontrolled modes
  • ✅ Eclipse design system styling
  • ✅ Built on Fumadocs InlineTOC

Best Practices

  • Place the InlineTOC near the top of long documents
  • Use "On this page" or "Table of Contents" as the trigger text
  • Set defaultOpen to true for shorter pages where the TOC is always relevant
  • Keep heading depth to 2-3 levels for better readability
  • Ensure all TOC items have corresponding heading anchors on the page
  • Use consistent heading levels throughout your content

Integration with Fumadocs

The InlineTOC component works seamlessly with Fumadocs' automatic TOC generation:

import { getPage } from "@/lib/source";
import { InlineTOC } from "@prisma-docs/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 />
    </>
  );
}

On this page