11/* eslint-disable no-mixed-spaces-and-tabs */
22/* eslint-disable indent */
3- import React , { useEffect , useState } from "react" ;
3+ import React , { useEffect , useState , useId } from "react" ;
44import throttle from "lodash.throttle" ;
55
66import { buildLinkTree , getActiveHeadingId , type LinkTreeItem } from "./utils" ;
@@ -16,6 +16,8 @@ export interface InPageNavProps {
1616 headingsExcludeSelector ?: string ;
1717 headingsExcludeContainer ?: string ;
1818 scrollTolerance ?: number ;
19+ noScroll ?: boolean ;
20+ twoColumns ?: boolean ;
1921}
2022
2123export const InPageNav = ( {
@@ -25,12 +27,15 @@ export const InPageNav = ({
2527 headingsExcludeSelector = "" , // Exclude any matched elements
2628 headingsExcludeContainer = "" , // Exclude all headings within this container
2729 scrollTolerance = 50 , // In pixels
30+ noScroll = false ,
31+ twoColumns = false ,
2832 ...rest
2933} : InPageNavProps ) => {
3034 const [ activeHeadingId , setActiveHeadingId ] = useState < null | string > ( null ) ;
3135 const [ linkTree , setlinkTree ] = useState < LinkTreeItem [ ] > ( [ ] ) ;
36+ const titleId = useId ( ) ;
3237
33- // Build the tree if links to use in the nav, from the headings found on the page
38+ // Build the tree of links from the headings on the page
3439 useEffect ( ( ) => {
3540 const headingsContainerElement = document . querySelector (
3641 headingsContainerSelector
@@ -72,6 +77,8 @@ export const InPageNav = ({
7277
7378 // Now that we've built the tree of links, work out which is active based on scroll position
7479 useEffect ( ( ) => {
80+ if ( noScroll ) return ; // No point highlighting links in the no scroll variant
81+
7582 const scrollHandler = throttle ( ( ) => {
7683 setActiveHeadingId ( getActiveHeadingId ( linkTree , scrollTolerance ) ) ;
7784 } , 100 ) ;
@@ -87,14 +94,27 @@ export const InPageNav = ({
8794
8895 if ( linkTree . length === 0 ) return null ;
8996
97+ const classNames = [ "in-page-nav" ] ;
98+ if ( className ) {
99+ classNames . push ( className ) ;
100+ }
101+ if ( noScroll ) {
102+ classNames . push ( "in-page-nav--no-scroll" ) ;
103+
104+ // We're only allowing two columns within the noScroll variant
105+ if ( twoColumns ) {
106+ classNames . push ( "in-page-nav--two-columns" ) ;
107+ }
108+ }
109+
90110 return (
91111 < nav
92- className = { [ "in-page-nav" , className ] . join ( " " ) }
93- aria-labelledby = "inpagenav-title"
112+ className = { classNames . join ( " " ) }
113+ aria-labelledby = { titleId }
94114 data-component = "in-page-nav"
95115 { ...rest }
96116 >
97- < h2 id = "inpagenav-title" className = "in-page-nav__title" >
117+ < h2 id = { titleId } className = "in-page-nav__title" >
98118 On this page
99119 </ h2 >
100120 < ol
0 commit comments