Mischief

06 / Wayfinding

Floating Index

A compact outline for long pages. It keeps the active section and reading progress visible without becoming another permanent sidebar.

Live previewSource

01

Keep your place.

The index stays close while the page keeps moving.

Scroll this frame to try it.

02

See where you are.

Open it for the full outline, or glance at the progress ring.

03

Jump without getting lost.

Choose a section and the index follows you there.

Installation

Copy the source into your project, or keep it behind a package.

Copy the component into your project and make it yours.

Usage

const items = [
  { id: "introduction", label: "Introduction" },
  { id: "details", label: "Details" },
  { id: "examples", label: "Examples" },
]

export function PageIndex() {
  return <FloatingIndex items={items} />
}

API

itemsFloatingIndexItem[]Section ids, labels, and optional icons.
labelstringThe toggle label. Defaults to Index.
activeIdstringThe active section when controlled.
defaultActiveIdstringThe initial active section.
onActiveChange(id: string) => voidRuns when the visible section changes.
containerRefRefObject<HTMLElement>Tracks a scroll container instead of the page.
classNamestringClasses for placement and appearance.

Accessibility

The index is a labelled navigation landmark with native buttons, visible focus, aria-expanded on the toggle, and aria-current on the active section. Escape closes the outline. Reduced motion removes panel animation and smooth scrolling.

Dependencies

motion, lucide-react, clsx, tailwind-merge