Newer
Older
iuav-ui / src / components / header / header-navbar-item.ts
/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: BSD-3-Clause
 */

import {LitElement, html, css} from 'lit';
import {customElement, property, queryAssignedElements} from 'lit/decorators.js';

/**
 * An example element.
 */

@customElement('iu-header-navbar-item')

export class SiteHeaderNavbarItem extends LitElement {
  static override styles = css`
    :host a, :host span{
      color: var(--theme-color-black);
      text-decoration: none;
      cursor: pointer;
    }
    .is-active{
      text-decoration: underline;
    }
  `;

  @property() href?= '';
  @property() text= '';
  @property({type: Boolean}) isActive: boolean = false;
  @property({type: Boolean, reflect: true}) submenu: boolean = false;

  // Query the slotted content
  @queryAssignedElements({ slot: '' }) submenuElements!: HTMLElement[];

  private toggleSubmenu(){

    // Notify the parent navbar to handle submenu states
    this.dispatchEvent(
      new CustomEvent('iu-header-toggle-submenu', {
        bubbles: true,
        composed: true,
        detail: { 
          source: this,
          closing: this.isActive
        },
      })
    );
    
    this.isActive = !this.isActive;
    this.toggleOverlay(this.isActive);

    if (this.isActive) {
      // Get scrolled height
      document.body.dataset.scrollY = window.scrollY.toString();
      // Lock body
      document.body.style.top = `-${window.scrollY}px`;
      document.body.style.position = 'fixed';
    } else {
      // Remove and restore previous scroll position
      document.body.style.top = '';
      document.body.style.position = '';
      
      // Restore scroll position
      window.scrollTo(0, Number(document.body.dataset.scrollY || '0'));
    }  

    // Add/remove the `is-active` class on slotted elements
    this.submenuElements.forEach((submenu) => {
      if (this.isActive) {
        submenu.classList.add('is-active');
      } else {
        // submenu.classList.remove('is-active');
      }
    });

  }

  private toggleOverlay(visible: boolean) {
    const overlay = document.querySelector('iu-overlay') as Overlay;
    if (overlay) {
      overlay.visible = visible;
    }
  }

  override render() {

    const isActiveClass = this.isActive ? 'is-active' : '';
    const clickHandler = this.submenu ? this.toggleSubmenu : null;
  
    return html`
      <li 
        @click="${clickHandler}" 
        class="${isActiveClass}">
        ${this.submenu 
          ? html`<span>${this.text}</span>` 
          : html`<a href="${this.href}">${this.text}</a>`}
        <slot></slot>
      </li>
    `;

  }

}

declare global {
  interface HTMLElementTagNameMap {
    'iu-header-navbar-item': SiteHeaderNavbarItem;
  }
}