overview / js /alpine-init.js
Yacine Jernite
v07
8ed13f7
raw
history blame
6.34 kB
// alpine-init.js - Alpine.js component definitions
// Navigation data is already available (loaded in <head> before Alpine.js)
// Alpine.js data stores and components
document.addEventListener('alpine:init', () => {
// Use navigation data from global scope (loaded in index.html <head>)
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;
}
}
}));
});