A scroll-spy table of contents: a sticky in-page nav that marks the section being read with aria-current="location" and slides an accent rule to it. Plain #id links that work without JavaScript; with it, clicks scroll smoothly, update the hash and move focus.
Overview
What the handbook covers and who it is for.
Setup
Accounts, devices and the tools you need on day one.
Workflow
How work moves from a request to a finished task.
Reviews
When to ask for a review and what reviewers look for.
Installation
The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";
Usage
import { SectionNav } from "@vamos-ui/react";
<SectionNav
title="On this page"
items={[{ id: "overview", label: "Overview" }, { id: "setup", label: "Setup" }]}
/>
<section id="overview">…</section>Give the sections scroll-margin-top (scroll-mt-*) when the page has a fixed header.
Between sections the last one stays current, so the marker never blinks off.
Examples
Static contents list
sticky={false} and no meta: a compact list at the top of a page.
API
SectionNav
| Prop | Type | Default |
|---|---|---|
itemsSections on the page, by element id. meta is a small leading number or count. | { id: string; label: ReactNode; meta?: ReactNode }[] | — |
titleVisible heading above the list; also names the landmark. | ReactNode | — |
stickyStick while the page scrolls. | boolean | true |
topSticky offset (clear a fixed header). | number | string | "1.5rem" |
rootMarginThe band of the window that counts as being read. | string | "-20% 0px -55% 0px" |
onActiveChangeThe current section changed. | (id: string | null) => void | — |
labelsDictionary namespace "sectionNav": label (the landmark name without a title). | Partial<SectionNavLabels> | — |