feat(52-mobile-main-menu): hamburger + slide-in overlay sidebar na mobile

Zastapienie niedzialajacej nawigacji horyzontalnej pelnoekranowym
overlay sidebar z hamburgerem, backdrop i animacja CSS transform.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-29 23:15:52 +02:00
parent cbc2058b83
commit 1c87489824
8 changed files with 3710 additions and 40 deletions

View File

@@ -115,8 +115,17 @@
</nav>
</aside>
<div class="sidebar-backdrop" id="js-sidebar-backdrop"></div>
<div class="app-main">
<header class="topbar">
<button class="topbar__hamburger" id="js-hamburger" type="button" aria-label="Otwórz menu">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="3" y1="6" x2="21" y2="6"/>
<line x1="3" y1="12" x2="21" y2="12"/>
<line x1="3" y1="18" x2="21" y2="18"/>
</svg>
</button>
<div>
<strong><?= $e((string) (($user['name'] ?? '') !== '' ? $user['name'] : ($user['email'] ?? ''))) ?></strong>
</div>
@@ -167,6 +176,60 @@
}
});
});
// Mobile menu
var hamburger = document.getElementById('js-hamburger');
var backdrop = document.getElementById('js-sidebar-backdrop');
var mobileQuery = window.matchMedia('(max-width: 768px)');
function closeMobileMenu() {
sidebar.classList.remove('is-mobile-open');
backdrop.classList.remove('is-visible');
document.body.classList.remove('no-scroll');
}
function openMobileMenu() {
sidebar.classList.add('is-mobile-open');
backdrop.classList.add('is-visible');
document.body.classList.add('no-scroll');
}
if (hamburger) {
hamburger.addEventListener('click', function () {
if (sidebar.classList.contains('is-mobile-open')) {
closeMobileMenu();
} else {
openMobileMenu();
}
});
}
if (backdrop) {
backdrop.addEventListener('click', closeMobileMenu);
}
// Close button (collapse-btn acts as X on mobile)
collapseBtn.addEventListener('click', function () {
if (mobileQuery.matches) {
closeMobileMenu();
}
});
// Close on navigation link click (mobile only)
sidebar.querySelectorAll('.sidebar__link, .sidebar__sublink').forEach(function (link) {
link.addEventListener('click', function () {
if (mobileQuery.matches) {
closeMobileMenu();
}
});
});
// Reset state on resize to desktop
mobileQuery.addEventListener('change', function (e) {
if (!e.matches) {
closeMobileMenu();
}
});
})();
</script>
</body>