Anchor Experimental
Scroll-aware table-of-contents navigation. Provide items manually or point it at a scrollable container to auto-discover headings.
import { Anchor } from 'phoundry-ui'; Basic (Manual Items)
Introduction
Welcome to the Anchor component. It provides scroll-aware navigation for long pages.
Installation
Install via npm: npm install phoundry-ui
Usage
Import the component and pass your items array.
API Reference
See the props table below for full API documentation.
<Anchor items={[
{ key: 'intro', href: '#intro', title: 'Introduction' },
{ key: 'install', href: '#install', title: 'Installation' },
{ key: 'usage', href: '#usage', title: 'Usage' },
{ key: 'api', href: '#api', title: 'API Reference' },
]} />Auto-Discovery
Overview
The auto mode scans the container for headings and builds the item list.
Configuration
Use headingSelector to control which elements are picked up.
Scroll Tracking
Active state updates automatically as the user scrolls.
Events
onChange fires whenever the active link changes.
<Anchor target={scrollContainer} headingSelector="h3" />Horizontal
Introduction
Horizontal anchor for compact navigation.
Installation
Same install process.
Usage
Set direction to horizontal.
API Reference
Full API below.
<Anchor
items={items}
direction="horizontal"
/>Nested Items
Getting Started
Prerequisites
Node.js 18+, Svelte 5.
Setup
Run the init script.
Components
Input
Text input field.
Select
Dropdown selector.
<Anchor items={[
{ key: 'start', href: '#start', title: 'Getting Started',
children: [
{ key: 'prereqs', href: '#prereqs', title: 'Prerequisites' },
{ key: 'setup', href: '#setup', title: 'Setup' },
]},
{ key: 'components', href: '#components', title: 'Components',
children: [
{ key: 'button', href: '#button', title: 'Button' },
{ key: 'input', href: '#input', title: 'Input' },
]},
]} />Offsets, replaceState, onChange
offsetTop shifts which heading counts as “active” while scrolling. targetOffset controls the gap after clicking (defaults to offsetTop). replace avoids cluttering history on each jump.
Introduction
Scroll to see onChange update.
Installation
Middle segment.
Usage
Another section.
API Reference
Last segment.
<Anchor
items={items}
target={scrollEl}
offsetTop={24}
targetOffset={16}
replace
affix={false}
onChange={(href) => (active = href)}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| items | AnchorItem[] | — | Explicit anchor items (manual mode). |
| target | HTMLElement | — | Scrollable container to scan for headings (auto mode). |
| headingSelector | string | 'h2, h3' | CSS selector for discoverable headings in auto mode. |
| direction | 'vertical' | 'horizontal' | 'vertical' | Layout direction. Horizontal disables nesting. |
| offsetTop | number | 0 | Pixel offset for calculating the active section position. |
| targetOffset | number | — | Scroll-to offset when clicking a link. Defaults to offsetTop. |
| bounds | number | 5 | Bounding distance in px for active section detection. |
| affix | boolean | true | Stick the anchor with position: sticky. |
| replace | boolean | false | Use replaceState instead of pushState for URL hash. |
| onChange | (activeHref: string) => void | — | Fires when the highlighted link changes (hash string, e.g. `#section-id`). |
| onclick | (e: MouseEvent, item: AnchorItem) => void | — | Click handler for anchor links. |
| getCurrentAnchor | (href: string) => string | — | Override which link is highlighted. |
| class | string | — | Additional CSS classes. |
AnchorItem
| Prop | Type | Default | Description |
|---|---|---|---|
| key required | string | — | Unique identifier. |
| href required | string | — | Hash target (e.g. #section-id). |
| title required | string | — | Display text. |
| children | AnchorItem[] | — | Nested child links (vertical only). |
Usage tips
- Pass
itemsfor full control, ortargetto auto-discover headings from a container. - In auto mode, headings without
idattributes get one assigned automatically (slugified from text). - Use
headingSelectorto control which heading levels are included (e.g."h2, h3"or just"h3"). - Set
direction="horizontal"for compact inline navigation. Nesting is disabled in horizontal mode. - The component renders nothing when there are no items — safe to include in layouts unconditionally.
- Add to a layout file with
target={mainEl}to get a page ToC on every page automatically.