<script lang="ts">
import { TableOfContents } from 'kumo-svelte';
const headings = [
'Introduction',
'Installation',
'Usage',
'API Reference',
'Examples'
];
</script>
<div class="min-w-48">
<TableOfContents>
<TableOfContents.Title>On this page</TableOfContents.Title>
<TableOfContents.List>
{#each headings as heading (heading)}
<TableOfContents.Item active={heading === 'Usage'} class="cursor-pointer">
{heading}
</TableOfContents.Item>
{/each}
</TableOfContents.List>
</TableOfContents>
</div> Installation
Barrel
import { TableOfContents } from 'kumo-svelte'; Granular
import { TableOfContents } from 'kumo-svelte/components/table-of-contents';Usage
<script lang="ts">import { TableOfContents } from "kumo-svelte";</script> <TableOfContents> <TableOfContents.Title>On this page</TableOfContents.Title> <TableOfContents.List> <TableOfContents.Item href="#intro" active> Introduction </TableOfContents.Item> <TableOfContents.Item href="#api">API Reference</TableOfContents.Item> </TableOfContents.List> </TableOfContents> This component is purely presentational. All interaction logic — scroll
tracking, IntersectionObserver, active state management — is left to the
consumer.
Examples
Interactive
Click an item to set it as active. The consumer controls state via active and onclick.
<script lang="ts">
import { TableOfContents } from 'kumo-svelte';
const headings = [
'Introduction',
'Installation',
'Usage',
'API Reference',
'Examples'
];
let active = $state('Introduction');
</script>
<div class="min-w-48">
<TableOfContents>
<TableOfContents.Title>On this page</TableOfContents.Title>
<TableOfContents.List>
{#each headings as heading (heading)}
<TableOfContents.Item
active={heading === active}
onclick={() => (active = heading)}
class="cursor-pointer"
>
{heading}
</TableOfContents.Item>
{/each}
</TableOfContents.List>
</TableOfContents>
</div> No active item
When no item has active set, all items show the default subtle text style
with a hover indicator.
<script lang="ts">
import { TableOfContents } from 'kumo-svelte';
const headings = [
'Introduction',
'Installation',
'Usage',
'API Reference',
'Examples'
];
</script>
<div class="min-w-48">
<TableOfContents>
<TableOfContents.Title>On this page</TableOfContents.Title>
<TableOfContents.List>
{#each headings as heading (heading)}
<TableOfContents.Item class="cursor-pointer">{heading}</TableOfContents.Item>
{/each}
</TableOfContents.List>
</TableOfContents>
</div> Groups
Use TableOfContents.Group to organize items into labeled sections with
indented children. Groups support two modes: pass an href to make the group
label a clickable link (like "Examples" and "API" below), or omit it for a
plain non-interactive title (like "Getting Started").
<script lang="ts">
import { TableOfContents } from 'kumo-svelte';
</script>
<div class="min-w-48">
<TableOfContents>
<TableOfContents.Title>On this page</TableOfContents.Title>
<TableOfContents.List>
<TableOfContents.Item active class="cursor-pointer">Overview</TableOfContents.Item>
<TableOfContents.Group label="Examples" href="#examples-demo">
<TableOfContents.Item class="cursor-pointer">Basic example</TableOfContents.Item>
<TableOfContents.Item class="cursor-pointer">Advanced example</TableOfContents.Item>
</TableOfContents.Group>
<TableOfContents.Group label="Getting Started">
<TableOfContents.Item class="cursor-pointer">Installation</TableOfContents.Item>
<TableOfContents.Item class="cursor-pointer">Configuration</TableOfContents.Item>
</TableOfContents.Group>
<TableOfContents.Group label="API" href="#api-demo">
<TableOfContents.Item class="cursor-pointer">Props</TableOfContents.Item>
<TableOfContents.Item class="cursor-pointer">Events</TableOfContents.Item>
</TableOfContents.Group>
</TableOfContents.List>
</TableOfContents>
</div> Without title
The title sub-component is optional — use TableOfContents.List directly if
you don't need a heading.
<script lang="ts">
import { TableOfContents } from 'kumo-svelte';
const headings = [
'Introduction',
'Installation',
'Usage',
'API Reference',
'Examples'
];
</script>
<div class="min-w-48">
<TableOfContents>
<TableOfContents.List>
{#each headings.slice(0, 3) as heading (heading)}
<TableOfContents.Item active={heading === 'Introduction'} class="cursor-pointer">
{heading}
</TableOfContents.Item>
{/each}
</TableOfContents.List>
</TableOfContents>
</div> Custom element
Use the render prop to swap the default anchor for a button, router link, or
any element.
<script lang="ts">
import { TableOfContents } from 'kumo-svelte';
let clicked = $state<string | null>(null);
</script>
<div class="min-w-48 space-y-3">
<TableOfContents>
<TableOfContents.List>
{#each ['Introduction', 'Installation', 'Usage'] as heading (heading)}
<TableOfContents.Item
as="button"
type="button"
active={heading === 'Introduction'}
onclick={() => (clicked = heading)}
>
{heading}
</TableOfContents.Item>
{/each}
</TableOfContents.List>
</TableOfContents>
{#if clicked}
<p class="text-xs text-kumo-subtle">Clicked: {clicked}</p>
{/if}
</div> SvelteKit
<TableOfContents.Item render={<Link to="/intro" />} active> Introduction</TableOfContents.Item> Next.js
import Link from "next/link";<TableOfContents.Item render={<Link href="/intro" />} active> Introduction</TableOfContents.Item>; Button (no navigation)
<TableOfContents.Item render={<button type="button" />} onclick={handleClick}> Introduction</TableOfContents.Item>API Reference
TableOfContents
Root nav container with a default aria-label of "Table of contents".
| Prop | Type | Default | Description |
|---|---|---|---|
| class | string | - | Additional classes merged onto the nav element. |
| children | Snippet | - | TableOfContents.Title and TableOfContents.List children. |
| aria-label | string | "Table of contents" | Accessible label for the nav landmark. |
TableOfContents.Title
Optional uppercase heading displayed above the list (renders a <p>).
| Prop | Type | Default | Description |
|---|---|---|---|
| No component-specific props. Accepts standard HTML attributes. | |||
TableOfContents.List
List container with a left border rail.
| Prop | Type | Default | Description |
|---|---|---|---|
| No component-specific props. Accepts standard HTML attributes. | |||
TableOfContents.Item
Individual navigation link. Set active for the current section. Use the render prop to swap the anchor for a router link or button.
| Prop | Type | Default | Description |
|---|---|---|---|
| active | boolean | false | Whether this item represents the currently active section. |
| href | string | - | Destination URL. |
| as | 'a' | 'button' | "a" | Svelte replacement for React's render prop when rendering a button item. |
TableOfContents.Group
Groups items under a labeled section with indented children. Pass href to make the label a clickable link, or omit for a plain title.
| Prop | Type | Default | Description |
|---|---|---|---|
| label * | string | - | Label displayed above the group's items. |
| href | string | - | URL the group label links to. When provided, the label renders as a clickable link. |
| active | boolean | false | Whether this group's label represents the currently active section. Only applies when href is provided. |