PathLogs UI
English

Hooks

useActiveSection

Подсветка активного раздела длинной страницы при прокрутке.

Подсветка активного раздела при прокрутке — и плавный переход к нему по клику. Оглавление справа на этой странице работает на нём же.

Пример

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

function Toc({ entries }) {
  const { active, scrollTo } = useActiveSection(
    entries.map((e) => e.id),
    { offset: 80 }        // высота липкой шапки
  );

  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>
  );
}

Разделы находятся по document.getElementById, так что на самой странице достаточно проставить id заголовкам.

Параметры

ids*string[]

Идентификаторы разделов в порядке их следования на странице.

offsetnumber | (() => number)

по умолчанию: 0

Отступ сверху, ниже которого раздел считается «доскроллили» — обычно высота липкой панели. Функцией, если высота зависит от ширины экрана.

enabledboolean

по умолчанию: true

Выключить слежение.

Возвращает { active, scrollTo }. Плавность прокрутки отключается при prefers-reduced-motion.

Правила подсветки

Активен последний раздел, чья верхняя граница уже прошла линию отступа. Два исключения:

  • Пока не доскроллили ни до одного — активен первый. Иначе в начале страницы не подсвечивалось бы ничего.
  • У самого низа страницы — активен последний. Короткие разделы в конце физически не могут подняться к линии, и без этого правила они никогда бы не подсветились.

Сама арифметика вынесена в activeSectionId(positions, line, atBottom) — чистую функцию без DOM, покрытую тестами.