Table of Contents
Accessible, unstyled table of contents that tracks the section in view.
|
|
| Package |
@vizejs/ui/toc |
| Maturity |
stable |
| Own the source |
vize lib pull toc |
| Requires |
collection, context, controllable-state, id, scroll-spy |
| Aliases |
table of contents, toc, on this page, outline navigation, anchor navigation |
| Covers |
HTML nav landmark, aria-current location, Docusaurus TOC, Nuxt UI ContentToc |
Usage
import { Toc, TocRoot, TocItem, TocLink, TocList } from "@vizejs/ui/toc";
Or copy the source into your project with vize lib pull toc (see Source Distribution).
API
Toc
Source: src/families/navigation/toc/toc-root.vue
Props
| Prop |
Type |
Default |
Description |
activeId |
string | null |
undefined |
Controlled active section id (v-model:activeId). undefined lets the scroll spy own it. |
defaultActiveId |
string | null |
null |
Active id rendered on the server and before the first measurement. |
offset |
number |
0 |
Activation line in CSS pixels below the scroll container top, such as a sticky header height. |
root |
Element | null |
undefined |
Scroll container holding the sections. undefined tracks the document viewport. |
track |
boolean |
true |
Track scroll position. Disable it to drive activeId entirely from outside. |
scrollBehavior |
TocScrollBehavior |
undefined |
Script-driven scrolling for link clicks. undefined keeps native fragment navigation. |
updateHash |
boolean |
true |
Replace the URL fragment after script-driven scrolling. |
ariaLabel |
string |
"Table of contents" |
Accessible name of the navigation landmark. |
ariaLabelledby |
string |
undefined |
Space-separated ids that label the landmark instead of ariaLabel. |
Events
| Event |
Payload |
Description |
update:activeId |
[id: string | null] |
Fired with the section id that came into view or was navigated to. |
navigate |
[id: string, nativeEvent: MouseEvent] |
Fired when a link is activated, before any script-driven scrolling. |
Slots
| Slot |
Slot props |
Description |
default |
TocSlotState |
TocList, TocItem, and TocLink children. Receives the active id and tracked ids. |
Exposed
| Member |
Type |
Description |
activeId |
— |
|
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
refresh |
— |
|
scrollTo |
— |
|
TocRoot
Source: src/families/navigation/toc/toc-root.vue
Props
| Prop |
Type |
Default |
Description |
activeId |
string | null |
undefined |
Controlled active section id (v-model:activeId). undefined lets the scroll spy own it. |
defaultActiveId |
string | null |
null |
Active id rendered on the server and before the first measurement. |
offset |
number |
0 |
Activation line in CSS pixels below the scroll container top, such as a sticky header height. |
root |
Element | null |
undefined |
Scroll container holding the sections. undefined tracks the document viewport. |
track |
boolean |
true |
Track scroll position. Disable it to drive activeId entirely from outside. |
scrollBehavior |
TocScrollBehavior |
undefined |
Script-driven scrolling for link clicks. undefined keeps native fragment navigation. |
updateHash |
boolean |
true |
Replace the URL fragment after script-driven scrolling. |
ariaLabel |
string |
"Table of contents" |
Accessible name of the navigation landmark. |
ariaLabelledby |
string |
undefined |
Space-separated ids that label the landmark instead of ariaLabel. |
Events
| Event |
Payload |
Description |
update:activeId |
[id: string | null] |
Fired with the section id that came into view or was navigated to. |
navigate |
[id: string, nativeEvent: MouseEvent] |
Fired when a link is activated, before any script-driven scrolling. |
Slots
| Slot |
Slot props |
Description |
default |
TocSlotState |
TocList, TocItem, and TocLink children. Receives the active id and tracked ids. |
Exposed
| Member |
Type |
Description |
element |
HTMLElement | null |
Rendered navigation landmark. |
activeId |
string | null |
Id of the section currently in view. |
scrollTo |
(id: string) => boolean |
Scroll a target into view and make it active. |
refresh |
() => void |
Re-measure targets immediately. |
TocItem
Source: src/families/navigation/toc/toc-item.vue
Props
| Prop |
Type |
Default |
Description |
targetId |
string |
undefined |
Target id of this entry. Supply it for exact server-rendered data-active; otherwise it is learned from the nested TocLink after it renders. |
Slots
| Slot |
Slot props |
Description |
default |
TocLinkSlotState |
TocLink and optional nested TocList. Receives the link target and active state. |
TocLink
Source: src/families/navigation/toc/toc-link.vue
Props
| Prop |
Type |
Default |
Description |
targetId (required) |
string |
required |
Id of the heading or section this link points to. |
Slots
| Slot |
Slot props |
Description |
default |
TocLinkSlotState |
Link text. Receives the target id and whether its section is in view. |
Exposed
| Member |
Type |
Description |
active |
— |
|
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
TocList
Source: src/families/navigation/toc/toc-list.vue
Props
| Prop |
Type |
Default |
Description |
level |
number |
1 |
Nesting depth exposed to styles; nested lists live inside a TocItem. |
Slots
| Slot |
Slot props |
Description |
default |
{ /** Nesting depth of this list. */ readonly level: number; } |
TocItem children. |
Behavior
Normative state x input -> outcome table for toc-root.vue, toc-list.vue,
toc-item.vue, and toc-link.vue (@vizejs/ui/toc), plus
collectTocEntries. Every row is proven by the named test in toc.test.ts or
toc-ssr.test.ts; compile-only guarantees live in toc.types.test-d.ts.
The root is a labelled <nav> landmark with nested <ol> lists of native
fragment links. The link whose section is in view carries
aria-current="location". Active tracking reuses the @vizejs/ui/scroll-spy
composable over the ids of the registered links.
| ID |
State |
Input |
Outcome |
Evidence |
| C1 |
default |
render |
labelled nav, nested ol lists, #fragment links, aria-current on the default id |
renders a labelled navigation landmark with fragment links |
| C2 |
tracking |
scroll |
the section past the offset line becomes active on its link and item |
tracks the section in view and marks links and items active |
| C3 |
controlled / track=false |
scroll, prop change |
the parent owns activeId; no tracking updates are emitted |
controlled activeId and disabled tracking leave ownership to the parent |
| C4 |
scrollBehavior set |
primary click, modified |
smooth script scrolling, immediate activation, fragment update; modified clicks stay native |
scrollBehavior drives smooth navigation and updates the fragment |
| C5 |
no scrollBehavior |
click |
native fragment navigation is not intercepted |
native fragment navigation is untouched without scrollBehavior |
| C6 |
exposed root |
scrollTo, refresh |
imperative navigation and re-measurement; ariaLabelledby replaces the default label |
exposes scrollTo and refresh |
| C7 |
rendered content |
collectTocEntries |
id-bearing headings in document order with normalized text and levels |
collectTocEntries reads headings with ids in document order |
| C8 |
missing provider |
setup |
links and items fail closed with the shared context diagnostic |
compound parts require a matching root provider |
| C9 |
SSR and hydration |
isolated render/mount |
defaultActiveId renders on links and items and hydrates without warnings |
toc-ssr.test.ts |