forked from izu/student-web-if-development-kit
89 lines
3.1 KiB
JavaScript
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();
|
|
}
|
|
}
|