Skip to content

Commit

Permalink
fix: docs toc highlight on click (#1392)
Browse files Browse the repository at this point in the history
* fix: toc highlight on click - docs

* fix: Replace document query with inline conditional classes and tweak scroll magic scene settings

* test: force rebuild

Co-authored-by: svvimming <benmunozj@gmail.com>
Co-authored-by: orun <orun@agencyundone.com>
  • Loading branch information
3 people authored Jun 10, 2022
1 parent f6c427d commit 29f45ca
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 19 deletions.
2 changes: 1 addition & 1 deletion packages/website/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ TBD

## Docs

Docs are written in markdown and use Nextra.
Docs are written in markdown and uses [Nextra](https://nextra.vercel.app/).

Notes
- ensure that components (eg. `<Callout>... </Callout>`) are not indented
Expand Down
61 changes: 43 additions & 18 deletions packages/website/modules/docs-theme/toc/toc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEffect, useState } from 'react';
import { useEffect, useState, useRef } from 'react';
import clsx from 'clsx';

import { ReactComponent as Chevron } from '../../../assets/icons/chevron.svg';

Expand All @@ -10,8 +11,9 @@ if (typeof window !== 'undefined') {
export default function Toc() {
const [isOpen, setOpen] = useState(false);
const [nestedHeadings, setNestedHeadings] = useState([]);
const [updateKey, setUpdateKey] = useState(0);
const activeHeadings = useRef({});
let controller;
// const controller = new ScrollMagic.Controller();

const toggleClass = () => {
setOpen(!isOpen);
Expand All @@ -33,45 +35,68 @@ export default function Toc() {
return str;
};

const updateHeadings = (id) => {
for (const element in activeHeadings.current) {
if (activeHeadings.current[element]) {
activeHeadings.current[element] = false;
}
}
activeHeadings.current[id] = true;
setUpdateKey(key => key + 1);
}

const getNestedHeadings = headingElements => {
const nestedHeadings = [];
const headingIds = [];
headingElements.forEach((heading, index) => {
const id = string_to_slug(heading.innerText);
const title = heading.innerText;
activeHeadings.current[id] = false;
headingIds.push(id);
// add a[href] to headings
heading.innerHTML = '<a href="#' + id + '" id="' + id + '">' + title + '</a>';
// store toc data
if (heading.nodeName === 'H2') {
nestedHeadings.push({ id, title, items: [] });
} else if (heading.nodeName === 'H3' && nestedHeadings.length > 0) {
nestedHeadings[nestedHeadings.length - 1].items.push({
id,
title,
});
nestedHeadings[nestedHeadings.length - 1].items.push({ id, title });
}

// scroll effects / add active class
new ScrollMagic.Scene({ triggerElement: `#${id}` })
.on('enter leave', () => {
document.querySelectorAll('#toc a').forEach(el => {
el.classList.remove('active');
});
document.querySelector(`#toc a[href="#${id}"]`)?.classList.add('active');
})
.addTo(controller);
const exitScene = (e) => {
if (e.scrollDirection === 'REVERSE' && index !== 0) {
updateHeadings(headingIds[index - 1]);
}
}

const scene = new ScrollMagic.Scene({
triggerElement: `#${id}`,
triggerHook: 0.25,
duration: 200
}).on('enter', () => { updateHeadings(id) }).addTo(controller);
scene.on('leave', exitScene).addTo(controller);
});
return nestedHeadings;
};

const Headings = ({ headings }) => (
<ul>
{headings.map(heading => (
{headings.map((heading, i) => (
<li key={heading.id}>
<a href={`#${heading.id}`}>{heading.title}</a>
<a
href={`#${heading.id}`}
className={clsx(activeHeadings.current[heading.id] ? 'active' : '')}>
{heading.title}
</a>
{heading.items.length > 0 && (
<ul>
{heading.items.map(child => (
{heading.items.map((child, j) => (
<li key={child.id}>
<a href={`#${child.id}`}>{child.title}</a>
<a
href={`#${child.id}`}
className={clsx(activeHeadings.current[child.id] ? 'active' : '')}>
{child.title}
</a>
</li>
))}
</ul>
Expand Down

0 comments on commit 29f45ca

Please sign in to comment.