@fluid-topics/ftds-toc
v2.2.46
Published
The design system table of contents (TOC) component
Keywords
Readme
Install
npm install @fluid-topics/ftds-toc
yarn add @fluid-topics/ftds-tocUsage
The design system table of contents (TOC). It is a navigation component with two levels (section and sub-section) that links to anchors of a page.
The link matching the current page location is flagged with aria-current="page". It is updated on click and on hashchange, or can be forced with the current property.
It is sticky, and hidden on screens up to 1440px wide.
import { html } from "lit"
import "@fluid-topics/ftds-toc"
function render() {
return html`
<ftds-toc
label="Content"
.items=${ [
{ value: "general", label: "General", href: "#general" },
{
value: "provider",
label: "Provider",
href: "#provider",
children: [
{ value: "settings", label: "Settings", href: "#settings" },
],
},
] }
></ftds-toc>`
}Keyboard navigation
It follows the APG treeview navigation pattern, without expand and collapse. Only one item is in the tab sequence (the current one, or the first).
| Key | Action |
|---------------------|----------------------------------------------------------|
| ArrowDown / Up | Moves the focus to the next / previous item |
| ArrowRight | Moves the focus to the first child of the item |
| ArrowLeft | Moves the focus to the parent of a child item |
| Home / End | Moves the focus to the first / last item |
| A letter | Moves the focus to the next item starting with that letter |
| Space / Enter | Activates the link |
Events
item-selected (TocItemSelectedEvent, detail is the selected item) is dispatched when an item is clicked or activated with the keyboard.
It is cancelable: calling preventDefault() on it cancels the native navigation of the link, so the host can scroll to the section itself.
Building the items from the page
Instead of writing the items by hand, FtTocController (from @fluid-topics/ft-wc-utils) can build them from the sections of a host component and track the section currently in view.
Mark each section of the host's light DOM with data-toc-label. Add data-toc-level="1" to make a sub-section of the previous section.
An element without an id is given one. The sections are rescanned whenever the host's light DOM changes.
import { html } from "lit"
import { FtLitElement, FtTocController } from "@fluid-topics/ft-wc-utils"
import { TocItemSelectedEvent } from "@fluid-topics/ftds-toc"
import "@fluid-topics/ftds-toc"
class MyPage extends FtLitElement {
private readonly toc = new FtTocController(this, {
scrollContainer: () => this.renderRoot.querySelector("main"),
})
protected render() {
return html`
<ftds-toc label="Content"
.items=${ this.toc.items }
.current=${ this.toc.current }
@item-selected=${ this.onItemSelected }>
</ftds-toc>
<main>
<slot></slot>
</main>`
}
private onItemSelected(e: TocItemSelectedEvent) {
if (this.toc.scrollTo(e.detail.value)) {
e.preventDefault()
}
}
}html`
<my-page>
<section data-toc-label="General">...</section>
<section data-toc-label="Provider">...</section>
<section data-toc-label="Settings" data-toc-level="1">...</section>
</my-page>`| Member | Description |
|-----------------------------------|-----------------------------------------------------------------------------------------------------------|
| scrollContainer (option) | The element scrolling the sections. |
| isVisible (option) | Returns whether the TOC is visible. The scroll is not tracked while it returns false. Defaults to always visible. |
| scrollOffset (option) | Distance in pixels from the top of the container at which a section is reached. Defaults to 24. |
| scrollSettleDelay (option) | Milliseconds without scroll event after which a scroll triggered by scrollTo is over. Defaults to 150. |
| items | The items to give to ftds-toc. |
| current | The value of the section in view, to give to ftds-toc. |
| scrollTo(value) | Scrolls to the section, makes it current and keeps it current until the scroll ends. |
| refresh() | Rescans the sections. |
ftds-page-layout does this for you with its withToc property.
