diff --git a/static/hyperscript/utils._hs b/static/hyperscript/utils._hs index 57a4155..1b74b37 100644 --- a/static/hyperscript/utils._hs +++ b/static/hyperscript/utils._hs @@ -170,6 +170,24 @@ def setFooterHover(show) end end +-- ============================================================================== +-- NAVIGATION SCROLL +-- ============================================================================== +-- Smooth scroll to a section by ID +def scrollToSection(evt, sectionId) + if evt then call evt.preventDefault() end + set el to document.getElementById(sectionId) + if el is not null + call el.scrollIntoView({ behavior: 'smooth' }) + -- Close the menu after navigation + set menu to document.querySelector('.navigation-menu') + if menu is not null + remove .menu-hover from menu + remove .menu-open from menu + end + end +end + -- ============================================================================== -- KEYBOARD SHORTCUTS -- ============================================================================== diff --git a/static/js/main.js b/static/js/main.js index 866ddde..84ae6da 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -91,18 +91,7 @@ }); } - /** - * Close menu when navigation links are clicked - * CSS handles scrolling with scroll-behavior: smooth - */ - function initMenuCloseOnClick() { - document.addEventListener('click', (e) => { - const navLink = e.target.closest('.submenu-content a[href^="#"]'); - if (navLink) { - document.querySelector('.navigation-menu')?.classList.remove('menu-hover', 'menu-open'); - } - }); - } + // Menu close on nav click is now handled by scrollToSection() in utils._hs // ============================================================================= // PREFERENCES & LANGUAGE @@ -265,16 +254,7 @@ toast?.classList.remove('show'); }; - /** - * Close button handler for error toast - */ - function initErrorToastClose() { - document.addEventListener('click', (e) => { - if (e.target.closest('.error-close')) { - document.getElementById('error-toast')?.classList.remove('show'); - } - }); - } + // Error toast close handled by hyperscript inline in error-toast.html // ============================================================================= // HTMX EVENT HANDLERS @@ -491,9 +471,7 @@ */ document.addEventListener('DOMContentLoaded', function() { initMenuSystem(); - initMenuCloseOnClick(); initPreferences(); - initErrorToastClose(); initHTMXHandlers(); handleLandscapeAccordions(); // Auto-open sidebar accordions in landscape mode // Note: Scroll behavior now handled by hyperscript in index.html body tag @@ -501,75 +479,6 @@ // initScrollBehaviorJS() removed - hyperscript handleScroll() is preferred }); - /** - * JavaScript-based scroll behavior (fallback for hyperscript) - * Desktop: Hide header on scroll down, show on scroll up - * Mobile (≤900px): Always show header (CSS handles this, but we skip adding class) - */ - function initScrollBehaviorJS() { - let lastScrollY = 0; - const scrollThreshold = 100; - const actionBar = document.querySelector('.action-bar'); - const navMenu = document.querySelector('.navigation-menu'); - - if (!actionBar) return; - - function isMobileViewport() { - return window.innerWidth <= 900; - } - - function handleScroll() { - const currentScrollY = window.scrollY || window.pageYOffset; - - // Skip header hiding logic on mobile - CSS override handles visibility - // but we still avoid adding the class for cleaner state - if (isMobileViewport()) { - // On mobile, always ensure header is visible - actionBar.classList.remove('header-hidden'); - if (navMenu) navMenu.classList.remove('header-hidden'); - lastScrollY = currentScrollY; - return; - } - - // At top of page - always show header - if (currentScrollY <= scrollThreshold) { - actionBar.classList.remove('header-hidden'); - if (navMenu && navMenu.classList.contains('menu-open')) { - navMenu.classList.remove('header-hidden'); - } - } - // Scrolling DOWN past threshold - hide header - else if (currentScrollY > lastScrollY && currentScrollY > scrollThreshold) { - actionBar.classList.add('header-hidden'); - if (navMenu && navMenu.classList.contains('menu-open')) { - navMenu.classList.add('header-hidden'); - } - } - // Scrolling UP - show header - else if (currentScrollY < lastScrollY) { - actionBar.classList.remove('header-hidden'); - if (navMenu && navMenu.classList.contains('menu-open')) { - navMenu.classList.remove('header-hidden'); - } - } - - lastScrollY = currentScrollY; - } - - // Use passive listener for better scroll performance - window.addEventListener('scroll', handleScroll, { passive: true }); - - // Also handle resize (viewport changes) - window.addEventListener('resize', function() { - if (isMobileViewport()) { - actionBar.classList.remove('header-hidden'); - if (navMenu) navMenu.classList.remove('header-hidden'); - } - }); - - console.log('Scroll behavior JS initialized'); - } - // ============================================================================= // HYPERSCRIPT-POWERED FEATURES (NO JS NEEDED) // ============================================================================= diff --git a/templates/partials/widgets/error-toast.html b/templates/partials/widgets/error-toast.html index 7e7c3ff..c51cdc3 100644 --- a/templates/partials/widgets/error-toast.html +++ b/templates/partials/widgets/error-toast.html @@ -3,6 +3,7 @@
{{end}}