UNPKG

@govbr-ds/webcomponents

Version:

Biblioteca de Web Components baseado no GovBR-DS

147 lines (120 loc) 4.17 kB
// MENU gerado automaticamente (preenchido via menu-index.json) let MENU_ITEMS = [] // Expõe referências no escopo global para integração com pageLoader.js window.MENU_ITEMS = MENU_ITEMS const MENU_BODY = document.querySelector('.menu-body') window.MENU_BODY = MENU_BODY const MENU_FILTER = document.getElementById('menu-filter') const CLEAR_MENU_FILTER = document.getElementById('clear-menu-filter') const menuButton = document.getElementById('menu-button') const responsiveMenuButton = document.getElementById('responsive-menu-button') const menuElement = document.getElementById('main-navigation') const iconElement = menuButton.querySelector('i') async function loadMenuItems() { const baseUrl = getBaseUrl() try { const res = await fetch(`${baseUrl}/assets/menu-index.json`, { cache: 'no-cache' }) if (!res.ok) throw new Error(`HTTP ${res.status}`) const items = await res.json() if (Array.isArray(items)) { MENU_ITEMS = items window.MENU_ITEMS = MENU_ITEMS } else { console.warn('menu-index.json inválido, esperado um array') MENU_ITEMS = [] } } catch (err) { console.warn('Falha ao carregar menu-index.json, usando menu vazio.', err) MENU_ITEMS = [] } } function setLinks() { const baseUrl = getBaseUrl() MENU_ITEMS.sort(compareByNames).forEach((page) => { const link = document.createElement('a') link.href = `${baseUrl}/${page.path}` link.className = 'menu-item br-link' link.textContent = page.name link.addEventListener('click', (event) => { event.preventDefault() if (link.classList.contains('active')) { return } removeAllActiveClasses() link.classList.add('active') loadPage(page.path, page.files) window.history.pushState({}, '', `${baseUrl}/${page.path}`) if (window.innerWidth <= 575) { toggleMenu() } }) MENU_BODY.appendChild(link) }) const divider = document.createElement('div') // Garante que o body do menu esteja acessível globalmente após montar os links window.MENU_BODY = MENU_BODY } function filterMenu() { const filterValue = MENU_FILTER.value.toLowerCase() const menuItems = MENU_BODY.querySelectorAll('.menu-item') menuItems.forEach((item) => { if (item.textContent.toLowerCase().includes(filterValue)) { item.style.display = '' } else { item.style.display = 'none' } }) CLEAR_MENU_FILTER.style.display = filterValue ? 'block' : 'none' } function clearInput() { MENU_FILTER.value = '' filterMenu() } window.addEventListener('load', async () => { await loadMenuItems() setLinks() // O roteador será iniciado pelo pageLoader via bootstrapRouting menuButton.addEventListener('click', toggleMenu) responsiveMenuButton.addEventListener('click', toggleMenu) const mediaQuery = window.matchMedia('(min-width: 576px)') mediaQuery.addEventListener('change', handleMediaChange) function handleMediaChange(event) { if (event.matches && responsiveMenuButton) responsiveMenuButton.style.display = 'none' if (!event.matches && responsiveMenuButton) responsiveMenuButton.style.display = '' } handleMediaChange(mediaQuery) MENU_FILTER.addEventListener('input', filterMenu) CLEAR_MENU_FILTER.addEventListener('click', clearInput) // Garante estado inicial do body conforme o menu syncBodyMenuState() }) function removeAllActiveClasses() { const menuItems = document.querySelectorAll('.menu-item') menuItems.forEach((item) => { item.classList.remove('active') }) } function toggleMenu() { menuElement.classList.toggle('active') if (menuElement.classList.contains('active')) { iconElement.classList.remove('fa-bars') iconElement.classList.add('fa-times') } else { iconElement.classList.add('fa-bars') iconElement.classList.remove('fa-times') } syncBodyMenuState() } function compareByNames(a, b) { if (a.name < b.name) { return -1 } if (a.name > b.name) { return 1 } return 0 } function syncBodyMenuState() { const isOpen = menuElement.classList.contains('active') document.body.classList.toggle('menu-open', isOpen) }