<header class="n7-header md-max-w-480-min-h:pt-[--header-offset] lg-min-w-480-min-h:pt-[--topbar-offset] shadow-md" id="siteHeader" aria-label="Header del sito">

    <!-- Top bar -->
    <div class="n7-top-bar flex items-center n7-background-02 py-1 md:py-2 px-4 hidden lg:flex">
        <div class="n7-top-bar__container n7-container mx-auto flex items-center lg:flex-1">

            <div class="n7-top-bar__navigation grid lg:flex items-center gap-2 lg:gap-8">

                <!-- Secondary nav/menu component -->
                <nav aria-label="Secondaria">
                    <ul class="n7-secondary-navigation grid lg:flex gap-4">

                        <li class="">
                            <a href="" class="n7-link p-2 text-xs lg:text-sm n7-content-01">
                                voce 1

                            </a>
                        </li>

                        <li class="">
                            <a href="" class="n7-link p-2 text-xs lg:text-sm n7-content-01">
                                voce 2

                            </a>
                        </li>

                    </ul>
                </nav>

            </div>

            <div class="n7-top-bar__utilities-area flex ml-auto">

                <!-- Social links component -->

                <div class="n7-social-links grid gap-1 md:flex md:gap-6">

                    <ul id="headerSocial" class="flex items-center gap-4 p-2 lg:p-0">

                        <li class="flex items-center">
                            <a href="" class="n7-link
     text-2xl n7-content-01 p-2 xl:p-1 n7-link--lg
">
                                <span class="sr-only">Vai al profilo Facebook di ???</span>

                                <svg class="n7-icon inline-block align-middle fill-current w-8 h-8 lg:w-6 lg:h-6" aria-hidden="true" focusable="false" role="img">
                                    <use href="../../icons.svg#solid--facebook" />
                                </svg>

                            </a>
                        </li>

                        <li class="flex items-center">
                            <a href="" class="n7-link
     text-2xl n7-content-01 p-2 xl:p-1 n7-link--lg
">
                                <span class="sr-only">Vai al profilo Instagram di ???</span>

                                <svg class="n7-icon inline-block align-middle fill-current w-8 h-8 lg:w-6 lg:h-6" aria-hidden="true" focusable="false" role="img">
                                    <use href="../../icons.svg#solid--instagram" />
                                </svg>

                            </a>
                        </li>

                        <li class="flex items-center">
                            <a href="" class="n7-link
     text-2xl n7-content-01 p-2 xl:p-1 n7-link--lg
