summaryrefslogtreecommitdiffstats
path: root/themes/danix-xyz-hacker
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-04-16 15:57:37 +0200
committerDanilo M. <danix@danix.xyz>2026-04-16 15:57:37 +0200
commit80286039c0795211162b4ff4b8227f51b39fd918 (patch)
tree244d8e61c670becc12f8309087a182fc7471cb37 /themes/danix-xyz-hacker
parenta614ed818b7d435546bb86a887f97de53f019af1 (diff)
downloaddanixxyz-80286039c0795211162b4ff4b8227f51b39fd918.tar.gz
danixxyz-80286039c0795211162b4ff4b8227f51b39fd918.zip
fix: rewrite hamburger menu using Alpine.js event dispatcher
- Replace vanilla JS click handlers with Alpine.js @toggle-menu event - Hamburger button dispatches toggle-menu event on click - Menu overlay listens to toggle-menu and toggles menuOpen state - Alpine controls visibility via :class bindings (opacity/invisible) - Alpine controls panel slide via :class bindings (translate-x) - All menu interactions (close button, links, ESC, backdrop) use Alpine - Remove complex vanilla JS that wasn't working reliably - Rebuild CSS: main.min.css updated Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Diffstat (limited to 'themes/danix-xyz-hacker')
-rw-r--r--themes/danix-xyz-hacker/assets/css/main.min.css26
-rw-r--r--themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html104
-rw-r--r--themes/danix-xyz-hacker/layouts/partials/header.html4
3 files changed, 34 insertions, 100 deletions
diff --git a/themes/danix-xyz-hacker/assets/css/main.min.css b/themes/danix-xyz-hacker/assets/css/main.min.css
index 36c66d1..ab1f4bb 100644
--- a/themes/danix-xyz-hacker/assets/css/main.min.css
+++ b/themes/danix-xyz-hacker/assets/css/main.min.css
@@ -1487,23 +1487,6 @@ article.border.border-border\/30.rounded-lg.card.group.bg-bg {
/* Mobile menu overlay */
-.menu-overlay {
- visibility: hidden;
- position: fixed;
- inset: 0px;
- z-index: 40;
- background-color: var(--bg);
- opacity: 0;
- transition-property: all;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 300ms;
-}
-
-article.border.border-border\/30.rounded-lg.overflow-hidden.group.menu-overlay {
- border-color: var(--border);
- box-shadow: 0 0 20px var(--accent-glow);
-}
-
.menu-overlay.active {
visibility: visible;
opacity: 1;
@@ -1817,6 +1800,11 @@ article.border.border-border\/30.rounded-lg.overflow-hidden.group.menu-overlay {
flex-shrink: 0;
}
+.translate-x-0 {
+ --tw-translate-x: 0px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
.translate-x-full {
--tw-translate-x: 100%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
@@ -2163,6 +2151,10 @@ article.border.border-border\/30.rounded-lg.overflow-hidden.group.menu-overlay {
opacity: 0;
}
+.opacity-100 {
+ opacity: 1;
+}
+
.opacity-5 {
opacity: 0.05;
}
diff --git a/themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html b/themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html
index 4d02d9c..02e6d0d 100644
--- a/themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html
+++ b/themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html
@@ -1,17 +1,22 @@
+<!-- Mobile menu overlay (Alpine.js controlled) -->
<div
- id="menu-overlay"
- class="fixed inset-0 bg-black/50 backdrop-blur opacity-0 invisible transition-all duration-300 z-40"
- aria-hidden="true"
+ x-data="{ menuOpen: false }"
+ @toggle-menu.window="menuOpen = !menuOpen"
+ @keydown.escape.window="menuOpen = false"
+ :class="{ 'opacity-0 invisible': !menuOpen, 'opacity-100 visible': menuOpen }"
+ class="fixed inset-0 bg-black/50 backdrop-blur transition-all duration-300 z-40"
+ :aria-hidden="!menuOpen"
+ @click="if ($event.target === $el) menuOpen = false"
>
<div
- id="hamburger-menu"
- class="fixed top-0 right-0 h-screen w-full max-w-sm bg-bg border-l border-border overflow-y-auto transform translate-x-full transition-transform duration-300 z-50"
+ class="fixed top-0 right-0 h-screen w-full max-w-sm bg-bg border-l border-border overflow-y-auto transform transition-transform duration-300 z-50"
+ :class="{ 'translate-x-full': !menuOpen, 'translate-x-0': menuOpen }"
>
<!-- Close button -->
<div class="flex items-center justify-between p-6 border-b border-border">
<span class="font-bold text-lg text-accent font-oxanium">Menu</span>
<button
- id="menu-close"
+ @click="menuOpen = false"
aria-label="{{ i18n "closeMenu" }}"
class="p-2 hover:bg-surface rounded transition-colors"
>
@@ -24,6 +29,7 @@
{{ range .Site.Menus.main }}
<a
href="{{ .URL }}"
+ @click="menuOpen = false"
class="block py-4 text-lg font-medium hover:text-accent transition-colors border-b border-border/30"
>
{{ i18n .Name }}
@@ -54,6 +60,7 @@
{{ end }}
<a
href="{{ $url }}"
+ @click="menuOpen = false"
class="flex-1 py-2 px-3 text-center rounded transition-colors {{ if $current }}bg-accent text-white{{ else }}bg-surface hover:bg-surface/80{{ end }}"
>
{{ $langName }}
@@ -66,83 +73,18 @@
</div>
<script>
- function initializeHamburgerMenu() {
+ // Make menuOpen accessible from the menu toggle button
+ document.addEventListener('DOMContentLoaded', () => {
const menuToggle = document.getElementById('menu-toggle');
- const menuClose = document.getElementById('menu-close');
- const menuOverlay = document.getElementById('menu-overlay');
- const hamburgerMenu = document.getElementById('hamburger-menu');
-
- if (!menuToggle || !menuOverlay || !hamburgerMenu) {
- console.warn('Hamburger menu elements not found', {
- menuToggle: !!menuToggle,
- menuOverlay: !!menuOverlay,
- hamburgerMenu: !!hamburgerMenu
- });
- return;
- }
-
- const openMenu = () => {
- menuOverlay.classList.remove('opacity-0', 'invisible');
- hamburgerMenu.classList.remove('translate-x-full');
- menuOverlay.setAttribute('aria-hidden', 'false');
- document.body.style.overflow = 'hidden';
- menuToggle.setAttribute('aria-expanded', 'true');
- };
-
- const closeMenu = () => {
- menuOverlay.classList.add('opacity-0', 'invisible');
- hamburgerMenu.classList.add('translate-x-full');
- menuOverlay.setAttribute('aria-hidden', 'true');
- document.body.style.overflow = '';
- menuToggle.setAttribute('aria-expanded', 'false');
- };
-
- // Toggle button click
- menuToggle.addEventListener('click', (e) => {
- e.preventDefault();
- e.stopPropagation();
- if (menuOverlay.classList.contains('opacity-0')) {
- openMenu();
- } else {
- closeMenu();
- }
- });
-
- // Close button click
- if (menuClose) {
- menuClose.addEventListener('click', (e) => {
+ if (menuToggle && window.__alpineInstances) {
+ menuToggle.addEventListener('click', (e) => {
e.preventDefault();
- closeMenu();
+ // Find the Alpine component and toggle it
+ const overlay = document.querySelector('[x-data*="menuOpen"]');
+ if (overlay && overlay.__x) {
+ overlay.__x.$data.menuOpen = !overlay.__x.$data.menuOpen;
+ }
});
}
-
- // Close on ESC key
- document.addEventListener('keydown', (e) => {
- if (e.key === 'Escape' && !menuOverlay.classList.contains('opacity-0')) {
- closeMenu();
- }
- });
-
- // Close when clicking menu links
- const menuLinks = hamburgerMenu.querySelectorAll('a');
- menuLinks.forEach(link => {
- link.addEventListener('click', (e) => {
- closeMenu();
- });
- });
-
- // Close when clicking the overlay (but not the menu panel)
- menuOverlay.addEventListener('click', (e) => {
- if (e.target === menuOverlay) {
- closeMenu();
- }
- });
- }
-
- // Run when DOM is ready
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', initializeHamburgerMenu);
- } else {
- initializeHamburgerMenu();
- }
+ });
</script>
diff --git a/themes/danix-xyz-hacker/layouts/partials/header.html b/themes/danix-xyz-hacker/layouts/partials/header.html
index cd77032..8722e81 100644
--- a/themes/danix-xyz-hacker/layouts/partials/header.html
+++ b/themes/danix-xyz-hacker/layouts/partials/header.html
@@ -57,9 +57,9 @@
<!-- Hamburger menu button (mobile only) -->
<button
- id="menu-toggle"
+ x-data
+ @click="$dispatch('toggle-menu')"
aria-label="{{ i18n "toggleMenu" }}"
- aria-expanded="false"
aria-controls="hamburger-menu"
class="md:hidden p-2 rounded hover:bg-surface transition-colors"
>