/** * Submenús anidados para el navbar de Bootstrap 5.3.x. * El primer nivel lo gestiona Bootstrap (data-bs-toggle="dropdown"); * este script gestiona los niveles 2 y 3 (.dropdown-submenu). * Funciona como comportamiento de Drupal y también en HTML estático. */ (function () { 'use strict'; function closeSubmenu(item) { var menu = item.querySelector(':scope > .dropdown-menu'); var toggle = item.querySelector(':scope > .dropdown-toggle'); item.querySelectorAll('.dropdown-submenu').forEach(function (child) { var childMenu = child.querySelector(':scope > .dropdown-menu'); var childToggle = child.querySelector(':scope > .dropdown-toggle'); childMenu.classList.remove('show', 'flip-left'); childToggle.setAttribute('aria-expanded', 'false'); }); menu.classList.remove('show', 'flip-left'); toggle.setAttribute('aria-expanded', 'false'); } function openSubmenu(item) { // Cierra los submenús hermanos abiertos Array.prototype.forEach.call(item.parentElement.children, function (sibling) { if (sibling !== item && sibling.classList.contains('dropdown-submenu')) { closeSubmenu(sibling); } }); var menu = item.querySelector(':scope > .dropdown-menu'); var toggle = item.querySelector(':scope > .dropdown-toggle'); menu.classList.remove('flip-left'); menu.classList.add('show'); toggle.setAttribute('aria-expanded', 'true'); // Si se sale de la ventana por la derecha, ábrelo hacia la izquierda if (menu.getBoundingClientRect().right > document.documentElement.clientWidth) { menu.classList.add('flip-left'); } } function init(nav) { nav.querySelectorAll('.dropdown-submenu > .dropdown-toggle').forEach(function (toggle) { if (toggle.dataset.submenuInit) { return; } // evita doble registro si .navbar y .offcanvas se anidan toggle.dataset.submenuInit = '1'; var item = toggle.parentElement; toggle.addEventListener('click', function (event) { event.preventDefault(); // Evita que Bootstrap cierre el menú de primer nivel event.stopPropagation(); var menu = item.querySelector(':scope > .dropdown-menu'); if (menu.classList.contains('show')) { closeSubmenu(item); } else { openSubmenu(item); } }); // Barra espaciadora activa el enlace (role="button") toggle.addEventListener('keydown', function (event) { if (event.key === ' ') { event.preventDefault(); toggle.click(); } }); }); // Al cerrarse un menú de primer nivel, se cierran sus submenús nav.addEventListener('hidden.bs.dropdown', function (event) { var parent = event.target.closest('.nav-item.dropdown'); if (parent) { parent.querySelectorAll('.dropdown-submenu').forEach(closeSubmenu); } }); } if (window.Drupal && window.once) { Drupal.behaviors.navbarMenu = { attach: function (context) { once('navbar-menu', '.navbar, .offcanvas', context).forEach(init); } }; } else { document.addEventListener('DOMContentLoaded', function () { document.querySelectorAll('.navbar, .offcanvas').forEach(init); }); } })();