Skip to content
Snippets Groups Projects
hy-desktop-menu-links.tsx 9.17 KiB
Newer Older
  • Learn to ignore specific revisions
  • export interface ShortcutLinks {
      shortcut_title: string;
      shortcut_url: string;
      shortcut_is_external: string;
      shortcut_aria_label: string;
    }
    
    
    export interface DesktopLinks {
      label: string;
      url: string;
    
      description: string;
    
      menuLinkId: string;
    
    druid's avatar
    druid committed
      items: Array<DesktopLinks>;
    
      shortcuts: Array<ShortcutLinks>;
    
    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');
    
    
    druid's avatar
    druid committed
          let menuItems = hyDesktopPanel.querySelectorAll('ul.first');
    
    druid's avatar
    druid committed
          menuItems.forEach((item) => {
    
    druid's avatar
    druid committed
            (item as HTMLElement).classList.remove('desktop-menu--is-active');
    
    druid's avatar
    druid committed
          });
    
        }
      }
    
      @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');
    
    
    druid's avatar
    druid committed
          // Show proper subtree on panel based on given menu-link-id.
          let menuItems = hyDesktopPanel.querySelectorAll('ul.first');
    
    druid's avatar
    druid committed
          menuItems.forEach((item) => {
    
    druid's avatar
    druid committed
            (item as HTMLElement).classList.remove('desktop-menu--is-active');
    
    druid's avatar
    druid committed
          });
    
    
    druid's avatar
    druid committed
          let menuActivatedItems = hyDesktopPanel.querySelectorAll('ul[menu-link-id="' + id + '"]');
          (menuActivatedItems[0] as HTMLElement).classList.add('desktop-menu--is-active');
    
        }
      }
    
      componentDidLoad() {
        const links = this._dataDesktopLinks as Array<DesktopLinks>;
        let firstLevelLinksList = [];
    
    
    druid's avatar
    druid committed
        links.forEach((item) => {
    
          let classAttributes = [
            'desktop-menu-link',
            item.isActive === 'true' ? 'desktop-menu-link--is-active-trail' : '',
          ].join(' ');
    
          //item.isActive ? classAttributes'desktop-menu-link--is-active-trail' : ''
    
    
          firstLevelLinksList.push(
            <div
    
              class={classAttributes}
    
    druid's avatar
    druid committed
              link-id={item.menuLinkId}
              onMouseOver={() => this.handleMenuDesktopHover(item.menuLinkId)}
    
              onFocus={() => this.handleMenuDesktopHover(item.menuLinkId)}
              tabIndex={0}
    
    druid's avatar
    druid committed
              {item.label}
    
              <span class="desktop-menu-link__heading__icon">
    
    Ekaterina Kondareva's avatar
    Ekaterina Kondareva committed
                <hy-icon icon={'hy-icon-caret-down'} size={16} />
    
    druid's avatar
    druid committed
        });
    
    
        this.firstLevelLinksList = firstLevelLinksList;
      }
    
      render() {
    
    druid's avatar
    druid committed
        return (
    
    shamalainen's avatar
    shamalainen committed
          <nav role={'navigation'} class="hy-site-header__menu-desktop">
            <ul class="hy-site-header__menu-desktop-container">
              {this.firstLevelLinksList.map((firstLevelLink) => {
                return (
                  <li>
                    {firstLevelLink}
                    <div class="hy-desktop-menu-panel" onMouseLeave={() => this.closeDesktopMenuPanel()}>
                      <div class="hy-desktop-menu-panel__desktop-menu">
                        {this._dataDesktopLinks &&
                          this._dataDesktopLinks.map((link) => {
                            return (
                              <div>
                                <ul class={'desktop-menu first'} menu-link-id={link.menuLinkId}>
                                  <li class={'first'}>
                                    <a aria-current={link.label} href={link.url} class="" menu-link-id={link.menuLinkId}>
                                      <span class="heading-icon-first">
                                        <hy-icon icon={'hy-icon-arrow-right'} size={40} />
                                      </span>
                                      <span class="hy-menu-item__label">{link.label}</span>
    
    druid's avatar
    druid committed
                                      <span class="hy-menu-item__description">{link.description}</span>
    
    shamalainen's avatar
    shamalainen committed
                                    {link.items && (
                                      <ul class="second" menu-link-id={link.menuLinkId}>
                                        {link.items.map((subitem) => {
                                          return (
                                            <li class={'second'}>
                                              <a
                                                aria-current={subitem.label}
                                                href={subitem.url}
                                                class=""
                                                menu-link-id={subitem.menuLinkId}
                                              >
                                                <span class="heading-icon-second">
                                                  <hy-icon icon={'hy-icon-caret-right'} size={12} />
                                                </span>
                                                <span class="hy-menu-item__label">{subitem.label}</span>
                                              </a>
                                            </li>
                                          );
                                        })}
                                      </ul>
                                    )}
                                  </li>
                                </ul>
                                {link.shortcuts.length > 0 && (
                                  <div class="shortcuts-panel">
    
    druid's avatar
    druid committed
                                    <div class="shortcuts-panel__title">{'Shortcuts'}</div>
                                    {link.shortcuts.map((shortcut_item, index) => {
    
    shamalainen's avatar
    shamalainen committed
                                      let target = shortcut_item.shortcut_is_external ? '_blank' : '_self';
    
    druid's avatar
    druid committed
                                      let shortcutClass = [
                                        'shortcuts-panel__shortcut-item',
                                        index == 0 ? 'shortcuts-panel__shortcut-item__first' : '',
                                      ].join(' ');
    
    shamalainen's avatar
    shamalainen committed
                                      return (
    
    druid's avatar
    druid committed
                                        <div class={shortcutClass}>
    
    shamalainen's avatar
    shamalainen committed
                                          <a
                                            aria-current={shortcut_item.shortcut_aria_label}
                                            href={shortcut_item.shortcut_url}
                                            class="shortcut-item__link"
                                            target={target}
                                            aria-label={shortcut_item.shortcut_aria_label}
                                          >
                                            <span class="shortcut-item__label">{shortcut_item.shortcut_title}</span>
    
    druid's avatar
    druid committed
                                            <span class="shortcut-item__icon">
                                              <hy-icon icon={'hy-icon-arrow-right'} size={24} />
                                            </span>
    
    shamalainen's avatar
    shamalainen committed
                                          </a>
                                        </div>
                                      );
                                    })}
    
    shamalainen's avatar
    shamalainen committed
                                )}
                              </div>
                            );
                          })}
                      </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>
                  </li>
                );
              })}
            </ul>
          </nav>
    
    druid's avatar
    druid committed
        );