Files
oak-gpui/docs/theme/page-toc.js
T
Danilo Leal 557d39332c docs: Add sidebar title collapse functionality and design facelift (#43754)
This PR adds the ability to collapse section in the docs sidebar (which
are persistent until you close the tab), and some design facelift to the
docs, which makes its design close to the site as well as polishing up
many elements and interactions (like moving the search to a modal and
making the table of content visible in smaller breakpoints).

<img width="600" height="2270" alt="Screenshot 2025-11-28 at 5  26@2x"
src="https://github.com/user-attachments/assets/3a8606c6-f74f-4bd2-84c8-d7a67ff97564"
/>

Release Notes:

- N/A
2025-11-28 17:36:50 -03:00

91 lines
2.6 KiB
JavaScript

let scrollTimeout;
const listenActive = () => {
const elems = document.querySelector(".pagetoc").children;
[...elems].forEach((el) => {
el.addEventListener("click", (event) => {
clearTimeout(scrollTimeout);
[...elems].forEach((el) => el.classList.remove("active"));
el.classList.add("active");
// Prevent scroll updates for a short period
scrollTimeout = setTimeout(() => {
scrollTimeout = null;
}, 100); // Adjust timing as needed
});
});
};
const getPagetoc = () =>
document.querySelector(".pagetoc") || autoCreatePagetoc();
const autoCreatePagetoc = () => {
const main = document.querySelector("#content > main");
const content = Object.assign(document.createElement("div"), {
className: "content-wrap",
});
content.append(...main.childNodes);
main.prepend(content);
main.insertAdjacentHTML(
"afterbegin",
'<div class="sidetoc"><nav class="pagetoc"></nav></div>',
);
return document.querySelector(".pagetoc");
};
const updateFunction = () => {
if (scrollTimeout) return; // Skip updates if within the cooldown period from a click
const headers = [...document.getElementsByClassName("header")];
const scrolledY = window.scrollY;
let lastHeader = null;
// Find the last header that is above the current scroll position
for (let i = headers.length - 1; i >= 0; i--) {
if (scrolledY >= headers[i].offsetTop) {
lastHeader = headers[i];
break;
}
}
const pagetocLinks = [...document.querySelector(".pagetoc").children];
pagetocLinks.forEach((link) => link.classList.remove("active"));
if (lastHeader) {
const activeLink = pagetocLinks.find(
(link) => lastHeader.href === link.href,
);
if (activeLink) activeLink.classList.add("active");
}
};
window.addEventListener("load", () => {
const pagetoc = getPagetoc();
const headers = [...document.getElementsByClassName("header")];
const nonH1Headers = headers.filter(
(header) => !header.parentElement.tagName.toLowerCase().startsWith("h1"),
);
const sidetoc = document.querySelector(".sidetoc");
const tocContainer = document.querySelector(".toc-container");
if (nonH1Headers.length === 0) {
if (sidetoc) {
sidetoc.style.display = "none";
}
if (tocContainer) {
tocContainer.style.display = "none";
}
return;
}
headers.forEach((header) => {
const link = Object.assign(document.createElement("a"), {
textContent: header.text,
href: header.href,
className: `pagetoc-${header.parentElement.tagName}`,
});
pagetoc.appendChild(link);
});
updateFunction();
listenActive();
window.addEventListener("scroll", updateFunction);
});