diff --git a/docs/src/assets/js/main.js b/docs/src/assets/js/main.js index 28ec0e1306b..bf3268266f4 100644 --- a/docs/src/assets/js/main.js +++ b/docs/src/assets/js/main.js @@ -1,3 +1,42 @@ +(function () { + // for sticky table of contents + const tocBody = document.querySelector(".docs-aside #js-toc-panel"); + const options = { + root: null, + rootMargin: `0px 0px -90% 0px`, + threshold: 1.0, + }; + const activeClassName = "active"; + const observer = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + const activeAnchor = tocBody.querySelector( + `a.${activeClassName}` + ); + if (activeAnchor) { + activeAnchor.parentNode.classList.remove(activeClassName); + activeAnchor.classList.remove(activeClassName); + } + + const nextActiveAnchor = tocBody.querySelector( + `a[href="#${entry.target.id}"]` + ); + if (nextActiveAnchor) { + nextActiveAnchor.parentNode.classList.add(activeClassName); + nextActiveAnchor.classList.add(activeClassName); + } + } + }); + }, options); + if (window.matchMedia("(min-width: 1400px)").matches) { + document + .querySelectorAll( + "#main > div > h2[id], #main > div > h3[id], #main > div > h4[id]" // only h2, h3, h4 are shown in toc + ) + .forEach((el) => observer.observe(el)); + } +})(); + (function() { var toc_trigger = document.getElementById("js-toc-label"), toc = document.getElementById("js-toc-panel"), @@ -279,4 +318,4 @@ if (index) { document.addEventListener("DOMContentLoaded", () => { anchors.add(".docs-content h2:not(.c-toc__label), .docs-content h3, .docs-content h4"); -}); \ No newline at end of file +}); diff --git a/docs/src/assets/scss/components/toc.scss b/docs/src/assets/scss/components/toc.scss index 5e2e66a166a..74da310b325 100644 --- a/docs/src/assets/scss/components/toc.scss +++ b/docs/src/assets/scss/components/toc.scss @@ -18,6 +18,30 @@ } } +.docs-aside { + // for sticky table of contents in sidebar + .docs-toc.c-toc { + background-color: var(--body-background-color); + @media all and (min-width: 1400px) { + position: sticky; + top: 20px; + overflow-y: auto; // show scrollbar when toc is higher than viewport + padding-right: 5px; // push scrollbar away from content + max-height: calc(100vh - 32px); // minus element's margin-top + a.active { + color: var(--link-color); + font-weight: 500; + } + } + } + + .c-toc ol li.active::before { + @media all and (min-width: 1400px) { + color: var(--link-color); + } + } +} + .c-toc { ol { margin: 0;