import {LitElement, html, css, unsafeCSS} from 'lit'; import { customElement, queryAssignedElements } from 'lit/decorators.js'; import { breakpoints } from '../../breakpoints'; @customElement('iu-header-navbar') export class SiteHeaderNavbar extends LitElement { static override styles = css` @media ${unsafeCSS(breakpoints.xxl)} { :host{ display: block; } } :host a{ color: var(--theme-color-black); text-decoration: none; } :host iu-container{ align-items: center; height: 3.75rem; background: var(--theme-color-white); display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); } .logo{ font-weight: 700; } .nav{ grid-column: 2 / 5; display: flex; justify-content: space-between; align-items: center; } .nav ul{ margin: 0; padding: 0; list-style-type: none; display: flex; } :host nav ul ::slotted(*:not(:last-child)){ margin-right: var(--iu-spacing-4); } .actions button{ width: 50px; height: 50px; background: transparent; border: 0; padding: 0; cursor: pointer; display: none; margin-right: calc((50px - 16px) / 2 * -1) } .actions button svg{ height: 16px; width: 16px; } `; // Query all `iu-header-navbar-item` elements @queryAssignedElements({ slot: '' }) navbarItems!: HTMLElement[]; private isAnySubmenuOpen(): boolean { return !this.navbarItems.some((item: any) => item.isActive); } private updateActionsVisibility() { const actionsButton = this.shadowRoot?.querySelector('.actions button') as HTMLElement; if (actionsButton) { if (this.isAnySubmenuOpen()) { actionsButton.style.display = 'block'; // Show the button } else { actionsButton.style.display = 'none'; // Hide the button } } } private handleSubmenuToggle(event: CustomEvent) { const { source } = event.detail; this.navbarItems.forEach((item: any) => { // Close all other submenus if (item !== source) { item.isActive = false; item.submenuElements.forEach((submenu: HTMLElement) => submenu.classList.remove('is-active') ); } // Handle closing animation if same element toggled if (event.detail.closing && item === source) { item.submenuElements.forEach((submenu: HTMLElement) => { submenu.classList.add('is-closing') const container = submenu.container; const containerHeight = container.scrollHeight; container.animate( [ { height: `${containerHeight}px` }, { height: 0 } ], { duration: 250, delay: 250, easing: 'ease-out' } ).onfinish = () => { submenu.classList.remove('is-closing'), submenu.classList.remove('is-active') } }); } }); // Check if any submenu is open and toggle button visibility this.updateActionsVisibility(); } private closeAllSubmenu(){ const actionsButton = this.shadowRoot?.querySelector('.actions button') as HTMLElement; if (actionsButton) { actionsButton.style.display = 'none'; // Hide the button } document.body.classList.remove('is-locked'); this.navbarItems.forEach((item: any) => { // Close all submenus item.isActive = false; item.submenuElements.forEach((submenu: HTMLElement) => { // Animate open submenu if (submenu.classList.contains('is-active')){ const overlay = document.querySelector('iu-overlay') as Overlay; overlay.visible = false; submenu.classList.add('is-closing'); const container = submenu.container; const containerHeight = container.scrollHeight; container.animate( [ { height: `${containerHeight}px` }, { height: 0 } ], { duration: 250, delay: 250, easing: 'ease-out' } ).onfinish = () => { submenu.classList.remove('is-closing'), submenu.classList.remove('is-active') } } else { submenu.classList.remove('is-active') } } ); }); } override connectedCallback() { super.connectedCallback(); this.addEventListener('iu-header-toggle-submenu', this.handleSubmenuToggle as EventListener); // Update the button visibility on initial load this.updateActionsVisibility(); } override disconnectedCallback() { this.removeEventListener('iu-header-toggle-submenu', this.handleSubmenuToggle as EventListener); super.disconnectedCallback(); } override render() { return html` <iu-container> <div class="logo"> <a href="#" class="logo">Università Iuav di Venezia</a> </div> <div class="nav"> <nav role="navigation"> <ul> <slot></slot> </ul> </nav> <div class="actions"> <button @click="${this.closeAllSubmenu}" role="button"><svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M18.838 1.161 1.16 18.84M18.838 18.839 1.16 1.16" stroke="#000" stroke-width="2"/></svg></button> </div> </div> </iu-container> `; } } declare global { interface HTMLElementTagNameMap { 'iu-header-navbar': SiteHeaderNavbar; } }