Skip to content

Commit 767b634

Browse files
barkertronChris Barker
andauthored
OI-224 Add in-page-nav variants (no scroll, two cols) (#313)
Co-authored-by: Chris Barker <chris.barker@nice.org.uk>
1 parent 184ff0a commit 767b634

4 files changed

Lines changed: 52 additions & 15 deletions

File tree

components/nds-in-page-nav/scss/in-page-nav.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,21 @@
5050
position: sticky;
5151
top: 0;
5252

53+
&--no-scroll {
54+
max-height: none;
55+
position: relative;
56+
}
57+
5358
&__list {
5459
flex-grow: 1;
5560
overflow: auto;
5661
padding-top: utils.rem(spacing.$x-small);
5762
scrollbar-width: thin;
5863

64+
.in-page-nav--two-columns & {
65+
columns: 2;
66+
}
67+
5968
.in-page-nav__list {
6069
height: 0;
6170
overflow: hidden;

components/nds-in-page-nav/src/InPageNav.tsx

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
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";
44
import throttle from "lodash.throttle";
55

66
import { 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

2123
export 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

components/nds-in-page-nav/src/__snapshots__/InPageNav.test.tsx.snap

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ exports[`InPageNav should match snapshot 1`] = `
55
"asFragment": [Function],
66
"baseElement": <div>
77
<nav
8-
aria-labelledby="inpagenav-title"
9-
class="in-page-nav "
8+
aria-labelledby=":r0:"
9+
class="in-page-nav"
1010
data-component="in-page-nav"
1111
data-track="false"
1212
>
1313
<h2
1414
class="in-page-nav__title"
15-
id="inpagenav-title"
15+
id=":r0:"
1616
>
1717
On this page
1818
</h2>
@@ -52,14 +52,14 @@ exports[`InPageNav should match snapshot 1`] = `
5252
</div>,
5353
"container": <div>
5454
<nav
55-
aria-labelledby="inpagenav-title"
56-
class="in-page-nav "
55+
aria-labelledby=":r0:"
56+
class="in-page-nav"
5757
data-component="in-page-nav"
5858
data-track="false"
5959
>
6060
<h2
6161
class="in-page-nav__title"
62-
id="inpagenav-title"
62+
id=":r0:"
6363
>
6464
On this page
6565
</h2>

docs/pages/testpage.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,18 @@ export default function Test() {
2121
sometimes be hard to debug components using MDX alone.
2222
</p>
2323

24-
<h2>Full bleed (default)</h2>
24+
<h2>In-page nav (no scroll)</h2>
25+
26+
<InPageNav noScroll />
27+
28+
<h2>In-page nav (no scroll, two cols)</h2>
29+
30+
<InPageNav noScroll twoColumns />
31+
32+
<h2>
33+
Full bleed (default) with a really massive title that should hopefully
34+
run onto the next line and maybe beyond
35+
</h2>
2536
<FullBleed>
2637
<h3>Full bleed heading</h3>
2738
<p>
@@ -90,9 +101,6 @@ export default function Test() {
90101

91102
<h2>Hero</h2>
92103
<Hero title="Hello!" header={<p>Here is a header</p>} />
93-
94-
<h2>In-page nav</h2>
95-
<InPageNav />
96104
</>
97105
);
98106
}

0 commit comments

Comments
 (0)