npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fluid-topics/ftds-toc

v2.2.46

Published

The design system table of contents (TOC) component

Readme

Install

npm install @fluid-topics/ftds-toc
yarn add @fluid-topics/ftds-toc

Usage

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.