From 4751a99e8e0610dbcb5fe52c5c653e4193d34786 Mon Sep 17 00:00:00 2001 From: luxick Date: Thu, 23 Apr 2026 10:56:05 +0200 Subject: [PATCH] Refactor calendar widget changes --- assets/diary/diary-calendar.html | 3 +- assets/diary/diary-calendar.js | 32 +-------------- assets/global-shortcuts.js | 30 ++++++++++++++ assets/page-actions.js | 21 +--------- assets/page.html | 5 +-- assets/style.css | 70 ++++---------------------------- assets/toc.js | 4 +- main.go | 6 +-- render.go | 2 +- 9 files changed, 51 insertions(+), 122 deletions(-) diff --git a/assets/diary/diary-calendar.html b/assets/diary/diary-calendar.html index 7a1cd41..a76c430 100644 --- a/assets/diary/diary-calendar.html +++ b/assets/diary/diary-calendar.html @@ -1,5 +1,5 @@
- +
{{.MonthName}} + diff --git a/assets/diary/diary-calendar.js b/assets/diary/diary-calendar.js index 075e3d6..2ef1fee 100644 --- a/assets/diary/diary-calendar.js +++ b/assets/diary/diary-calendar.js @@ -4,7 +4,7 @@ var toggle = document.createElement("button"); toggle.type = "button"; - toggle.className = "diary-cal-toggle"; + toggle.className = "panel-toggle"; toggle.textContent = "Kalender"; toggle.setAttribute("aria-expanded", "false"); toggle.addEventListener("click", function () { @@ -18,35 +18,7 @@ main.parentNode.insertBefore(cal, main); } - // Wire up month/year dropdowns inside the calendar. - var drops = cal.querySelectorAll(".diary-cal-drop"); - drops.forEach(function (drop) { - var trigger = drop.querySelector("button"); - var menu = drop.querySelector(".dropdown-menu"); - if (!trigger || !menu) return; - trigger.addEventListener("click", function (e) { - e.stopPropagation(); - drops.forEach(function (other) { - if (other !== drop) { - other.querySelector(".dropdown-menu").classList.remove("is-open"); - } - }); - menu.classList.toggle("is-open"); - }); - }); - document.addEventListener("click", function (e) { - drops.forEach(function (drop) { - if (!drop.contains(e.target)) { - drop.querySelector(".dropdown-menu").classList.remove("is-open"); - } - }); - }); - document.addEventListener("keydown", function (e) { - if (e.key !== "Escape") return; - drops.forEach(function (drop) { - drop.querySelector(".dropdown-menu").classList.remove("is-open"); - }); - }); + cal.querySelectorAll(".diary-cal-drop > button").forEach(wireDropdown); var pageHeader = document.querySelector("header"); function updateTop() { diff --git a/assets/global-shortcuts.js b/assets/global-shortcuts.js index 1082910..572d682 100644 --- a/assets/global-shortcuts.js +++ b/assets/global-shortcuts.js @@ -17,3 +17,33 @@ } }); })(); + +// Wire a dropdown: clicking the trigger toggles its sibling .dropdown-menu; +// clicking outside or pressing Escape closes all wired menus. Safe to call +// multiple times on the same trigger (no-op on re-registration). +function wireDropdown(trigger) { + if (!trigger || trigger.dataset.wired) return; + var menu = trigger.parentElement && trigger.parentElement.querySelector('.dropdown-menu'); + if (!menu) return; + trigger.dataset.wired = '1'; + trigger.addEventListener('click', function (e) { + e.stopPropagation(); + document.querySelectorAll('.dropdown-menu.is-open').forEach(function (m) { + if (m !== menu) m.classList.remove('is-open'); + }); + menu.classList.toggle('is-open'); + }); + menu.addEventListener('click', function () { menu.classList.remove('is-open'); }); +} + +document.addEventListener('click', function (e) { + document.querySelectorAll('.dropdown-menu.is-open').forEach(function (menu) { + if (!menu.parentElement.contains(e.target)) menu.classList.remove('is-open'); + }); +}); +document.addEventListener('keydown', function (e) { + if (e.key !== 'Escape') return; + document.querySelectorAll('.dropdown-menu.is-open').forEach(function (menu) { + menu.classList.remove('is-open'); + }); +}); diff --git a/assets/page-actions.js b/assets/page-actions.js index 7cb90f9..47b987b 100644 --- a/assets/page-actions.js +++ b/assets/page-actions.js @@ -68,24 +68,5 @@ function deletePage() { } document.addEventListener('DOMContentLoaded', function () { - var trigger = document.querySelector('[data-action="actions-drop"]'); - if (!trigger) return; - var menu = trigger.parentElement.querySelector('.dropdown-menu'); - if (!menu) return; - - trigger.addEventListener('click', function (e) { - e.stopPropagation(); - menu.classList.toggle('is-open'); - }); - menu.addEventListener('click', function () { - menu.classList.remove('is-open'); - }); - document.addEventListener('click', function (e) { - if (!trigger.contains(e.target) && !menu.contains(e.target)) { - menu.classList.remove('is-open'); - } - }); - document.addEventListener('keydown', function (e) { - if (e.key === 'Escape') menu.classList.remove('is-open'); - }); + wireDropdown(document.querySelector('[data-action="actions-drop"]')); }); diff --git a/assets/page.html b/assets/page.html index 5ee64b1..52835ad 100644 --- a/assets/page.html +++ b/assets/page.html @@ -99,9 +99,6 @@ {{end}} {{end}} - {{if .DiaryWidget}} - {{.DiaryWidget}} - - {{end}} + {{if .SidebarWidget}}{{.SidebarWidget}}{{end}} diff --git a/assets/style.css b/assets/style.css index 2426a42..8a89534 100644 --- a/assets/style.css +++ b/assets/style.css @@ -417,7 +417,7 @@ hr { font-size: 0.85rem; } -.toc-header { +.panel-header { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; @@ -455,7 +455,7 @@ hr { padding-left: 1.6rem; } -.toc-toggle { +.panel-toggle { display: none; } @@ -528,16 +528,6 @@ hr { font-size: 0.85rem; } -.diary-cal-label { - font-size: 0.75rem; - text-transform: uppercase; - letter-spacing: 0.05em; - color: var(--text-muted); - border-bottom: 1px dashed var(--secondary); - padding-bottom: 0.25rem; - margin-bottom: 0.4rem; -} - .diary-cal-nav { display: flex; align-items: center; @@ -609,13 +599,9 @@ hr { color: var(--primary-hover); } -.diary-cal-toggle { - display: none; -} - /* === Responsive === */ @media (max-width: 1100px) { - .diary-cal-toggle { + .panel-toggle { display: block; background: none; border: 1px solid var(--secondary); @@ -630,13 +616,14 @@ hr { width: calc(100% - 2rem); max-width: 860px; } - .diary-cal-toggle::before { + .panel-toggle::before { content: "▸ "; color: var(--secondary); } - .diary-cal-toggle[aria-expanded="true"]::before { + .panel-toggle[aria-expanded="true"]::before { content: "▾ "; } + .toc, .diary-cal { position: static; display: none; @@ -645,48 +632,12 @@ hr { margin: 0 auto 1rem; max-height: none; } + .toc.is-open, .diary-cal.is-open { display: block; } } -/* === Responsive === */ -@media (max-width: 1100px) { - .toc-toggle { - display: block; - background: none; - border: 1px solid var(--secondary); - color: var(--text); - font: inherit; - font-size: 0.8rem; - text-transform: uppercase; - letter-spacing: 0.05em; - cursor: pointer; - padding: 0.4rem 0.75rem; - margin: 1rem auto; - width: calc(100% - 2rem); - max-width: 860px; - } - .toc-toggle::before { - content: "▸ "; - color: var(--secondary); - } - .toc-toggle[aria-expanded="true"]::before { - content: "▾ "; - } - .toc { - position: static; - display: none; - width: calc(100% - 2rem); - max-width: 860px; - margin: 0 auto 1rem; - max-height: none; - } - .toc.is-open { - display: block; - } -} - @media (max-width: 600px) { header { padding: 0.5rem 0.75rem; @@ -697,11 +648,8 @@ hr { textarea { min-height: 50vh; } - .toc-toggle, - .toc.is-open { - width: calc(100% - 1.5rem); - } - .diary-cal-toggle, + .panel-toggle, + .toc.is-open, .diary-cal.is-open { width: calc(100% - 1.5rem); } diff --git a/assets/toc.js b/assets/toc.js index c797477..2309d57 100644 --- a/assets/toc.js +++ b/assets/toc.js @@ -9,7 +9,7 @@ nav.className = "toc"; var header = document.createElement("div"); - header.className = "toc-header"; + header.className = "panel-header"; header.textContent = "Contents"; nav.appendChild(header); @@ -28,7 +28,7 @@ var toggle = document.createElement("button"); toggle.type = "button"; - toggle.className = "toc-toggle"; + toggle.className = "panel-toggle"; toggle.textContent = "Contents"; toggle.setAttribute("aria-expanded", "false"); toggle.addEventListener("click", function () { diff --git a/main.go b/main.go index 3cf36e7..dcb5e83 100644 --- a/main.go +++ b/main.go @@ -170,10 +170,10 @@ func (h *handler) serveDir(w http.ResponseWriter, r *http.Request, urlPath, fsPa } var specialContent template.HTML - var diaryWidget template.HTML + var sidebarWidget template.HTML if special != nil { specialContent = special.Content - diaryWidget = special.Widget + sidebarWidget = special.Widget } rawContent := string(rawMD) @@ -196,7 +196,7 @@ func (h *handler) serveDir(w http.ResponseWriter, r *http.Request, urlPath, fsPa Content: rendered, Entries: entries, SpecialContent: specialContent, - DiaryWidget: diaryWidget, + SidebarWidget: sidebarWidget, } w.Header().Set("Content-Type", "text/html; charset=utf-8") diff --git a/render.go b/render.go index ce61b7f..9170988 100644 --- a/render.go +++ b/render.go @@ -46,7 +46,7 @@ type pageData struct { Content template.HTML Entries []entry SpecialContent template.HTML - DiaryWidget template.HTML + SidebarWidget template.HTML } // pageSettings holds the parsed contents of a .page-settings file.