Newer
Older
iuav-ui / src / components / mobile-menu / mobile-menu.ts
import { LitElement, html, css, unsafeCSS} from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { breakpoints } from '../../breakpoints';

@customElement('iu-mobile-menu')

export class MobileMenu extends LitElement {

  static override styles = css`
    :host {
        position: fixed;
        display: none;
        left: 0;
        height: calc(100dvh - 50px);
        width: 100%;
        max-width: 48rem;
        background: var(--iu-color-white);
        top: 50px;
        z-index: 50;
        overflow: auto;
    }
    @media ${unsafeCSS(breakpoints.md)} {
      :host{
        width: calc((100% - var(--iu-grid-offset)) - var(--iu-grid-gutter));
      }
    }
    :host([open]){
      display: block;
    }
    /* fallback if event listener doesn't work */
    @media ${unsafeCSS(breakpoints.xl)} {
      :host([open]){
        display: none;
      }
    }
    ul{
      list-style-type: none;
      padding: 0;
      margin: 0;
    }
    .secondary-nav{
      background: var(--iu-color-black);
      ul{
        padding-top: var(--iu-spacing-1);
        padding-bottom: var(--iu-spacing-2);
      }
      li:not(:last-child){
        margin-bottom: var(--iu-spacing-0);
      }
      a{
        color: var(--iu-color-white);
        text-decoration: none;
        padding: 0 var(--iu-grid-gutter);
      }
    }
  `;

  @property({ type: String }) label? = 'Menu principale';
  @property({ type: Boolean, reflect: true }) open : boolean = false; 
  @property({ type: Array, attribute: 'secondary-nav-items' }) secondaryNavItems: Array<{ text: string; href: string }> = [];
  @property({ type: String, attribute: 'secondary-nav-label' }) secondaryNavLabel: string = 'Menu secondario';

  private handleMenuToggle = () => {
    this.open = !this.open;
    this.requestUpdate();
  };  

  override connectedCallback() {
    super.connectedCallback();
    window.addEventListener('toggle-mobile-menu', this.handleMenuToggle);
  }
  
  override disconnectedCallback() {
    window.removeEventListener('toggle-mobile-menu', this.handleMenuToggle);
    super.disconnectedCallback();
  }  

  override render() {
    return html`
      ${this.secondaryNavItems.length > 0 ? html`
          <nav aria-label="${this.secondaryNavLabel}" role="navigation" class="secondary-nav">
            <ul>
              ${this.secondaryNavItems.map(
                item => html`
                  <li><a href="${item.href}">${item.text}</a></li>
                `)
              }
            </ul>
          </nav>
        `
        : ''
      }
      <nav aria-label="${this.label}" role="navigation">
          <ul>
              <slot></slot>
          </ul>
      </nav>
    `;
  }
}

declare global {
    interface HTMLElementTagNameMap {
      'iu-mobile-menu': MobileMenu;
    }
  }