homegrade_theme_production/resources/js/menus.js
2025-08-04 11:24:36 +02:00

409 lines
14 KiB
JavaScript

export default function menuInit() {
const header = document.querySelector('#main-header');
const footer = document.querySelector('footer');
if (!header) return;
// Search module
const searchModule = header.querySelector('.search-module');
// const searchModuleToggle = header.querySelector('#search-module-toggle');
const searchModuleToggles = header.querySelectorAll('#search-module-toggle');
// Mobile Menu
const mobileMenuToggle = header.querySelector('#mobile-menu-toggle');
/* -----------------------------------------------------------
HANDLE SUBMENUS
-----------------------------------------------------------*/
// SubmenusToggles
const headerSubmenuToggles = header.querySelectorAll('.menu-item__submenu-toggle');
const headerSubmenuCloseBtns = header.querySelectorAll('.menu-item__submenu-close');
const footerSubmenuToggles = footer.querySelectorAll('.menu-item__submenu-toggle');
const footerSubmenuCloseBtns = footer.querySelectorAll('.menu-item__submenu-close');
function isSubmenuOpen() {
return (
header.querySelector('.sub-menu--open') !== null ||
footer.querySelector('.sub-menu--open') !== null
);
}
function isFooterSubmenu(buttonToggle) {
let currentElement = buttonToggle;
for (let i = 0; i < 6; i++) {
currentElement = currentElement.parentElement;
// Vérifiez si l'élément actuel est un menu-renovateur--footer
if (currentElement.classList.contains('menu-renovateur--footer')) {
return true; // Si trouvé, retournez true
}
// Arrêtez la boucle si l'élément actuel est null (pas plus de parents)
if (!currentElement) {
break;
}
}
return false;
// return buttonToggle.parentElement.parentElement.parentElement.parentElement.classList.contains(
// 'menu-renovateur--footer'
// );
}
function openSubmenu(buttonToggle) {
let isExpanded = buttonToggle.getAttribute('aria-expanded') === 'true';
const submenu = buttonToggle.parentElement.querySelector('.sub-menu');
buttonToggle.setAttribute('aria-expanded', !isExpanded);
submenu.classList.toggle('sub-menu--open');
submenu.classList.toggle('sub-menu--closed');
if (isFooterSubmenu(buttonToggle)) {
submenu.parentElement.parentElement.style.marginBottom = submenu.clientHeight + 'px';
}
}
function closeSubmenus() {
const headerOpenSubmenus = header.querySelectorAll('.sub-menu--open');
const footerOpenSubmenus = footer.querySelectorAll('.sub-menu--open');
headerOpenSubmenus.forEach((submenu) => {
submenu.classList.remove('sub-menu--open');
submenu.classList.add('sub-menu--closed');
submenu.parentElement
.querySelector('.menu-item__submenu-toggle')
.setAttribute('aria-expanded', 'false');
});
footerOpenSubmenus.forEach((submenu) => {
submenu.classList.remove('sub-menu--open');
submenu.classList.add('sub-menu--closed');
submenu.parentElement
.querySelector('.menu-item__submenu-toggle')
.setAttribute('aria-expanded', 'false');
submenu.parentElement.parentElement.style.marginBottom = '0px';
});
}
function handleSubmenuToggle(buttonToggle) {
let isExpanded = buttonToggle.getAttribute('aria-expanded') === 'true';
if (!isExpanded) {
closeSubmenus();
openSubmenu(buttonToggle);
} else {
closeSubmenus();
}
}
function closeCurrentSubmenu(buttonClose) {
const currentOpenedSubmenu = buttonClose.parentElement;
currentOpenedSubmenu.classList.remove('sub-menu--open');
currentOpenedSubmenu.classList.add('sub-menu--closed');
currentOpenedSubmenu.parentElement
.querySelector('.menu-item__submenu-toggle')
.setAttribute('aria-expanded', 'false');
if (isFooterSubmenu(buttonClose)) {
currentOpenedSubmenu.parentElement.parentElement.style.marginBottom = '0px';
}
}
// ###HEADER — SUBMENU TOGGGLES open/close
headerSubmenuToggles.forEach((button) => {
button.addEventListener('click', () => {
if (isSearchOpen() === true) {
closeSearch();
}
handleSubmenuToggle(button);
// closeSearch();
});
});
headerSubmenuCloseBtns.forEach((button) => {
button.addEventListener('click', () => closeCurrentSubmenu(button));
});
// ###FOOTER — SUBMENU TOGGGLES open/close
footerSubmenuToggles.forEach((button) => {
button.addEventListener('click', () => {
if (isSearchOpen() === true) {
closeSearch();
}
handleSubmenuToggle(button);
// closeSearch();
});
});
footerSubmenuCloseBtns.forEach((button) => {
button.addEventListener('click', () => closeCurrentSubmenu(button));
});
/* -----------------------------------------------------------
HANDLE SEARCH
-----------------------------------------------------------*/
function isSearchOpen() {
if (!searchModule) return null;
// IF CLOSED
if (
searchModule.getAttribute('mobile-closed') != null &&
searchModule.getAttribute('aria-hidden') != null &&
searchModule.getAttribute('mobile-opened') === null
) {
return false;
}
// IF OPENED
if (
searchModule.getAttribute('mobile-opened') != null &&
searchModule.getAttribute('mobile-closed') === null &&
searchModule.getAttribute('aria-hidden') === null
) {
return true;
}
// IF TRANSITIONNING OR PROBLEM
return null;
}
function openSearch(searchModuleToggle) {
const searchFieldInput = header.querySelector('.search-module__search-form__input');
searchModuleToggle.setAttribute('aria-expanded', 'true');
searchModule.setAttribute('mobile-opened', '');
searchModule.removeAttribute('mobile-closed');
searchFieldInput.focus();
setTimeout(() => {
searchModule.removeAttribute('aria-hidden');
}, 400);
}
function closeSearch(searchModuleToggle) {
searchModuleToggle.setAttribute('aria-expanded', 'false');
searchModuleToggle.focus();
searchModule.setAttribute('aria-hidden', '');
searchModule.removeAttribute('mobile-opened', '');
searchModule.setAttribute('mobile-closing', '');
searchModule.addEventListener(
'animationend',
() => {
searchModule.setAttribute('mobile-closed', '');
searchModule.removeAttribute('mobile-closing', '');
},
{ once: true }
);
// setTimeout(() => {
// searchModule.setAttribute('mobile-closed', '');
// searchModule.removeAttribute('mobile-opened', '');
// }, 50);
}
function handleSearchOpening() {
// SEARCH TOGGLE open/close
searchModuleToggles.forEach((searchModuleToggle) => {
searchModuleToggle.addEventListener('click', function (e) {
closeSubmenus();
if (isMobileNavOpened()) {
closeMenu();
}
// SEARCH IS CLOSED --> OPEN IT
if (isSearchOpen() === false) {
openSearch(searchModuleToggle);
return;
}
// SEARCH IS OPEN --> CLOSE IT
if (isSearchOpen() === true) {
closeSearch(searchModuleToggle);
}
});
});
}
handleSearchOpening();
/* -----------------------------------------------------------
HANDLE MOBILE
-----------------------------------------------------------*/
const renovateurNavListContainer = header.querySelector('.menu-renovateur__navlist-container');
const menuRenovateur = header.querySelector('.menu-renovateur');
const menuMobileBrand = header.querySelector('.menu-mobile-brand');
const HomegradeNavListContainer = header.querySelector('.menu-homegrade');
function isMobileNavOpened() {
return (
renovateurNavListContainer.hasAttribute('opened') &&
mobileMenuToggle.getAttribute('aria-expanded') === 'true'
);
}
function openMenu(menuContainer) {
// Change Toggle expanded
mobileMenuToggle.setAttribute('aria-expanded', 'true');
menuMobileBrand.setAttribute('aria-expanded', 'true');
// Change Text button
const textContent = mobileMenuToggle.querySelector('span.text-content');
textContent.textContent = mobileMenuToggle.getAttribute('data-text-close');
function openRenovateur() {
renovateurNavListContainer.removeAttribute('closed', '');
renovateurNavListContainer.setAttribute('opened', '');
renovateurNavListContainer.removeAttribute('aria-hidden', '');
renovateurNavListContainer.setAttribute('opening', '');
menuRenovateur.removeAttribute('closed', '');
menuRenovateur.setAttribute('opened', '');
menuRenovateur.removeAttribute('aria-hidden', '');
renovateurNavListContainer.addEventListener(
'animationend',
() => {
renovateurNavListContainer.removeAttribute('opening', '');
},
{ once: true }
);
}
function openMobileBrand() {
if (!menuMobileBrand) return;
menuMobileBrand.removeAttribute('closed', '');
menuMobileBrand.setAttribute('opened', '');
menuMobileBrand.removeAttribute('aria-hidden', '');
}
function openHomegrade() {
HomegradeNavListContainer.removeAttribute('closed', '');
HomegradeNavListContainer.setAttribute('opened', '');
HomegradeNavListContainer.removeAttribute('aria-hidden', '');
HomegradeNavListContainer.setAttribute('opening', '');
HomegradeNavListContainer.addEventListener(
'animationend',
() => {
HomegradeNavListContainer.removeAttribute('opening', '');
},
{ once: true }
);
}
openRenovateur();
openHomegrade();
openMobileBrand();
}
function closeMenu(menuContainer) {
// Change Toggle expanded
mobileMenuToggle.setAttribute('aria-expanded', 'false');
// Button Text Content
let textContent = mobileMenuToggle.querySelector('span.text-content');
textContent.textContent = mobileMenuToggle.getAttribute('data-text-open');
// CLOSING #RENOVATEUR
renovateurNavListContainer.removeAttribute('opened');
renovateurNavListContainer.setAttribute('aria-hidden', '');
renovateurNavListContainer.setAttribute('closing', '');
menuRenovateur.removeAttribute('opened');
menuRenovateur.setAttribute('aria-hidden', '');
menuRenovateur.setAttribute('closing', '');
renovateurNavListContainer.addEventListener(
'animationend',
() => {
renovateurNavListContainer.setAttribute('closed', '');
renovateurNavListContainer.removeAttribute('closing', '');
},
{ once: true }
);
// CLOSING #HOMEGRADE
HomegradeNavListContainer.removeAttribute('opened');
HomegradeNavListContainer.setAttribute('aria-hidden', '');
HomegradeNavListContainer.setAttribute('closing', '');
HomegradeNavListContainer.addEventListener(
'animationend',
() => {
HomegradeNavListContainer.setAttribute('closed', '');
HomegradeNavListContainer.removeAttribute('closing', '');
},
{ once: true }
);
}
mobileMenuToggle.addEventListener('click', function (e) {
// Button Text Content
if (isMobileNavOpened() === false) {
openMenu();
return;
}
if (isMobileNavOpened() === true) {
closeMenu();
}
});
/* -----------------------------------------------------------
HANDLE FOCUS CHANGE
-----------------------------------------------------------*/
function getFirstLink(menuLinks) {
return menuLinks[0].querySelector('button')
? menuLinks[0].querySelector('button')
: menuLinks[0].querySelector('a');
}
function getLastLink(menuLinks) {
return menuLinks[menuLinks.length - 1].querySelector('button')
? menuLinks[menuLinks.length - 1].querySelector('button')
: menuLinks[menuLinks.length - 1].querySelector('a');
}
// Menu Renovateur elements
const renovateurLinks = header.querySelectorAll('.menu-renovateur__navlist .menu-item');
const renovateurFirstLink = getFirstLink(renovateurLinks);
const renovateurLastLink = getLastLink(renovateurLinks);
// Menu homegrade elements
const homegradeLinks = header.querySelectorAll('.menu-homegrade__navlist .menu-item');
const homegradeFirstLink = getFirstLink(homegradeLinks);
const homegradeLastLink = getLastLink(homegradeLinks);
// Leaving the mobile menu Toggle --> Focus on Menu Homegrade
// mobileMenuToggle.addEventListener('focusout', (e) => {
// if (isMobileNavOpened()) {
// renovateurFirstLink.focus();
// }
// });
// Si shift tab pour retour --> Focuser correctement sur le mobile menu toggle
// renovateurFirstLink.addEventListener('focusout', (e) => {
// if (e.relatedTarget.id == 'website-logo-link' && isMobileNavOpened()) {
// mobileMenuToggle.focus();
// }
// });
// Leaving the Menu Rénovateur --> Focus on Menu Homegrade
// renovateurLastLink.addEventListener('focusout', (e) => {
// if (isMobileNavOpened()) {
// homegradeFirstLink.focus();
// }
// });
// Leaving the Menu Homegrade --> Focus on the toggle
// homegradeLastLink.addEventListener('focusout', (e) => {
// if (isMobileNavOpened()) {
// mobileMenuToggle.focus();
// }
// });
/* -----------------------------------------------------------
HANDLE ESCAPE KEY
-----------------------------------------------------------*/
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
if (isMobileNavOpened()) {
closeMenu(renovateurNavListContainer);
closeMenu(HomegradeNavListContainer);
}
if (isSearchOpen() === true) {
closeSearch();
}
if (isSubmenuOpen()) {
closeSubmenus();
}
}
});
}