Hooks
useActiveSection
Подсветка активного раздела длинной страницы при прокрутке.
Подсветка активного раздела при прокрутке — и плавный переход к нему по клику. Оглавление справа на этой странице работает на нём же.
Пример
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[] | — | Идентификаторы разделов в порядке их следования на странице. |
offset | number | (() => number) | 0 | Отступ сверху, ниже которого раздел считается «доскроллили» — обычно высота липкой панели. Функцией, если высота зависит от ширины экрана. |
enabled | boolean | true | Выключить слежение. |
ids*string[]Идентификаторы разделов в порядке их следования на странице.
offsetnumber | (() => number)по умолчанию: 0
Отступ сверху, ниже которого раздел считается «доскроллили» — обычно высота липкой панели. Функцией, если высота зависит от ширины экрана.
enabledbooleanпо умолчанию: true
Выключить слежение.
Возвращает { active, scrollTo }. Плавность прокрутки отключается при prefers-reduced-motion.
Правила подсветки
Активен последний раздел, чья верхняя граница уже прошла линию отступа. Два исключения:
- Пока не доскроллили ни до одного — активен первый. Иначе в начале страницы не подсвечивалось бы ничего.
- У самого низа страницы — активен последний. Короткие разделы в конце физически не могут подняться к линии, и без этого правила они никогда бы не подсветились.
Сама арифметика вынесена в activeSectionId(positions, line, atBottom) — чистую функцию без DOM, покрытую тестами.