From a2a31f528be4aa4b9b5ca57cdce0a28c038243fd Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Sat, 4 Apr 2026 16:32:57 -0500 Subject: [PATCH] Sidebar accordions at all breakpoints, open on desktop, closed on mobile Accordion structure now applies at all screen sizes. On desktop (>= 992px) all panels start expanded (show class + aria-expanded true). On mobile (< 992px) all panels start collapsed. CSS no longer scoped to mobile media query. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/media/css/template.css | 54 +++++++++--------- src/media/js/template.js | 109 ++++++++++++------------------------- 2 files changed, 60 insertions(+), 103 deletions(-) diff --git a/src/media/css/template.css b/src/media/css/template.css index 4d2a3dc..5aaf9b5 100644 --- a/src/media/css/template.css +++ b/src/media/css/template.css @@ -15844,37 +15844,35 @@ body:not(.has-sidebar-right) .site-grid .container-component { grid-area: side-r; } -/* Sidebar accordion on mobile */ -@media (max-width: 991.98px) { - .container-sidebar-left.accordion .card, - .container-sidebar-right.accordion .card { - border: none; - border-bottom: 1px solid var(--border-color, #dee2e6); - border-radius: 0; - } +/* Sidebar accordion */ +.container-sidebar-left.accordion .card, +.container-sidebar-right.accordion .card { + border: none; + border-bottom: 1px solid var(--border-color, #dee2e6); + border-radius: 0; +} - .container-sidebar-left.accordion .card-header, - .container-sidebar-right.accordion .card-header { - padding: 0; - background: none; - border: none; - } +.container-sidebar-left.accordion .card-header, +.container-sidebar-right.accordion .card-header { + padding: 0; + background: none; + border: none; +} - .container-sidebar-left.accordion .accordion-button, - .container-sidebar-right.accordion .accordion-button { - padding: .75rem 1rem; - font-weight: 600; - font-size: .95rem; - background: var(--bs-body-bg, #fff); - color: var(--body-font-color, #444); - } +.container-sidebar-left.accordion .accordion-button, +.container-sidebar-right.accordion .accordion-button { + padding: .75rem 1rem; + font-weight: 600; + font-size: .95rem; + background: var(--bs-body-bg, #fff); + color: var(--body-font-color, #444); +} - .container-sidebar-left.accordion .accordion-button:not(.collapsed), - .container-sidebar-right.accordion .accordion-button:not(.collapsed) { - background: var(--bs-body-bg, #fff); - color: var(--link-color, #3565e5); - box-shadow: none; - } +.container-sidebar-left.accordion .accordion-button:not(.collapsed), +.container-sidebar-right.accordion .accordion-button:not(.collapsed) { + background: var(--bs-body-bg, #fff); + color: var(--link-color, #3565e5); + box-shadow: none; } .container-main-top { diff --git a/src/media/js/template.js b/src/media/js/template.js index 34beca6..4504bb3 100644 --- a/src/media/js/template.js +++ b/src/media/js/template.js @@ -497,87 +497,46 @@ var sidebars = doc.querySelectorAll(".container-sidebar-left, .container-sidebar-right"); if (!sidebars.length) return; - var accordionised = false; + // Build accordion structure once — works at all breakpoints + sidebars.forEach(function (sidebar, si) { + var accId = "sidebarAcc-" + si; + sidebar.setAttribute("id", accId); + sidebar.classList.add("accordion"); - function apply() { var isMobile = win.innerWidth < BREAKPOINT; + var cards = sidebar.querySelectorAll(":scope > .card"); - if (isMobile && !accordionised) { - sidebars.forEach(function (sidebar, si) { - var accId = "sidebarAcc-" + si; - sidebar.setAttribute("id", accId); - sidebar.classList.add("accordion"); + cards.forEach(function (card, ci) { + var collapseId = accId + "-c" + ci; + card.classList.add("accordion-item"); - var cards = sidebar.querySelectorAll(":scope > .card"); - cards.forEach(function (card, ci) { - var collapseId = accId + "-c" + ci; - card.classList.add("accordion-item"); + var header = card.querySelector(".card-header"); + var body = card.querySelector(".card-body"); + if (!header || !body) return; - var header = card.querySelector(".card-header"); - var body = card.querySelector(".card-body"); - if (!header || !body) return; + // Turn header into accordion button + header.classList.add("accordion-header"); + var btn = doc.createElement("button"); + btn.className = isMobile ? "accordion-button collapsed" : "accordion-button"; + btn.type = "button"; + btn.setAttribute("data-bs-toggle", "collapse"); + btn.setAttribute("data-bs-target", "#" + collapseId); + btn.setAttribute("aria-expanded", isMobile ? "false" : "true"); + btn.setAttribute("aria-controls", collapseId); + btn.textContent = header.textContent; + header.textContent = ""; + header.appendChild(btn); - // Turn header into accordion button - header.classList.add("accordion-header"); - var btn = doc.createElement("button"); - btn.className = "accordion-button collapsed"; - btn.type = "button"; - btn.setAttribute("data-bs-toggle", "collapse"); - btn.setAttribute("data-bs-target", "#" + collapseId); - btn.setAttribute("aria-expanded", "false"); - btn.setAttribute("aria-controls", collapseId); - btn.textContent = header.textContent; - header.textContent = ""; - header.appendChild(btn); - header.setAttribute("data-moko-original-text", btn.textContent); - - // Wrap body in collapse - var wrapper = doc.createElement("div"); - wrapper.id = collapseId; - wrapper.className = "accordion-collapse collapse"; - wrapper.setAttribute("data-bs-parent", "#" + accId); - card.insertBefore(wrapper, body); - wrapper.appendChild(body); - body.classList.add("accordion-body"); - }); - }); - accordionised = true; - } else if (!isMobile && accordionised) { - // Revert to plain cards - sidebars.forEach(function (sidebar) { - sidebar.classList.remove("accordion"); - sidebar.removeAttribute("id"); - - var cards = sidebar.querySelectorAll(":scope > .card"); - cards.forEach(function (card) { - card.classList.remove("accordion-item"); - - var header = card.querySelector(".card-header"); - var btn = header ? header.querySelector(".accordion-button") : null; - if (header && btn) { - var text = header.getAttribute("data-moko-original-text") || btn.textContent; - header.removeAttribute("data-moko-original-text"); - header.classList.remove("accordion-header"); - header.textContent = text; - } - - var wrapper = card.querySelector(".accordion-collapse"); - if (wrapper) { - var body = wrapper.querySelector(".card-body"); - if (body) { - body.classList.remove("accordion-body"); - card.appendChild(body); - } - wrapper.parentNode.removeChild(wrapper); - } - }); - }); - accordionised = false; - } - } - - apply(); - win.addEventListener("resize", apply); + // Wrap body in collapse + var wrapper = doc.createElement("div"); + wrapper.id = collapseId; + wrapper.className = isMobile ? "accordion-collapse collapse" : "accordion-collapse collapse show"; + wrapper.setAttribute("data-bs-parent", "#" + accId); + card.insertBefore(wrapper, body); + wrapper.appendChild(body); + body.classList.add("accordion-body"); + }); + }); } /**