diff --git a/packages/website/README.md b/packages/website/README.md
index c7fb52b579..f4014f9555 100644
--- a/packages/website/README.md
+++ b/packages/website/README.md
@@ -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. `... `) are not indented
diff --git a/packages/website/modules/docs-theme/toc/toc.js b/packages/website/modules/docs-theme/toc/toc.js
index 0bedbfc066..adf20c26d5 100644
--- a/packages/website/modules/docs-theme/toc/toc.js
+++ b/packages/website/modules/docs-theme/toc/toc.js
@@ -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';
@@ -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);
@@ -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 = '' + title + '';
// 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 }) => (