PathLogs UI
Русский

Hooks

useActiveSection

Highlighting the active section of a long page while scrolling.

Highlighting the active section while scrolling — and smoothly moving to it on click. The table of contents on the right of this very page runs on it.

Example

tsx
import { useActiveSection } from "@toimetdev/pathlogs-hooks";

function Toc({ entries }) {
  const { active, scrollTo } = useActiveSection(
    entries.map((e) => e.id),
    { offset: 80 }        // height of the sticky header
  );

  return (
    <ul>
      {entries.map((e) => (
        <li key={e.id}>
          <button
            onClick={() => scrollTo(e.id)}
            aria-current={active === e.id ? "true" : undefined}
          >
            {e.title}
          </button>
        </li>
      ))}
    </ul>
  );
}

Sections are located with document.getElementById, so on the page itself it is enough to put ids on the headings.

Options

ids*string[]

Section ids, in the order they appear on the page.

offsetnumber | (() => number)

defaults to: 0

The top inset below which a section counts as «scrolled to» — usually the height of the sticky bar. Pass a function if that height depends on the screen width.

enabledboolean

defaults to: true

Turn tracking off.

Returns { active, scrollTo }. Smooth scrolling is disabled under prefers-reduced-motion.

Highlighting rules

The active section is the last one whose top edge has already passed the offset line. With two exceptions:

  • Before you have reached any of them — the first one is active. Otherwise nothing would be highlighted at the top of the page.
  • At the very bottom of the page — the last one is active. Short sections at the end physically cannot rise to the line, and without this rule they would never light up.

The arithmetic itself lives in activeSectionId(positions, line, atBottom) — a pure, DOM-free function covered by tests.