/** * Kanbante — sidebar behaviour (issue #16, 0.16.0 layout). * Desktop: collapse to an icon rail (persisted in localStorage). * Mobile: the same sidebar becomes an off-canvas drawer, toggled * by the topbar burger, closed by backdrop / Escape / navigation. */ (function () { var burger = document.getElementById('nav-burger'); var backdrop = document.getElementById('side-backdrop'); var collapseBtn = document.getElementById('side-collapse'); function closeDrawer() { document.body.classList.remove('sidebar-open'); if (backdrop) backdrop.hidden = true; if (burger) { burger.setAttribute('aria-expanded', 'false'); burger.textContent = '☰'; } } if (burger) { burger.addEventListener('click', function () { var open = document.body.classList.toggle('sidebar-open'); burger.setAttribute('aria-expanded', open ? 'true' : 'false'); burger.textContent = open ? '✕' : '☰'; if (backdrop) backdrop.hidden = !open; }); } if (backdrop) backdrop.addEventListener('click', closeDrawer); document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeDrawer(); }); window.addEventListener('resize', function () { if (window.innerWidth > 900) closeDrawer(); }); if (collapseBtn) { collapseBtn.addEventListener('click', function () { var collapsed = document.body.classList.toggle('sidebar-collapsed'); try { localStorage.setItem('kanbante-sidebar', collapsed ? 'collapsed' : 'open'); } catch (e) { /* private mode: state lasts for the page only */ } }); } /* Accordion sections: the closed set lives in body classes (applied pre-paint by the bootstrap script in _header.html) and is persisted here on every toggle. */ var groupBtns = document.querySelectorAll('[data-group-btn]'); function persistClosedGroups() { var closed = []; groupBtns.forEach(function (btn) { if (document.body.classList.contains('nav-closed-' + btn.getAttribute('data-group-btn'))) { closed.push(btn.getAttribute('data-group-btn')); } }); try { localStorage.setItem('kanbante-nav-closed', JSON.stringify(closed)); } catch (e) { /* non-fatal */ } } function syncGroupBtn(btn) { var closed = document.body.classList.contains( 'nav-closed-' + btn.getAttribute('data-group-btn')); btn.setAttribute('aria-expanded', closed ? 'false' : 'true'); } groupBtns.forEach(function (btn) { syncGroupBtn(btn); btn.addEventListener('click', function () { document.body.classList.toggle( 'nav-closed-' + btn.getAttribute('data-group-btn')); syncGroupBtn(btn); persistClosedGroups(); }); }); /* The section holding the current page is always opened. */ var activeLink = document.querySelector('.sidebar .side-link.active'); if (activeLink) { var section = activeLink.closest('.side-section'); if (section) { var key = section.getAttribute('data-group'); if (document.body.classList.contains('nav-closed-' + key)) { document.body.classList.remove('nav-closed-' + key); groupBtns.forEach(syncGroupBtn); persistClosedGroups(); } } } })();