Files
student-web-if-development-kit/groups/Tapops/js/controllers/navigation-controller.js
T
2026-06-04 18:13:23 +07:00

89 lines
3.1 KiB
JavaScript

export class NavigationController {
constructor({
menuSelector = '[data-menu]',
overlayId = 'mega-overlay',
} = {}) {
this.menuItems = Array.from(document.querySelectorAll(menuSelector));
this.overlay = document.getElementById(overlayId);
this.activeMenu = null;
this.menuMap = {
tentang: 'mega-tentang',
program: 'mega-program',
sdm: 'mega-sdm',
fasilitas: 'mega-fasilitas',
karya: 'mega-karya',
kontak: 'mega-kontak',
};
}
init() {
if (this.menuItems.length === 0 || !this.overlay) return;
this.menuItems.forEach(item => {
const menuId = item.getAttribute('data-menu');
const button = item.querySelector('.nav-menu-btn');
if (!button) return;
button.setAttribute('aria-haspopup', 'true');
button.setAttribute('aria-expanded', 'false');
button.addEventListener('click', event => {
event.preventDefault();
event.stopPropagation();
if (this.activeMenu === menuId) {
this.closeMenus();
} else {
this.openMenu(menuId);
}
});
});
this.overlay.addEventListener('click', () => this.closeMenus());
document.addEventListener('click', event => this._handleOutsideClick(event));
document.addEventListener('keydown', event => {
if (event.key === 'Escape' && this.activeMenu) this.closeMenus();
});
}
openMenu(menuId) {
const targetPanel = document.getElementById(this.menuMap[menuId]);
if (!targetPanel) return;
Object.values(this.menuMap).forEach(panelId => {
document.getElementById(panelId)?.classList.remove('active');
});
targetPanel.classList.add('active');
this.overlay.classList.add('active');
this._setButtonState(menuId);
this.activeMenu = menuId;
}
closeMenus() {
Object.values(this.menuMap).forEach(panelId => {
document.getElementById(panelId)?.classList.remove('active');
});
this.overlay.classList.remove('active');
this._setButtonState(null);
this.activeMenu = null;
}
_setButtonState(menuId) {
this.menuItems.forEach(item => {
const isActive = item.getAttribute('data-menu') === menuId;
const button = item.querySelector('.nav-menu-btn');
const chevron = item.querySelector('.fa-chevron-down');
button?.classList.toggle('active', isActive);
button?.setAttribute('aria-expanded', isActive ? 'true' : 'false');
if (chevron) chevron.style.transform = isActive ? 'rotate(180deg)' : '';
});
}
_handleOutsideClick(event) {
const clickedInsideNav = event.target.closest('#main-nav');
const clickedInsidePanel = event.target.closest('.mega-panel');
if (!clickedInsideNav && !clickedInsidePanel && this.activeMenu) this.closeMenus();
}
}