">
                                <span class="sr-only">Vai al canale YouTube di ???</span>

                                <svg class="n7-icon inline-block align-middle fill-current w-8 h-8 lg:w-6 lg:h-6" aria-hidden="true" focusable="false" role="img">
                                    <use href="../../icons.svg#solid--youtube" />
                                </svg>

                            </a>
                        </li>

                    </ul>

                </div>

                <div class="w-1e flex mx-6 hidden lg:block">
                    <img class="w-full h-auto" src="/images/vertical-divider.svg" alt="">
                </div>

                <!-- Language Selctor component -->
                <div class="px-4">Lingua</div>

                <!-- Search component -->
                <div class="hidden lg:block">
                    <button type="button" id="searchModalTrigger" class="n7-btn n7-btn--secondary n7-btn--icon rounded-full w-6 h-6 md:w-10 md:h-10">
                        <span class="sr-only">Cerca nel sito - apri la modale</span>
                        <svg class="n7-icon inline-block align-middle fill-current w-4 h-4 md:w-5 md:h-5" aria-hidden="true" focusable="false" role="img">
                            <use href="../../icons.svg#mini--magnifying-glass" />
                        </svg>

                    </button>

                    <!-- Search Modal -->
                    <div id="searchModal" class="fixed items-center content-center inset-0 bg-black bg-opacity-50 overflow-y-auto h-full w-full" style="display:none;" aria-hidden="true" role="dialog" aria-modal="true" aria-labelledby="modalTitle">

                        <div class="relative h-full lg:h-full lg:w-full mx-auto p-6 lg:p-16 shadow-lg bg-white">
                            <div class="container n7-modal-content px-16 grid gap-14">
                                <div class="flex justify-between items-center">
                                    <h2 id="modalTitle" class="text-3xl md:text-5xl lg:text-6xl">Cerca nel sito</h2>
                                    <button id="closeModal" class="n7-btn n7-btn--icon border-0 hover:n7-background-primary hover:text-white">
                                        <span class="sr-only">Chiudi</span>
                                        <svg class="n7-icon inline-block align-middle fill-current w-8 h-8" aria-hidden="true" focusable="false" role="img">
                                            <use href="../../icons.svg#mini--x-mark" />
                                        </svg>

                                    </button>
                                </div>

                                <form role="search" class="flex gap-2">
                                    <div class="n7-input-field gap-1 flex-1 ">
                                        <label for="inputSearch" class="n7-input-field__label">
                                            Cerca servizi, informazioni, aiuti...

                                        </label>

                                        <div class="n7-input has-icon">

                                            <svg class="n7-icon inline-block align-middle fill-current n7-input__icon" aria-hidden="true" focusable="false" role="img">
                                                <use href="../../icons.svg#mini--magnifying-glass" />
                                            </svg>

                                            <input id="inputSearch" class="text-sm n7-input-placeholder" type="search" placeholder="Cerca">
                                        </div>

                                    </div>
                                    <button type="button" class="n7-btn 
    n7-btn--icon-right group/button n7-btn--primary self-end">

                                        Cerca nel sito

                                        <svg class="n7-icon inline-block align-middle fill-current w-4 h-4 md:w-5 md:h-5 transition-all duration-200 ease-out transform group-hover/button:translate-x-1" aria-hidden="true" focusable="false" role="img">
                                            <use href="../../icons.svg#mini--chevron-right" />
                                        </svg>

                                    </button>

                                </form>

                            </div><!-- /END MODAL CONTENT -->
                        </div>

                    </div>
                </div><!--/ END SEARCH WRAPPER -->

            </div>
            <!--/ END TOP BAR UTILITIES -->

        </div>
    </div><!-- /END TOPBAR -->

    <!-- Main heading -->
    <div class="n7-main-heading bg-white flex items-center px-4 py-3 lg:p-4 border-b n7-border-primary lg:border-b-0 md-max-w-480-min-h:fixed md-max-w-480-min-h:top-[--header-top-position] md-max-w-480-min-h:right-0 md-max-w-480-min-h:left-0 md-max-w-480-min-h:z-30">
        <div class="n7-main-heading__container n7-container mx-auto flex items-center flex-1">

            <div class="n7-site-branding n7-branding flex items-center site-branding lg:max-w-[35.7%]">
                <a class="n7-site-logo site-logo flex n7-logo--main auto" href="#">
                    <img class="w-full h-full object-cover md:object-contain object-left-top" src="/images/logo.png" alt="Alt logo image" width="248" height="81" />
                </a>

                <div class="n7-w-4 n7-h-10 md:n7-w-10 md:n7-h-20">
                    <img class="w-full h-auto" src="/images/vertical-divider.svg" alt="">
                </div>

                <a class="n7-site-logo site-logo flex n7-logo--secondary w-auto" href="#">
                    <img class="w-full h-full object-contain object-left-top" src="/images/logo.png" alt="Alt logo image" width="248" height="81" />
                </a>

            </div>

            <div class="n7-main-headings__center flex-1 lg:ml-auto lg:justify-end">
                <nav class="n7-primary-navigation flex lg:justify-end" aria-label="Principale" id="siteNavWrapper">
                    <button type="button" class="n7-btn n7-btn--only-text rounded-0 lg:hidden ml-auto n7-btn--icon group" aria-expanded="false" aria-controls="mainNavPanel" id="mobileNavToggle">
                        <svg class="n7-icon inline-block align-middle fill-current w-4 h-4 md:w-5 md:h-5 lg:w-6 lg:h-6 m-0 p-0 transition-all duration-200 ease-out transform group-hover:translate-none is-show-menu group-aria-expanded:hidden" aria-hidden="true" focusable="false" role="img">
                            <use href="../../icons.svg#mini--bars-3" />
                        </svg>

                        <svg class="n7-icon inline-block align-middle fill-current w-4 h-4 md:w-5 md:h-5 lg:w-6 lg:h-6 m-0 p-0 transition-all duration-200 ease-out transform group-hover:translate-none is-close-menu hidden group-aria-expanded:inline-block" aria-hidden="true" focusable="false" role="img">
                            <use href="../../icons.svg#mini--x-mark" />
                        </svg>

                        <span class="sr-only is-show-menu">
                            Menu
                        </span>
                    </button>

                    <!-- Mobile panel -->
                    <div class="n7-primary-navigation__panel flex-col bg-white transition-all invisible w-[88%] lg:w-auto fixed lg:static lg:visible top-[--header-height] bottom-0 left-[12%] lg:left-0 border-l n7-border-primary lg:border-l-0 overflow-y-auto lg:overflow-visible" id="mainNavPanel">
                        <!-- Main nav -->
                        <div class="n7-primary-navigation__module is-main lg:border-b-0">
                            <ul class="n7-primary-navigation__list grid lg:flex lg:justify-end  gap-4 xl:gap-8">

                                <li>
                                    <a href="#" class="n7-primary-navigation__link group w-full flex items-center p-3 gap-2 font-medium hover:underline focus:n7-content-primary text-sm lg:text-base">
                                        Item
                                    </a>
                                </li>

                                <li class="n7-dropdown-menu has-dropdown-menu n7-primary-navigation__item">
                                    <button class="n7-dropdown-menu__trigger n7-dropdown-trigger group w-full flex items-center  font-medium hover:underline focus:n7-content-primary  aria-expanded:n7-background-02 lg:aria-expanded:bg-white aria-expanded:n7-content-01 p-3 gap-2 text-sm lg:text-base" aria-expanded="false" aria-controls="dropdown-2">

                                        Dropdown normale<svg class="n7-icon inline-block align-middle fill-current w-5 h-5 ml-auto transition-all n7-dropdown-menu__trigger-icon group-aria-expanded:-rotate-180" aria-hidden="true" focusable="false" role="img">
                                            <use href="../../icons.svg#mini--chevron-down" />
                                        </svg>
                                    </button>
                                    <ul class="n7-dropdown-menu__list hidden border border-t-0 n7-border-gray-01 lg:w-52  lg:border-t lg:absolute lg:rounded lg:shadow-md border-r-0 border-l-0 lg:border-r lg:border-l" id="dropdown-2">

                                        <li class="n7-dropdown-menu__item group border-b n7-border-gray-01 last-of-type:border-b-0">
                                            <a class="block p-3 transition bg-white text-sm xl:text-base hover:underline hover:n7-background-02 focus:n7-background-02 group-first:rounded-t group-last:rounded-b" href="">
                                                <div class="flex gap-2 items-center">

                                                    <span class="grow">Item 1</span>

                                                </div>

                                            </a>
                                        </li>

                                        <li class="n7-dropdown-menu__item group border-b n7-border-gray-01 last-of-type:border-b-0">
                                            <a class="block p-3 transition bg-white text-sm xl:text-base hover:underline hover:n7-background-02 focus:n7-background-02 group-first:rounded-t group-last:rounded-b" href="">
                                                <div class="flex gap-2 items-center">

                                                    <span class="grow">Item 2</span>

                                                </div>

                                            </a>
                                        </li>

                                        <li class="n7-dropdown-menu__item group border-b n7-border-gray-01 last-of-type:border-b-0">
                                            <a class="block p-3 transition bg-white text-sm xl:text-base hover:underline hover:n7-background-02 focus:n7-background-02 group-first:rounded-t group-last:rounded-b" href="">
                                                <div class="flex gap-2 items-center">

                                                    <span class="grow">Item 3</span>

                                                </div>

                                            </a>
                                        </li>

                                        <li class="n7-dropdown-menu__item group border-b n7-border-gray-01 last-of-type:border-b-0">
                                            <a class="block p-3 transition bg-white text-sm xl:text-base hover:underline hover:n7-background-02 focus:n7-background-02 group-first:rounded-t group-last:rounded-b" href="">
                                                <div class="flex gap-2 items-center">

                                                    <span class="grow">Item 4</span>

                                                </div>

                                            </a>
                                        </li>

                                    </ul>
                                </li>

                                <li class="n7-dropdown-menu has-dropdown-menu has-dropdown-menu relative n7-primary-navigation__item">

                                    <button class="n7-dropdown-menu__trigger n7-dropdown-trigger group w-full flex items-center font-medium hover:underline focus:n7-content-primary  aria-expanded:n7-background-02 lg:aria-expanded:bg-white aria-expanded:n7-content-01 p-3 gap-2 text-sm lg:text-base text-gray-700" aria-expanded="false" aria-controls="megamenu-3">

                                        Megamenu<svg class="n7-icon inline-block align-middle fill-current w-5 h-5 ml-auto transition-all n7-dropdown-menu__trigger-icon" aria-hidden="true" focusable="false" role="img">
                                            <use href="../../icons.svg#mini--chevron-down" />
                                        </svg>
                                    </button>

                                    <!-- MEGAMENU CONTENT -->
                                    <div class="n7-dropdown-menu__list hidden border n7-border-gray-01 bg-white lg:shadow-lg
                lg:absolute top-full left-0 right-0 z-50 
                min-w-full w-auto
                lg:min-w-[800px] lg:max-w-[1000px] lg:w-auto lg:right-auto
                 border-r-0 border-l-0 lg:border-r lg:border-l" id="megamenu-3">

                                        <div class="overflow-hidden rounded-lg">
                                            <div class="flex flex-col lg:flex-row">

                                                <!-- Left Panel -->

                                                <div class="w-full lg:w-1/3 bg-gray-50 p-4 lg:p-6 border-b n7-border-gray-01 lg:border-b-0 lg:border-r lg:border-r-gray-200">
                                                    <div class="relative lg:border-l-4 lg:border-blue-500 lg:pl-5">

                                                        <p class="font-semibold text-gray-900">Titolo pannello</p>

                                                        <p class="mt-2 text-sm text-gray-600">Descrizione del pannello sinistro</p>

                                                    </div>
                                                </div>

                                                <!-- Right Panel with menu items -->
                                                <div class="w-full lg:w-2/3 p-4 lg:p-6">
                                                    <ul class="n7-megamenu-list flex flex-col lg:grid lg:grid-cols-1 lg:md:grid-cols-2 list-none m-0 p-0">

                                                        <li class="n7-megamenu-item border-b n7-border-gray-01 last-of-type:border-b-0 lg:border-b-0 lg:rounded-md">

                                                            <!-- Item con sottomenu -->
                                                            <div class="n7-megamenu-dropdown group w-full lg:bg-gray-50 lg:rounded-md">
                                                                <button type="button" class="n7-megamenu-trigger w-full flex items-center p-3 text-sm font-medium text-gray-900 lg:rounded-md text-left transition-colors duration-200 hover:underline focus:n7-background-02" aria-expanded="false" data-dropdown-trigger>
                                                                    <svg class="mr-3 h-5 w-5 transition-transform duration-200" viewBox="0 0 24 24" fill="currentColor" data-dropdown-icon>
                                                                        <path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"></path>
                                                                    </svg>
                                                                    <span>Categoria 1</span>
                                                                </button>
                                                                <!-- Sottomenu -->
                                                                <ul class="n7-megamenu-submenu hidden overflow-hidden bg-gray-50 lg:bg-transparent lg:px-3 lg:py-3 list-none m-0 p-0 transition-all duration-200" data-dropdown-content>

                                                                    <li class="n7-megamenu-subitem border-b n7-border-gray-01 last:border-b-0 lg:border-b-0 lg:py-1">
                                                                        <a href="/categoria-1/sotto-1" class="n7-megamenu-sublink block text-sm lg:text-xs text-gray-600 p-3 lg:p-0 lg:pl-8 lg:pb-2.5 lg:py-1 transition-colors duration-200 hover:underline hover:n7-background-02 focus:n7-background-02">
                                                                            Sottoelemento 1
                                                                        </a>
                                                                    </li>

                                                                </ul>
                                                            </div>

                                                        </li>

                                                        <li class="n7-megamenu-item border-b n7-border-gray-01 last-of-type:border-b-0 lg:border-b-0 lg:rounded-md">

                                                            <!-- Item semplice -->
                                                            <div class="n7-megamenu-dropdown lg:bg-gray-50 lg:rounded-md">
                                                                <a href="/categoria-2" class="n7-megamenu-link group flex items-center p-3 text-sm font-medium text-gray-900 w-full transition-colors duration-200 lg:rounded-md hover:underline hover:n7-background-02 focus:n7-background-02">
                                                                    <svg class="mr-3 h-5 w-5" viewBox="0 0 24 24" fill="currentColor">
                                                                        <path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"></path>
                                                                    </svg>
                                                                    Categoria 2
                                                                </a>
                                                            </div>

                                                        </li>

                                                    </ul>
                                                </div>

                                            </div>
                                        </div>
                                    </div>

                                </li>

                            </ul>
                        </div>

                        <!-- Mobile search in panel -->
                        <div class="n7-primary-navigation__module is-main lg:hidden is-last-element">
                            <form role="search" class="flex items-end p-3">
                                <div class="n7-input-field gap-1 flex-1 ">
                                    <label for="inputSearchMobile" class="n7-input-field__label">
                                        Cerca servizi, informazioni, aiuti...

                                    </label>

                                    <div class="n7-input has-icon">

                                        <svg class="n7-icon inline-block align-middle fill-current n7-input__icon" aria-hidden="true" focusable="false" role="img">
                                            <use href="../../icons.svg#mini--magnifying-glass" />
                                        </svg>

                                        <input id="inputSearchMobile" class="rounded-l-lg rounded-r-none text-sm n7-input-placeholder" type="search" placeholder="Cerca">
                                    </div>

                                </div>
                                <button type="button" class="n7-btn n7-btn--secondary n7-btn--icon w-12 h-12">
                                    <span class="sr-only">Cerca</span>
                                    <svg class="n7-icon inline-block align-middle fill-current w-5 h-5" aria-hidden="true" focusable="false" role="img">
                                        <use href="../../icons.svg#mini--magnifying-glass" />
                                    </svg>

                                </button>
                            </form>
                        </div>

                    </div>

                    <div class="n7-primary-navigation__backdrop bg-black/25 top-[--header-height] lg:hidden"></div>
                </nav>
            </div>

        </div>
    </div>

    <div class="lg:flex lg:n7-background-02 lg:py-2 is-second-last">

        <nav class="lg:n7-container lg:flex lg:justify-center" aria-label="Label navigazione bottom">
            <ul class="grid lg:flex gap-4">

                <li class="">
                    <a href="" class="n7-link p-2 n7-content-01 font-medium text-sm lg:text-base">
                        Item 1

                    </a>
                </li>

                <li class="">
                    <a href="" class="n7-link p-2 n7-content-01 font-medium text-sm lg:text-base">
                        Item 2

                    </a>
                </li>

                <li class="">
                    <a href="" class="n7-link p-2 n7-content-01 font-medium text-sm lg:text-base">
                        Item 3

                    </a>
                </li>

            </ul>
        </nav>

    </div>

