Anchor
The list of headings on the page being read, with the one the reader is in marked. Real fragment links, so they jump to their headings whether or not the tracking is running.
import { Anchor } from 'neba';
<Anchor
items={[
{ href: '#install', label: 'Install' },
{ href: '#setup', label: 'Setup', depth: 1 }
]}
/>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
| items * | readonly AnchorItem[] | — | The headings, in the order they appear on the page |
| activeHref | string | null | — | Which row is marked, by its href. Given, the list stops tracking the scroll and says what it is told |
| onActiveChange | (href: string | null) => void | — | Called whenever the row the reader is in changes |
| offset | number | 0 | How far below the top of the scrollport a heading counts as reached, in pixels. Set it to the height of a sticky header |
| container | RefObject<HTMLElement | null> | — | What scrolls, when it is not the document |
| rail | boolean | true | Draws the rail down the leading edge, with the active row lit |
| sizeshared | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | The type scale of the rows and the width of one indent |
| colorshared | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'primary' | The role the marked row and the rail carry |
| densityshared | 'default' | 'compact' | 'default' | Tightens the rows and nothing else |
| locale | string | — | BCP 47 tag naming the nav in that language. Unsupported tags fall back to English |
| label | string | — | The accessible name of the nav. Defaults to the locale's word for it |
Every native <nav> attribute passes through, apart from color and children.
AnchorItem
| Prop | Type | Default | Description |
|---|---|---|---|
| href * | string | — | The fragment it points at. The id it names is what the list watches |
| label * | ReactNode | — | What the row says |
| depth | number | 0 | How deep the heading sits. Only the indent depends on it; the list is flat |
The headings are given rather than scraped out of the document. Anything that produces this list (an MDX pipeline, a CMS, a route's frontmatter) already knows the ids, and a component that went looking for them would be guessing at which headings were content and which were chrome.
Examples
activeHref and onActiveChange
Left alone, the list tracks the scroll: the marked row is the last heading whose top has passed the line, which reads correctly going up as well as down, and the last heading is marked once the scroll reaches the bottom. Pass activeHref and it stops tracking and says what it is told.
Nothing is marked while the reader is still above the first heading.
offset
How far below the top of the scrollport a heading counts as reached. Set it to the height of a sticky header, or the heading under the bar is never the one marked.
container
What scrolls, when it is not the document: the element a PageLayout with scroll="content" puts the page inside, for instance.
rail
The line down the leading edge, with the active row lit. It is a border on the row rather than a marker that travels, because nothing in the library slides under a reader who is already moving.
size
Accessibility
- Renders a real
<nav>of real<a href="#…">s. They work with JavaScript off and they are in the link list a screen reader can pull up; the tracking is added on top rather than being load-bearing. - The marked row carries
aria-current="location", which is the value for where the reader is within a set of links. - The
<nav>is named fromlocale, or fromlabel. - A heading with no
idcannot be tracked, and its row is a link to nothing.