From 689ca9be2c1d958252edfd19aa980b3c2b1c4a8d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 19 Jul 2026 02:13:01 +0200 Subject: [PATCH 1/2] Persist sidebar fold state Load a global nav-state script via Zensical extra_javascript so first-level nav groups open by default and fold/unfold state persists across navigation. Remove navigation.expand to avoid force-expanding all levels. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/docs/nav-state.js | 86 +++++++++++++++++++++++++++++++++++++++ .github/zensical.toml | 2 +- 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 .github/docs/nav-state.js diff --git a/.github/docs/nav-state.js b/.github/docs/nav-state.js new file mode 100644 index 0000000..f78a3f1 --- /dev/null +++ b/.github/docs/nav-state.js @@ -0,0 +1,86 @@ +(() => { + const storageKey = "zensical-nav-state-v1"; + let lastSignature = ""; + + const getToggles = () => + Array.from(document.querySelectorAll("input.md-nav__toggle.md-toggle[id]")); + + const getPrimaryList = () => + document.querySelector("nav.md-nav--primary > ul.md-nav__list"); + + const applyDefaultTopLevelState = (toggles) => { + const primaryList = getPrimaryList(); + if (!primaryList) { + return; + } + + const topLevelToggles = Array.from( + primaryList.querySelectorAll( + ":scope > li > input.md-nav__toggle.md-toggle[id]" + ) + ); + const topLevelIds = new Set(topLevelToggles.map((toggle) => toggle.id)); + + for (const toggle of toggles) { + toggle.checked = topLevelIds.has(toggle.id); + } + }; + + const restoreState = (toggles) => { + const raw = localStorage.getItem(storageKey); + if (!raw) { + applyDefaultTopLevelState(toggles); + return; + } + + try { + const state = JSON.parse(raw); + for (const toggle of toggles) { + if (Object.prototype.hasOwnProperty.call(state, toggle.id)) { + toggle.checked = !!state[toggle.id]; + } + } + } catch { + applyDefaultTopLevelState(toggles); + } + }; + + const persistState = (toggles) => { + const state = {}; + for (const toggle of toggles) { + state[toggle.id] = !!toggle.checked; + } + localStorage.setItem(storageKey, JSON.stringify(state)); + }; + + const initialize = () => { + const toggles = getToggles(); + if (toggles.length === 0) { + return; + } + + const signature = toggles.map((toggle) => toggle.id).join("|"); + if (signature === lastSignature) { + return; + } + + lastSignature = signature; + restoreState(toggles); + for (const toggle of toggles) { + if (toggle.dataset.navStateBound === "true") { + continue; + } + + toggle.dataset.navStateBound = "true"; + toggle.addEventListener("change", () => persistState(getToggles())); + } + }; + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initialize, { once: true }); + } else { + initialize(); + } + + setInterval(initialize, 500); +})(); diff --git a/.github/zensical.toml b/.github/zensical.toml index cdfe063..d454ba5 100644 --- a/.github/zensical.toml +++ b/.github/zensical.toml @@ -2,6 +2,7 @@ site_name = "-{{ REPO_NAME }}-" repo_name = "-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-" repo_url = "https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-" +extra_javascript = ["https://cdn.jsdelivr.net/gh/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-@main/.github/docs/nav-state.js"] [project.theme] language = "en" @@ -22,7 +23,6 @@ features = [ "navigation.instant", "navigation.instant.progress", "navigation.indexes", - "navigation.expand", "navigation.top", "navigation.tracking", "search.share", From 6b4e01eed5b024dd2436529e05f3efd778ab3229 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 19 Jul 2026 02:17:31 +0200 Subject: [PATCH 2/2] Trigger docs publish for nav state Add a non-rendered README marker to trigger the full docs publishing path so the nav-state script deployment is reflected on GitHub Pages. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 68db4f3..aefaee4 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ display: none !important; } + {{ DESCRIPTION }}