]> danix's work - danix.xyz-2.git/commitdiff
feat: create hamburger overlay menu with language and theme toggles
authorDanilo M. <redacted>
Wed, 15 Apr 2026 13:28:40 +0000 (15:28 +0200)
committerDanilo M. <redacted>
Wed, 15 Apr 2026 13:28:40 +0000 (15:28 +0200)
themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html [new file with mode: 0644]

diff --git a/themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html b/themes/danix-xyz-hacker/layouts/partials/hamburger-menu.html
new file mode 100644 (file)
index 0000000..9ce3b75
--- /dev/null
@@ -0,0 +1,112 @@
+<div
+  id="menu-overlay"
+  class="fixed inset-0 bg-black/50 backdrop-blur opacity-0 invisible transition-all duration-200 z-40"
+  @click="closeMenu()"
+>
+  <div
+    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"
+    @click.stop
+    x-ref="menuPanel"
+  >
+    <!-- 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
+        @click="closeMenu()"
+        aria-label="{{ i18n "closeMenu" }}"
+        class="p-2 hover:bg-surface rounded transition-colors"
+      >
+        <i data-feather="x" class="w-5 h-5"></i>
+      </button>
+    </div>
+
+    <!-- Menu items -->
+    <nav class="p-6">
+      {{ range .Site.Menus.main }}
+        <a
+          href="{{ .URL }}"
+          class="block py-4 text-lg font-medium hover:text-accent transition-colors border-b border-border/30"
+        >
+          {{ i18n .Name }}
+        </a>
+      {{ end }}
+    </nav>
+
+    <!-- Divider -->
+    <div class="border-t border-border/30 mx-6"></div>
+
+    <!-- Language switcher -->
+    <div class="p-6">
+      <div class="text-sm text-text-dim mb-3">{{ i18n "language" }}</div>
+      <div class="flex gap-2">
+        {{ range .Site.Languages }}
+          {{ $current := eq . $.Page.Language }}
+          <a
+            href="{{ .LanguagePrefix }}"
+            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 }}"
+          >
+            {{ .LanguageName }}
+          </a>
+        {{ end }}
+      </div>
+    </div>
+
+    <!-- Theme toggle -->
+    <div class="p-6 border-t border-border/30">
+      <button
+        @click="toggleTheme(); closeMenu()"
+        class="w-full py-3 px-4 bg-surface hover:bg-surface/80 rounded flex items-center justify-center gap-2 transition-colors"
+      >
+        <i data-feather="moon" class="w-4 h-4"></i>
+        <span>{{ i18n "toggleTheme" }}</span>
+      </button>
+    </div>
+  </div>
+</div>
+
+<script>
+  document.addEventListener('alpine:init', () => {
+    Alpine.store('menu', {
+      isOpen: false,
+      toggle() {
+        this.isOpen = !this.isOpen;
+        document.getElementById('menu-overlay').classList.toggle('opacity-0');
+        document.getElementById('menu-overlay').classList.toggle('invisible');
+        document.querySelector('[x-ref="menuPanel"]').classList.toggle('translate-x-full');
+        document.body.style.overflow = this.isOpen ? 'hidden' : '';
+      },
+      close() {
+        if (this.isOpen) {
+          this.toggle();
+        }
+      }
+    });
+  });
+
+  function closeMenu() {
+    Alpine.store('menu').close();
+  }
+
+  function toggleTheme() {
+    const html = document.documentElement;
+    const isDark = html.classList.contains('theme-dark');
+    const newTheme = isDark ? 'light' : 'dark';
+    html.classList.remove('theme-light', 'theme-dark');
+    html.classList.add('theme-' + newTheme);
+    localStorage.setItem('theme', newTheme);
+    feather.replace();
+  }
+
+  document.getElementById('menu-toggle').addEventListener('click', () => {
+    Alpine.store('menu').toggle();
+  });
+
+  document.getElementById('theme-toggle').addEventListener('click', toggleTheme);
+
+  // Close menu on Escape key
+  document.addEventListener('keydown', (e) => {
+    if (e.key === 'Escape') {
+      closeMenu();
+    }
+  });
+</script>