Active Heading
A scroll-spy hook that reports which heading the reader is on, for marking the current item in a table of contents.
documentationactiveheading
Loading interactive preview
A scroll-spy hook that reports which heading the reader is on, for marking the current item in a table of contents.
A scroll-spy hook that reports which heading the reader is on, for marking the current item in a table of contents.
A scroll-spy hook that reports which heading the reader is on, for marking the current item in a table of contents.
'use client';
import { useEffect, useState } from 'react';
export interface ActiveHeadingOptions {
/**
* How far below the top of the viewport a heading counts as reached, in px.
* Match it to any sticky header so a heading is active once it clears it.
*/
offset?: number;
}
/**
* Returns the id of the heading the reader is currently on: the last heading
* whose top has scrolled past `offset`. Before the first heading is reached it
* returns the first id, so a table of contents always marks something.
*/
export function useActiveHeading(ids: string[], { offset = 96 }: ActiveHeadingOptions = {}): string | null {
const [active, setActive] = useState<string | null>(ids[0] ?? null);
// Keyed on the ids' content, so a fresh array with the same ids each render
// does not tear the observer down.
const key = ids.join('\n');
useEffect(() => {
const elements = key
.split('\n')
.map((id) => document.getElementById(id))
.filter((element): element is HTMLElement => element !== null);Unlock everything with Supporter
The complete source and every other premium item unlock with Supporter.
Unlock everything with Supporter
The complete source and every other premium item unlock with Supporter.