summaryrefslogtreecommitdiffstats
path: root/layouts/partials/hamburger-menu.html
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-04-22 12:42:56 +0200
committerDanilo M. <danix@danix.xyz>2026-04-22 12:42:56 +0200
commit631547a75142326a7c71bdf123e1475217a5ad73 (patch)
treef3cfef6b3c5b42bf626fc823ddcf63b8dcf4cdbb /layouts/partials/hamburger-menu.html
parent77ccbe72fad5a4870185fff374f75471c16a9043 (diff)
downloaddanixxyz-theme-631547a75142326a7c71bdf123e1475217a5ad73.tar.gz
danixxyz-theme-631547a75142326a7c71bdf123e1475217a5ad73.zip
chore: replace with extracted danix.xyz-hacker theme (danix2-hugo-theme)
Diffstat (limited to 'layouts/partials/hamburger-menu.html')
-rw-r--r--layouts/partials/hamburger-menu.html125
1 files changed, 125 insertions, 0 deletions
diff --git a/layouts/partials/hamburger-menu.html b/layouts/partials/hamburger-menu.html
new file mode 100644
index 0000000..5d8d8ed
--- /dev/null
+++ b/layouts/partials/hamburger-menu.html
@@ -0,0 +1,125 @@
+<!-- Mobile menu overlay (Alpine.js controlled) -->
+<div
+ x-cloak
+ 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
+ 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
+ @click="menuOpen = false"
+ 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" role="navigation" aria-label="{{ i18n "mainMenu" }}">
+ {{ $currentPath := strings.TrimSuffix "/" .RelPermalink }}
+ {{ range .Site.Menus.main }}
+ {{ $menuPath := strings.TrimSuffix "/" .URL }}
+ {{ $isActive := eq $menuPath $currentPath }}
+ <a
+ href="{{ .URL }}"
+ @click="menuOpen = false"
+ class="block py-4 text-lg font-medium transition-colors border-b border-border/30 {{ if $isActive }}text-accent font-bold{{ else }}hover:text-accent{{ end }}"
+ {{ if $isActive }}aria-current="page"{{ end }}
+ >
+ {{ i18n .Name }}
+ </a>
+ {{ end }}
+ </nav>
+
+ <!-- Mobile search bar -->
+ <div class="p-6 border-b border-border" x-data="mobileSearch()">
+ <label for="search-input-mobile" class="sr-only">
+ {{ i18n "searchPlaceholder" }}
+ </label>
+ <input
+ id="search-input-mobile"
+ type="text"
+ :value="searchQuery"
+ @input="filterArticles($el.value); ensureIndexLoaded()"
+ placeholder="{{ i18n "searchPlaceholder" }}"
+ class="w-full px-4 py-2 border-2 border-border rounded focus:outline-none focus:ring-2 focus:ring-accent focus:border-transparent bg-bg text-text text-sm"
+ aria-describedby="mobile-search-results"
+ />
+
+ <!-- Mobile search results -->
+ <div id="mobile-search-results" class="mt-3 space-y-2" x-show="filteredArticles.length > 0" role="region" aria-live="polite">
+ <template x-for="article in filteredArticles" :key="article.url">
+ <div class="p-3 border-l-4 border-accent bg-bg/50 hover:bg-bg/70 transition-colors rounded text-sm">
+ <a :href="article.url" @click="menuOpen = false" class="block focus:outline-none focus:ring-2 focus:ring-accent rounded px-1 py-1">
+ <h4 class="font-bold text-accent" x-text="article.title"></h4>
+ <p class="text-xs text-text-dim mt-0.5" x-text="article.date"></p>
+ </a>
+ </div>
+ </template>
+ </div>
+
+ <!-- Empty state -->
+ <div
+ x-show="searchQuery && filteredArticles.length === 0"
+ class="mt-3 text-sm text-text-dim"
+ role="status"
+ >
+ {{ i18n "noSearchResults" }}
+ </div>
+ </div>
+
+ <!-- Language switcher -->
+ <div class="p-6">
+ <div class="text-sm text-text-dim mb-3">{{ i18n "language" }}</div>
+ <div class="flex gap-2">
+ {{ $currentLang := .Page.Language }}
+ {{ $currentPath := .RelPermalink }}
+ {{ range .Site.Languages }}
+ {{ $langCode := .Lang }}
+ {{ $langName := .LanguageName }}
+ {{ $current := eq $langCode $currentLang }}
+ <!-- Build the translated URL by replacing language prefix -->
+ {{ $url := $currentPath }}
+ {{ if eq $langCode "en" }}
+ {{ if hasPrefix $currentPath "/it/" }}
+ {{ $url = strings.TrimPrefix "/it" $currentPath }}
+ {{ end }}
+ {{ else }}
+ {{ if not (hasPrefix $currentPath "/it/") }}
+ {{ $url = printf "/it%s" $currentPath }}
+ {{ end }}
+ {{ 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 }}
+ </a>
+ {{ end }}
+ </div>
+ </div>
+
+ </div>
+</div>
+
+<script>
+ // Close menu before page navigation to prevent flicker
+ window.addEventListener('beforeunload', () => {
+ const overlay = document.querySelector('[x-data*="menuOpen"]');
+ if (overlay && overlay.__x) {
+ overlay.__x.$data.menuOpen = false;
+ }
+ });
+</script>