Skip to content
Snippets Groups Projects
hy-desktop-menu-links.tsx 5.14 KiB
Newer Older
export interface DesktopLinks {
  label: string;
  url: string;
  menuLinkId: string;
}

druid's avatar
druid committed
import {ColorVariant} from '../../../utils/utils';
import {Component, h, Element, Listen, Prop, State, Watch} from '@stencil/core';

@Component({
  tag: 'hy-desktop-menu-links',
  styleUrl: 'hy-desktop-menu-links.scss',
  shadow: true,
})
export class HyDesktopMenuLinks {
  @Element() el: HTMLElement;
  /*
  First level menu links to be displayed on Desktop screens.
  * */
  @Prop() dataDesktopLinks: DesktopLinks[] | string;
  private _dataDesktopLinks: DesktopLinks[];
  @State() firstLevelLinksList: Array<object> = [];

  @Watch('dataDesktopLinks') dataDesktopLinksWatcher(data: DesktopLinks[] | string) {
    this._dataDesktopLinks = typeof data === 'string' ? JSON.parse(data) : data;
  }

  componentWillLoad() {
    this.dataDesktopLinksWatcher(this.dataDesktopLinks);
  }

  closeDesktopMenuPanel() {
    // Remove is-active from desktop menu links.
druid's avatar
druid committed
    let desktopMenuItems = this.el.shadowRoot.querySelectorAll('.desktop-menu-link');
    desktopMenuItems.forEach((item) => {
      (item as HTMLElement).classList.remove('desktop-menu-link--is-active');
    });

    // Close desktop menu panel.
druid's avatar
druid committed
    let hyDesktopPanel = this.el.shadowRoot.querySelectorAll('.hy-desktop-menu-panel')[0];
    if (hyDesktopPanel) {
druid's avatar
druid committed
      // Hide panel, remove class is-active.
      (hyDesktopPanel as HTMLElement).classList.remove('hy-desktop-menu-panel--is-active');

      let parentMenu = document.querySelectorAll('hy-menu-level-container[menu-level="2"]');
      if (parentMenu) {
        const items = Array.from(parentMenu);
        items.forEach((item) => {
          item.classList.add('hy-menu-level-container--mobile');
          item.classList.remove('hy-menu-level-container--desktop');
        });
      }
    }
  }

  @Listen('click')
  handleMenuDesktopLinkClick(event) {
    this.closeDesktopMenuPanel();
    event.stopPropagation();
  }

Ekaterina Kondareva's avatar
Ekaterina Kondareva committed
  //Show desktop menu panel
  handleMenuDesktopHover(id) {
druid's avatar
druid committed
    // Set is-active class for the desktop menu selected link to highlight it.
    let desktopMenuItems = this.el.shadowRoot.querySelectorAll('.desktop-menu-link');
    desktopMenuItems.forEach((item) => {
      (item as HTMLElement).classList.remove('desktop-menu-link--is-active');
    });
    let desktopMenuActivatedItems = this.el.shadowRoot.querySelectorAll('.desktop-menu-link[link-id="' + id + '"]');
    (desktopMenuActivatedItems[0] as HTMLElement).classList.add('desktop-menu-link--is-active');

druid's avatar
druid committed
    let hyDesktopPanel = this.el.shadowRoot.querySelectorAll('.hy-desktop-menu-panel')[0];
    if (hyDesktopPanel) {
      // Show panel, add class is-active.
      (hyDesktopPanel as HTMLElement).classList.add('hy-desktop-menu-panel--is-active');

      //@todo show proper subtree on panel based on given menu-link-id
      // Hide all menu-item that have other menu-link-id attribute value.
      let menuItems = document.querySelectorAll('hy-site-header hy-menu-item');
      menuItems.forEach((item) => {
        (item as HTMLElement).classList.remove('hy-menu-item--is-active');
      });

      let menuActivatedItems = document.querySelectorAll('hy-site-header hy-menu-item[menu-link-id="' + id + '"]');
      (menuActivatedItems[0] as HTMLElement).classList.add('hy-menu-item--is-active');

      let parentMenu = (menuActivatedItems[0] as HTMLElement).querySelector('hy-menu-level-container[menu-level="2"]');
      if (parentMenu && parentMenu.children) {
        (parentMenu as HTMLElement).classList.remove('hy-menu-level-container--mobile');
        (parentMenu as HTMLElement).classList.add('hy-menu-level-container--desktop');
        const items = Array.from(parentMenu.children);
        items.forEach((item) => {
          item.classList.add('hy-menu-item--is-active');
        });
      }
    }
  }

  componentDidLoad() {
    const links = this._dataDesktopLinks as Array<DesktopLinks>;
    let firstLevelLinksList = [];

    for (let i = 0; i < links.length; i++) {
      let className = 'desktop-menu-link';
      firstLevelLinksList.push(
        <div
          class={className}
          link-id={links[i].menuLinkId}
          onMouseOver={() => this.handleMenuDesktopHover(links[i].menuLinkId)}
        >
          {links[i].label}
          <span class="desktop-menu-link__heading__icon">
Ekaterina Kondareva's avatar
Ekaterina Kondareva committed
            <hy-icon icon={'hy-icon-caret-down'} size={16} />
          </span>
        </div>
      );
    }
    this.firstLevelLinksList = firstLevelLinksList;
  }

  render() {
druid's avatar
druid committed
    return (
      <div class="hy-site-header__menu-desktop">
        {this.firstLevelLinksList}
        <div class="hy-desktop-menu-panel" onMouseLeave={() => this.closeDesktopMenuPanel()}>
          <div class="hy-desktop-menu-panel__desktop-menu">
            <slot></slot>
          </div>
          <button
            onClick={() => this.closeDesktopMenuPanel()}
            class={{
              'hy-desktop-menu-panel__panel-toggle': true,
            }}
            aria-label="close"
          >
            <span class="hy-desktop-menu-panel__panel-toggle__label">
              CLOSE
              <hy-icon icon={'hy-icon-remove'} size={20} fill={ColorVariant.black} />
            </span>
          </button>
        </div>
      </div>
    );