</header>
<header class="n7-header md-max-w-480-min-h:pt-[--header-offset] lg-min-w-480-min-h:pt-[--topbar-offset]{% if hasShadow %} shadow-md{% endif %}{% block classes %}{% if classes %} {{ classes }}{% endif %}{% endblock classes %}" id="siteHeader" aria-label="Header del sito">
    {% block topBar %}
    <!-- Top bar -->
    {% render '@top-bar', {hasSecondaryNav: 'true', hasSearchButton: 'true', hasTopBarSocial: 'true', mobileHidden: 'true'}, true %}
    {% endblock topBar %}

    {% block mainHeading %}
    <!-- Main heading -->
    {% render '@main-heading--megamenu',{logoDivider: 'true',secondLogo: 'true'}, true %}
    {% endblock mainHeading %}

    {% block bottomBar %}
        {% if hasBottomBar %}
            {% render '@bottom-bar' %}
        {% endif %}
    {% endblock bottomBar %}
</header>
{
  "hasShadow": true,
  "hasBottomBar": true
}
  • Content:
    document.addEventListener('DOMContentLoaded', function () {
        'use strict';
        if (document.querySelector('.n7-header')) {
            /* GLOBAL VARIABLES */
            var rootElement = document.documentElement;
            var siteHeader = document.querySelector('.n7-header');
            var mainHeading = document.querySelector('.n7-main-heading');
            var headerSocialLinks = document.querySelector('.n7-social-links');
            var headerHeight;
     
            var mainMenuWrapper = document.getElementById('mainNavPanel');
            var mobileNavToggle = document.getElementById('mobileNavToggle');
            var mobileMenuClose = document.getElementById('mobileMenuClose');
            var SiteMenuWrapper = document.getElementById('siteNavWrapper');
            const mobileMenuOverlay = document.getElementById('mobileMenuOverlay');
     
            / FUNCTIONS /
            function calculateSiteHeader(header) {
                headerHeight = header.offsetHeight;
                rootElement.style.setProperty('--header-height', headerHeight + 'px');
            }
     
            function toggleMobileMenu() {
                var isExpanded = mobileNavToggle.getAttribute('aria-expanded') === 'true';
                mobileNavToggle.setAttribute('aria-expanded', !isExpanded);
                mainMenuWrapper.classList.toggle('translate-x-0');
                document.body.classList.toggle('overflow-hidden');
                // Aggiungi toggle dell'overlay
                mobileMenuOverlay.classList.toggle('hidden');
     
                mobileNavToggle.querySelector('.is-show-menu').classList.toggle('hidden');
                mobileNavToggle.querySelector('.is-close-menu').classList.toggle('hidden');
            }
     
            function closeMobileMenu() {
                mobileNavToggle.setAttribute('aria-expanded', 'false');
                mainMenuWrapper.classList.remove('translate-x-0');
                document.body.classList.remove('overflow-hidden');
                // Nascondi l'overlay
                mobileMenuOverlay.classList.add('hidden');
    
                mobileNavToggle.querySelector('.is-show-menu').classList.remove('hidden');
                mobileNavToggle.querySelector('.is-close-menu').classList.add('hidden');
            }
     
            let resizeTimeout;
            function handleResize() {
                if (resizeTimeout) {
                    clearTimeout(resizeTimeout);
                }
     
                document.body.classList.add('resizing');
     
                resizeTimeout = setTimeout(() => {
                    if (window.innerWidth >= 1280) {
                        closeMobileMenu();
                    }
                    calculateSiteHeader(mainHeading);
                    document.body.classList.remove('resizing');
                }, 250);
            }
     
            / EVENT LISTENERS /
            mobileNavToggle.addEventListener('click', toggleMobileMenu);
            if (mobileMenuClose) {
                mobileMenuClose.addEventListener('click', closeMobileMenu);
            }
     
            // Aggiungi event listener per chiudere il menu cliccando sull'overlay
            if (mobileMenuOverlay) {
                mobileMenuOverlay.addEventListener('click', closeMobileMenu);
            }
     
            document.addEventListener('keyup', function(e) {
                if (e.key === "Escape" && mobileNavToggle.getAttribute('aria-expanded') === 'true') {
                    closeMobileMenu();
                }
            });
     
            window.addEventListener('resize', handleResize);
     
            // Initialize on page load
            handleResize();
            calculateSiteHeader(mainHeading);
     
            / SEARCH FUNCTIONALITY */
            const searchModalTrigger = document.getElementById('searchModalTrigger');
            const searchModal = document.getElementById('searchModal');
            const closeModal = document.getElementById('closeModal');
            const searchForm = document.getElementById('searchform');
            const mobileSearchForm = document.getElementById('mobileSearchForm');
     
            function openSearchModal() {
                searchModal.style.display = 'flex';
                searchModal.setAttribute('aria-hidden', 'false');
                document.body.classList.add('overflow-hidden');
            }
     
            function closeSearchModal() {
                searchModal.style.display = 'none';
                searchModal.setAttribute('aria-hidden', 'true');
                document.body.classList.remove('overflow-hidden');
            }
     
            if (searchModalTrigger) {
                searchModalTrigger.addEventListener('click', openSearchModal);
            }
     
            if (closeModal) {
                closeModal.addEventListener('click', closeSearchModal);
            }
     
            if (searchForm) {
                searchForm.addEventListener('submit', function(e) {
                    console.log('Desktop search submitted:', new FormData(this).get('s'));
                });
            }
     
            if (mobileSearchForm) {
                mobileSearchForm.addEventListener('submit', function(e) {
                    console.log('Mobile search submitted:', new FormData(this).get('s'));
                });
            }
     
            searchModal.addEventListener('click', function(e) {
                if (e.target === searchModal) {
                    closeSearchModal();
                }
            });
     
            document.addEventListener('keydown', function(e) {
                if (e.key === 'Escape' && searchModal.style.display === 'flex') {
                    closeSearchModal();
                }
            });
        }
    });
  • URL: /components/raw/header/-test-header-.js
  • Filesystem Path: components/04-organisms/header/-test-header-.js
  • Size: 5.3 KB
  • Content:
    /* HEADER SCRIPT - mobile management */
    document.addEventListener('DOMContentLoaded', function () {
        'use strict';
        if (document.querySelector('.n7-header')) {
            /* GLOBAL VARIABLES */
            var rootElement = document.documentElement;
            var siteHeader = document.querySelector('.n7-header');
            var mainHeading = document.querySelector('.n7-main-heading');
            // var breadcrumb = document.querySelector('.n7-breadcrumb');
            var headerHeight;
            // var breadcrumbHeight;
    
            var mainMenuWrapper = document.getElementById('mainNavPanel');
            var headerLinkRight = document.querySelector('.n7-header-link-right');
            var headerSocialLinks = document.querySelector('.n7-social-links');
            var headerSecondaryNav = document.querySelector('.n7-top-bar__navigation');
            var mobilePanelLastEl = document.querySelector('.is-last-element');
            var headerMainActions = document.querySelector('.n7-main-heading__actions');
    
            var SiteMenuWrapper = document.getElementById('siteNavWrapper');
    
            var mobilePanelSecondLastEl = document.querySelector('.is-second-last');
    
            /* FUNCTIONS */
    
            function toggleIcon(icon) {
                if (icon.classList.contains('is-hidden')) {
                    icon.classList.remove('is-hidden');
                    icon.classList.add('is-visible');
                } else if (icon.classList.contains('is-visible')) {
                    icon.classList.remove('is-visible');
                    icon.classList.add('is-hidden');
                }
            }
    
            function calculateSiteHeader(header) {
                headerHeight = header.offsetHeight;
                rootElement.style.setProperty('--header-offset', headerHeight + 'px');
            }
    
            // function calculateBreadcrumbHeader(breadcrumb) {
            //     breadcrumbHeight = breadcrumb.offsetHeight;
            //     rootElement.style.setProperty('--breadcrumb-height', breadcrumbHeight + 'px');
            // }
    
            function ariaExpandedToggle(target) {
                if (target.getAttribute('aria-expanded') === "false") {
                    target.setAttribute('aria-expanded', 'true');
                } else {
                    target.setAttribute('aria-expanded', 'false');
                }
            }
    
            function openOffCanvasMenu(button, targetMenu) {
                button.classList.toggle('is-selected');
                ariaExpandedToggle(button);
                targetMenu.classList.toggle('is-open');
                document.documentElement.classList.toggle('overflow-hidden');
            }
    
            function closeMobileMenu() {
                if (document.documentElement.classList.contains('overflow-hidden')) {
                    document.documentElement.classList.remove('overflow-hidden');
                }
    
                mainMenuWrapper.classList.remove('is-open');
                document.getElementById('mobileNavToggle').setAttribute('aria-expanded', 'false');
                document.getElementById('mobileNavToggle').classList.remove('is-selected');
            }
    
    
            function wrapAndAppend(wrapperClass, elementToWrap, parentElement) {
                // Controlla se l'elemento da avvolgere è già contenuto in un wrapperDiv con la stessa classe
                var existingWrapper = elementToWrap.closest('.' + wrapperClass);
    
                // Se l'elemento è già avvolto, utilizza il wrapper esistente anziché crearne uno nuovo
                if (existingWrapper) {
                    existingWrapper.appendChild(elementToWrap);
                } else {
                    // Altrimenti, crea un nuovo wrapperDiv
                    var wrapperDiv = document.createElement('div');
                    wrapperDiv.classList.add(wrapperClass);
                    wrapperDiv.appendChild(elementToWrap);
    
                    // Prependi il wrapperDiv al parentElement
                    parentElement.appendChild(wrapperDiv);
                    if (mobilePanelLastEl) {
                        parentElement.insertBefore(wrapperDiv, mobilePanelLastEl);
                    } else {
                        parentElement.appendChild(wrapperDiv);
                    }
    
                }
            }
    
            function unwrapAndRemove(wrapperDiv, elementToUnwrap, parentElement) {
                if (elementToUnwrap && elementToUnwrap.parentNode === parentElement) {
                    parentElement.removeChild(elementToUnwrap);
                }
    
                if (wrapperDiv && wrapperDiv.parentNode === parentElement) {
                    parentElement.removeChild(wrapperDiv);
                }
            }
    
            function handleResize() {
                if (window.matchMedia("screen and (max-width: 1023px)").matches) {
            
                    var topBar = document.querySelector('.n7-top-bar');
                    var bottomBar = document.querySelector('.n7-bottom-bar');
            
                    /* FOR HEADER WITH NAVIGATION IN TOP BAR */
                    if (topBar && topBar.contains(SiteMenuWrapper)) {
                        document.querySelector('.n7-main-heading__container').append(SiteMenuWrapper);
                    }
            
                    /* FOR HEADER WITH NAVIGATION IN BOTTOM BAR */
                    if (bottomBar && bottomBar.contains(SiteMenuWrapper)) {
                        document.querySelector('.n7-main-heading__container').append(SiteMenuWrapper);
                    }
            
                    // Verifica altri elementi e le azioni che devono essere fatte su di essi
                    if (headerLinkRight) {
                        wrapAndAppend('n7-primary-navigation__module', headerLinkRight, mainMenuWrapper);
                    }
            
                    if (headerSecondaryNav) {
                        wrapAndAppend('n7-primary-navigation__module', headerSecondaryNav, mainMenuWrapper);
                    }
            
                    if (headerMainActions) {
                        wrapAndAppend('n7-primary-navigation__module', headerMainActions, mainMenuWrapper);
                    }
            
                    if (mobilePanelSecondLastEl) {
                        wrapAndAppend('n7-primary-navigation__module', mobilePanelSecondLastEl, mainMenuWrapper);
                    }
            
                    if (headerSocialLinks) {
                        wrapAndAppend('n7-primary-navigation__module', headerSocialLinks, mainMenuWrapper);
                    }
            
                    calculateSiteHeader(mainHeading);
            
                } else if (window.matchMedia("screen and (min-width: 1024px)").matches) {
                    // Se la viewport è maggiore o uguale a 1024px
                    var emptyNavModules = document.querySelectorAll('.n7-primary-navigation__module:not(.is-main):empty');
            
                    emptyNavModules.forEach(function (emptyNavModule) {
                        if (SiteMenuWrapper.classList.contains('is-top-nav-positioned')) {
                            var topBarContainer = document.querySelector('.n7-top-bar__container');
                            if (topBarContainer) {
                                topBarContainer.prepend(SiteMenuWrapper);
                            }
                        }
            
                        if (SiteMenuWrapper.classList.contains('is-bottom-nav-positioned')) {
                            var bottomBarContainer = document.querySelector('.n7-bottom-bar__container');
                            if (bottomBarContainer) {
                                bottomBarContainer.prepend(SiteMenuWrapper);
                            }
                        }
            
                        if (headerSecondaryNav) {
                            unwrapAndRemove(emptyNavModule, headerSecondaryNav, mainMenuWrapper);
                        }
            
                        if (headerMainActions) {
                            unwrapAndRemove(emptyNavModule, headerMainActions, mainMenuWrapper);
                        }
            
                        if (mobilePanelSecondLastEl) {
                            unwrapAndRemove(emptyNavModule, mobilePanelSecondLastEl, mainMenuWrapper);
                        }
            
                        if (headerSocialLinks) {
                            unwrapAndRemove(emptyNavModule, headerSocialLinks, mainMenuWrapper);
                        }
            
                        if (headerLinkRight) {
                            unwrapAndRemove(emptyNavModule, headerLinkRight, mainMenuWrapper);
                        }
                    });
            
                    // Riporto headerSocialLinks nel suo posto originale
                    if (headerSecondaryNav) {
                        var topBarContainer = document.querySelector('.n7-top-bar__container');
                        if (topBarContainer) {
                            topBarContainer.prepend(headerSecondaryNav);
                        }
                    }
            
                    if (headerSocialLinks) {
                        var utilitiesArea = document.querySelector('.n7-top-bar__utilities-area');
                        if (utilitiesArea) {
                            utilitiesArea.prepend(headerSocialLinks);
                        }
                    }
            
                    if (headerLinkRight) {
                        var utilitiesArea = document.querySelector('.n7-top-bar__utilities-area');
                        if (utilitiesArea) {
                            utilitiesArea.prepend(headerLinkRight);
                        }
                    }
            
                    if (headerMainActions) {
                        document.querySelector('.n7-main-heading__container').append(headerMainActions);
                    }
            
                    if (mobilePanelSecondLastEl) {
                        document.querySelector('#siteHeader').append(mobilePanelSecondLastEl);
                    }
            
                    calculateSiteHeader(siteHeader);
                }
            }
            
            window.addEventListener('resize', handleResize);
            handleResize(); // Initialize on page load
    
            document.getElementById('mobileNavToggle').addEventListener('click', function (e) {
                e.preventDefault();
                openOffCanvasMenu(this, mainMenuWrapper);
                // console.log('clicked');
            });
    
            document.addEventListener('keyup', function (e) {
                // if (e.key === "Escape") {
                //     if (mainMenuWrapper.classList.contains('is-open')) {
                //         closeMobileMenu();
                //         if (window.getComputedStyle(document.getElementById('mobileNavToggle')).display !== 'none') {
                //             document.getElementById('mobileNavToggle').focus();
                //         }
    
                //         if (document.getElementById('mainMenuToggle')) {
                //             document.getElementById('mainMenuToggle').focus();
                //         }
                //     }
                // }
    
                if (e.key === "Escape") {
                    if (mainMenuWrapper.classList.contains('is-open')) {
                        // Verifica se il focus è all'interno del menu principale
                        const isFocusInsideMainMenu = SiteMenuWrapper.contains(document.activeElement) &&
                            !document.activeElement.closest('.n7-dropdown-menu__item');
    
                        if (isFocusInsideMainMenu) {
                            closeMobileMenu();
    
                            // Se disponibile, ripristina il focus sull'elemento principale di apertura menu
                            if (document.getElementById('mobileNavToggle')) {
                                document.getElementById('mobileNavToggle').focus();
                            }
                        }
                    }
                }
    
                // if ((e.key === 'Tab' || e.keyCode === 9) && !mainMenuWrapper.contains(e.target)) {
                //     closeMobileMenu();
                // }
            });
    
            document.body.addEventListener('click', function (e) {
                if ((!SiteMenuWrapper.contains(e.target) || document.querySelector('.n7-primary-navigation__backdrop').contains(e.target)) && mainMenuWrapper.classList.contains('is-open')) {
                    closeMobileMenu();
                }
            });
    
        }
    });
    
    
    /* SEARCH DIALOG */
    const openModal = () => {
        const modal = document.getElementById('searchModal');
        const modalContent = modal.querySelector('.n7-modal-content');
    
        modal.style.display = 'flex';
        modal.classList.add("z-20");
        modal.setAttribute('aria-hidden', 'false');
    
        // Get all the focusable elements inside the modal content
        const focusableElements = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
        const firstFocusable = modalContent.querySelectorAll(focusableElements)[0];
        const fallbackFocusable = modalContent.querySelector('.is-focusable-element'); // Adjust the selector if necessary
    
        // If there's a focusable element, focus on it; otherwise, focus on the fallback element
        if (firstFocusable) {
            firstFocusable.focus();
        } else if (fallbackFocusable) {
            fallbackFocusable.setAttribute('tabindex', '-1');
            fallbackFocusable.focus();
        }
    
        if (!document.documentElement.classList.contains('overflow-hidden')) {
            document.documentElement.classList.add('overflow-hidden');
        }
    };
    
    const closeModal = () => {
        const modal = document.getElementById('searchModal');
        const modalContent = modal.querySelector('.n7-modal-content');
        const previouslyFocusedElement = document.getElementById('searchModalTrigger');
    
        // Remove tabindex from the fallback focusable element
        const fallbackFocusable = modalContent.querySelector('.is-focusable-element');
        if (fallbackFocusable) {
            fallbackFocusable.removeAttribute('tabindex');
        }
    
        if (document.documentElement.classList.contains('overflow-hidden')) {
            document.documentElement.classList.remove('overflow-hidden');
        }
    
        modal.style.display = 'none';
        modal.setAttribute('aria-hidden', 'true');
        modal.classList.remove("z-10");
        previouslyFocusedElement.focus();
    };
    
    if (document.getElementById('searchModal')) {
        document.getElementById('searchModalTrigger').addEventListener('click', openModal);
    
        document.getElementById('closeModal').addEventListener('click', closeModal);
    
        document.getElementById('searchModal').addEventListener('keydown', function (event) {
            const modalContent = document.querySelector('.n7-modal-content');
            const focusableElements = modalContent.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
            const firstFocusableElement = focusableElements[0];
            const lastFocusableElement = focusableElements[focusableElements.length - 1];
    
            if (event.key === 'Tab') {
                if (event.shiftKey && document.activeElement === firstFocusableElement) {
                    lastFocusableElement.focus();
                    event.preventDefault();
                } else if (!event.shiftKey && document.activeElement === lastFocusableElement) {
                    firstFocusableElement.focus();
                    event.preventDefault();
                }
            }
    
            if (event.key === 'Escape') {
                closeModal();
            }
        });
    
        // window.addEventListener('click', function (event) {
        //     const modal = document.getElementById('searchModal');
        //     if (event.target === modal) {
        //         closeModal();
        //     }
        // });
    }
    
  • URL: /components/raw/header/header.js
  • Filesystem Path: components/04-organisms/header/header.js
  • Size: 15.1 KB

Modular header component.

Components:

  • top-bar component: manage secondary menu, search, other utilities
  • main-heading: cointains one or more logos, main navigation
  • bottom-bar

Use hasShadow:true in configuration to add header box shadow

  • classes: value - header classes

Blocks:

  • topBar
  • mainHeading
  • bottomBar
  • classes: for class overridings in variant templates, if needed