Skip to content
Snippets Groups Projects
hy-desktop-menu-links.tsx 4.69 KiB
Newer Older
  • Learn to ignore specific revisions
  • export interface DesktopLinks {
      label: string;
      url: string;
      menuLinkId: string;
    }
    
    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() {
        let hySiteHeader = document.querySelectorAll('hy-site-header')[0];
    
        // Remove is-active from desktop menu links.
        let hyDesktopMenuLinks = hySiteHeader.shadowRoot.querySelector('hy-desktop-menu-links');
        let desktopMenuItems = hyDesktopMenuLinks.shadowRoot.querySelectorAll('.desktop-menu-link');
        desktopMenuItems.forEach((item) => {
          (item as HTMLElement).classList.remove('desktop-menu-link--is-active');
        });
    
        // Close desktop menu panel.
        let hyDesktopPanel = hySiteHeader.shadowRoot.querySelector('hy-desktop-menu-panel');
        if (hyDesktopPanel) {
          //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) {
        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');
    
        let hySiteHeader = document.querySelectorAll('hy-site-header')[0];
        if (hySiteHeader) {
          let hyDesktopPanel = hySiteHeader.shadowRoot.querySelector('hy-desktop-menu-panel');
    
          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.
    
    Ekaterina Kondareva's avatar
    Ekaterina Kondareva committed
            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() {
        return <div class={'hy-site-header__menu-desktop'}>{this.firstLevelLinksList}</div>;
      }
    }