// alpine-init.js - Alpine.js component definitions // Navigation data is already available (loaded in before Alpine.js) // Alpine.js data stores and components document.addEventListener('alpine:init', () => { // Use navigation data from global scope (loaded in index.html ) const navigationAreas = window.navigationAreas || []; // Create a lookup map for easy access by area ID const areaTopicsMap = {}; navigationAreas.forEach(area => { areaTopicsMap[area.id] = { title: area.navTitle, topics: area.topics.map(topic => ({ id: topic.id, name: topic.navName })) }; }); // Global navigation state Alpine.store('navigation', { currentArea: null, currentTopic: null, currentPage: null, setArea(area) { this.currentArea = area; this.updateTopicNav(); }, setTopic(topic) { this.currentTopic = topic; this.updateTopicNav(); }, setPage(page) { this.currentPage = page; this.updateTopicNav(); }, updateTopicNav() { // Trigger update in topic navigation component if (window.Alpine) { const event = new CustomEvent('navigation-updated', { detail: { area: this.currentArea, topic: this.currentTopic, page: this.currentPage } }); window.dispatchEvent(event); } } }); // Mobile Topic Navigation Component // Uses navigation data generated from areas.js Alpine.data('mobileTopicNav', () => ({ areas: navigationAreas.map(area => ({ id: area.id, title: area.navTitle, topics: area.topics.map(topic => ({ id: topic.id, name: topic.navName })) })) })); // Home Hover Component Alpine.data('homeHover', () => ({ homeHovered: false, setHomeHover(state) { this.homeHovered = state; window.dispatchEvent(new CustomEvent('home-hovered', { detail: { hovered: state } })); } })); // Area Hover Component (for showing topics on hover) Alpine.data('areaHover', () => ({ hoveredArea: null, // Make navigation areas available to the template areas: navigationAreas, setHover(area) { this.hoveredArea = area; this.homeHovered = false; // Clear home hover when hovering area // Trigger update in topic navigation window.dispatchEvent(new CustomEvent('area-hovered', { detail: { area } })); window.dispatchEvent(new CustomEvent('home-hovered', { detail: { hovered: false } })); }, clearAllHover() { this.hoveredArea = null; this.homeHovered = false; window.dispatchEvent(new CustomEvent('area-hovered', { detail: { area: null } })); window.dispatchEvent(new CustomEvent('home-hovered', { detail: { hovered: false } })); }, isActiveArea(area) { return window.router && window.router.currentArea === area; } })); // Sub-Navigation Component (combines Home and Area menus) Alpine.data('subNavigation', () => ({ // Area state areaId: null, areaTitle: '', topics: [], currentTopic: null, hoveredArea: null, // Home state homeHovered: false, isHomePage: false, // Computed properties get showHomeMenu() { // Show home menu if we're hovering over Home OR if we're on the home page return this.homeHovered || this.isHomePage; }, get showAreaMenu() { // Show area menu if we're hovering over an area OR if we're on an area page // BUT hide if we're showing the home menu return (this.areaId !== null || this.hoveredArea !== null) && !this.showHomeMenu; }, get displayAreaId() { return this.hoveredArea || this.areaId; }, get displayAreaTitle() { const area = this.hoveredArea || this.areaId; return area && areaTopicsMap[area] ? areaTopicsMap[area].title : ''; }, get displayTopics() { const area = this.hoveredArea || this.areaId; return area && areaTopicsMap[area] ? areaTopicsMap[area].topics : []; }, init() { // Listen for navigation updates window.addEventListener('navigation-updated', (e) => { this.updateFromRouter(e.detail.area, e.detail.topic, e.detail.page); }); // Listen for area hover window.addEventListener('area-hovered', (e) => { this.hoveredArea = e.detail.area; }); // Listen for home hover window.addEventListener('home-hovered', (e) => { this.homeHovered = e.detail.hovered; }); // Initial update from router if (window.router) { this.updateFromRouter( window.router.currentArea, window.router.currentTopic, window.router.currentPage ); } }, updateFromRouter(area, topic, page) { // Update home page status this.isHomePage = page === 'home' && !area; // Update area and topic if (area && areaTopicsMap[area]) { this.areaId = area; this.areaTitle = areaTopicsMap[area].title; this.topics = areaTopicsMap[area].topics; this.currentTopic = topic || null; } else { this.areaId = null; this.areaTitle = ''; this.topics = []; this.currentTopic = null; } } })); });