From c50d6a9334c15b13c440a57169922d9c1a31c24f Mon Sep 17 00:00:00 2001 From: Joanna Ong Date: Tue, 31 May 2022 14:17:07 -0400 Subject: [PATCH 1/3] fix: toc highlight on click - docs --- packages/website/modules/docs-theme/toc/toc.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/website/modules/docs-theme/toc/toc.js b/packages/website/modules/docs-theme/toc/toc.js index 0bedbfc066..b5404e0ad3 100644 --- a/packages/website/modules/docs-theme/toc/toc.js +++ b/packages/website/modules/docs-theme/toc/toc.js @@ -11,7 +11,6 @@ export default function Toc() { const [isOpen, setOpen] = useState(false); const [nestedHeadings, setNestedHeadings] = useState([]); let controller; - // const controller = new ScrollMagic.Controller(); const toggleClass = () => { setOpen(!isOpen); @@ -49,15 +48,16 @@ export default function Toc() { 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 toggleClass = () => { + document.querySelectorAll('#toc a').forEach(el => { + el.classList.remove('active'); + }); + document.querySelector(`#toc a[href="#${id}"]`)?.classList.add('active'); + }; + new ScrollMagic.Scene({ triggerElement: `#${id}` }).on('enter', toggleClass).addTo(controller); + new ScrollMagic.Scene({ triggerElement: `#${id}`, triggerHook: 0 }).on('leave', toggleClass).addTo(controller); }); return nestedHeadings; }; From c0c036dde3b28d39b7d3e3e37b4b8cda781e684a Mon Sep 17 00:00:00 2001 From: svvimming Date: Wed, 8 Jun 2022 11:32:03 -0400 Subject: [PATCH 2/3] fix: Replace document query with inline conditional classes and tweak scroll magic scene settings --- .../website/modules/docs-theme/toc/toc.js | 59 +++++++++++++------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/packages/website/modules/docs-theme/toc/toc.js b/packages/website/modules/docs-theme/toc/toc.js index b5404e0ad3..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,6 +11,8 @@ 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 toggleClass = () => { @@ -32,46 +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 - const toggleClass = () => { - document.querySelectorAll('#toc a').forEach(el => { - el.classList.remove('active'); - }); - document.querySelector(`#toc a[href="#${id}"]`)?.classList.add('active'); - }; - new ScrollMagic.Scene({ triggerElement: `#${id}` }).on('enter', toggleClass).addTo(controller); - new ScrollMagic.Scene({ triggerElement: `#${id}`, triggerHook: 0 }).on('leave', toggleClass).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 }) => (