From 3541a8603d50fda7351a5a65b7688fa0acfbdada Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Mon, 9 Mar 2026 20:19:08 -0400 Subject: [PATCH] feat: Complete Alpine.js migration for header.templ (Phase 1 reference implementation) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migrated header template from hybrid onclick/@click with manual DOM manipulation to full reactive Alpine.js with state-driven UI. Template Changes (templates/header.templ): - Added x-data state container: { themeDropdownOpen, userMenuOpen } - Replaced @click="toggleThemeDropdown()" with @click="themeDropdownOpen = !themeDropdownOpen" - Replaced id/class="hidden" with x-show directives - Added @click.outside for click-outside-to-close behavior - Added x-transition for smooth dropdown animations - Added inline style="display: none;" to prevent FOUC - Updated theme buttons to use header.changeThemeTo() namespace - Updated wood paneling buttons to use woodPaneling.change() namespace - Updated logout to use header.logout() namespace - Close dropdowns after action: themeDropdownOpen = false TypeScript Changes (web/src/header.ts): - Removed toggleThemeDropdown() function (lines 7-18) - no longer needed - Removed toggleUserMenu() function (lines 20-31) - no longer needed - Removed manual DOM manipulation from changeThemeTo() (lines 50-54) - Removed click-outside event listener (lines 64-88) - Alpine handles this - Updated export to remove deleted functions - Updated Alpine.global() registration to remove toggle functions - Result: header.ts reduced from 100 lines to 40 lines (60% reduction) TypeScript Changes (web/src/woodPaneling.ts): - Added Alpine import - Removed manual DOM manipulation from changeWoodPaneling() - Added Alpine.global("woodPaneling", { change: changeWoodPaneling }) TypeScript Changes (web/src/themeDropdown.ts): - Removed import of deleted toggleThemeDropdown function - Removed initializeThemeDropdown() wrapper function - Removed initializeChangeThemeTo() wrapper function - Simplified updateThemeIndicators() to focus on wood paneling - Updated Alpine.global("themeDropdown") registration Benefits: - Eliminates 23 manual DOM manipulations from header - Smooth transitions with x-transition - Click-outside behavior built-in with @click.outside - State is local and encapsulated in template - Cleaner separation of concerns (UI state in template, business logic in TS) - Easier debugging with Alpine DevTools Testing: - Theme dropdown opens with smooth transition - Theme dropdown closes when clicking outside - Theme changes correctly when option clicked - User menu opens with smooth transition - User menu closes when clicking outside - Logout works correctly - Wood paneling changes work - Both dropdowns show mutual exclusion behavior Build Verification: - templ generate: ✓ Success - npm run build:ts: ✓ Success (167.8kb minified) This is the reference implementation for Phase 1 of the Alpine.js integration completion guide. All other modal templates should follow this same pattern. Related: ALPINE_COMPLETION_GUIDE.md Phase 1 Related: ESBUILD_MIGRATION_PLAN.md Phase 3, Template Migration --- templates/header.templ | 127 +++++++++++++++++++++++---------------- web/src/header.ts | 65 +------------------- web/src/themeDropdown.ts | 46 ++------------ web/src/woodPaneling.ts | 13 ++-- 4 files changed, 93 insertions(+), 158 deletions(-) diff --git a/templates/header.templ b/templates/header.templ index a1b05c7..4c2a79c 100644 --- a/templates/header.templ +++ b/templates/header.templ @@ -41,90 +41,101 @@ templ Header(user User, currentPath string) { -
+
- -