Skip to content
Snippets Groups Projects
hy-desktop-menu-links.tsx 6.7 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> = [];
    
      @State() menuLinkItems: Array<object> = [];
    
    
      @Watch('dataDesktopLinks') dataDesktopLinksWatcher(data: DesktopLinks[] | string) {
        this._dataDesktopLinks = typeof data === 'string' ? JSON.parse(data) : data;
      }
    
      componentWillLoad() {
        this.dataDesktopLinksWatcher(this.dataDesktopLinks);
      }
    
    
      handleDesktopMenuClose() {
        const menuItems = this.el.shadowRoot.querySelectorAll(`.desktop-menu-link`);
        const menuPanelItems = this.el.shadowRoot.querySelectorAll('.hy-desktop-menu-panel');
    
        // Reset elements by removing the active classes.
        menuItems.forEach((item) => {
          item.classList.remove('desktop-menu-link--is-active');
        });
        menuPanelItems.forEach((item) => {
          item.classList.remove('hy-desktop-menu-panel--is-active');
        });
    
      }
    
      @Listen('click')
      handleMenuDesktopLinkClick(event) {
    
        this.handleDesktopMenuClose();
    
        event.stopPropagation();
      }
    
    
      handleDesktopMenuToggle(id) {
    
    druid's avatar
    druid committed
        console.log(id);
    
    
        const menuItems = this.el.shadowRoot.querySelectorAll(`.desktop-menu-link`);
    
    druid's avatar
    druid committed
        const menuPanelItems = this.el.shadowRoot.querySelectorAll('.hy-desktop-menu-panel'); // all panels
    
        const activeMenuItem = this.el.shadowRoot.querySelector(`.desktop-menu-link[link-id="${id}"]`);
    
    druid's avatar
    druid committed
        const activeMenuItemSibling = activeMenuItem.nextElementSibling; // current panel
    
    
        // Reset elements by removing the active classes.
        menuItems.forEach((item) => {
          item.classList.remove('desktop-menu-link--is-active');
    
        menuPanelItems.forEach((item) => {
          item.classList.remove('hy-desktop-menu-panel--is-active');
        });
    
        // Add active classes to the currently active item and its sibling element.
        activeMenuItem.classList.add('desktop-menu-link--is-active');
        activeMenuItemSibling.classList.add('hy-desktop-menu-panel--is-active');
    
      }
    
      componentDidLoad() {
        const links = this._dataDesktopLinks as Array<DesktopLinks>;
    
    druid's avatar
    druid committed
        links.map(({menuLinkId: id, shortcuts, items, url, description, label, isActive}) => {
          let classAttributes = ['desktop-menu-link', isActive === 'true' ? 'desktop-menu-link--is-active-trail' : ''].join(
            ' '
          );
    
    
          menuLinkItems.push(
            <li>
              <button
                type="button"
    
    druid's avatar
    druid committed
                class={classAttributes}
    
                link-id={id}
                onMouseOver={() => this.handleDesktopMenuToggle(id)}
                onFocus={() => this.handleDesktopMenuToggle(id)}
              >
                {label}
                <span class="desktop-menu-link__heading__icon">
                  <hy-icon icon={'hy-icon-caret-down'} size={16} />
                </span>
              </button>
              <div class="hy-desktop-menu-panel" onMouseLeave={() => this.handleDesktopMenuClose()}>
                <div class="hy-desktop-menu-panel__desktop-menu">
    
    druid's avatar
    druid committed
                  <a
                    aria-current={label}
                    href={url}
                    class="hy-desktop-menu-panel__desktop-menu__first-level-menu-item"
                    menu-link-id={id}
                  >
                    <span class="heading-icon">
    
                      <hy-icon icon={'hy-icon-arrow-right'} size={40} />
                    </span>
    
    druid's avatar
    druid committed
                    <span class="label">{label}</span>
                    {description && <span class="description">{description}</span>}
    
    druid's avatar
    druid committed
                  <ul class={'hy-desktop-menu-panel__desktop-menu__second-level-menu'} menu-link-id={id}>
    
    druid's avatar
    druid committed
                    {items.map(({label, url}) => (
    
    druid's avatar
    druid committed
                        <a href={url}>
    
    druid's avatar
    druid committed
                          <span class="heading-icon">
    
    druid's avatar
    druid committed
                            <hy-icon icon={'hy-icon-caret-right'} size={12} />
                          </span>
    
    druid's avatar
    druid committed
                          <span class="label">{label}</span>
    
    druid's avatar
    druid committed
                        </a>
    
                      </li>
                    ))}
                  </ul>
                  {shortcuts.length > 0 && (
                    <ul class="shortcuts-panel">
    
                      <h2 class="shortcuts-panel__title">{'Shortcuts'}</h2>
                      {shortcuts.map(({shortcut_title, shortcut_url, shortcut_is_external, shortcut_aria_label}, index) => {
    
                        let target = shortcut_is_external ? '_blank' : '_self';
    
    
                        let shortcutClass = [
                          'shortcuts-panel__shortcut-item',
                          index == 0 ? 'shortcuts-panel__shortcut-item__first' : '',
                        ].join(' ');
    
    
                          <li class={shortcutClass}>
    
                            <a
                              aria-current={shortcut_aria_label}
                              href={shortcut_url}
                              class="shortcut-item__link"
                              target={target}
                              aria-label={shortcut_aria_label}
                            >
    
    druid's avatar
    druid committed
                              <span class="label">{shortcut_title}</span>
                              <span class="icon">
    
                                <hy-icon icon={'hy-icon-arrow-right'} size={24} />
                              </span>
    
                            </a>
                          </li>
                        );
                      })}
                    </ul>
                  )}
                </div>
                <button
                  onClick={() => this.handleDesktopMenuClose()}
                  class={{
                    'hy-desktop-menu-panel__panel-toggle': true,
                  }}
                  aria-label="close"
                >
                  <span class="hy-desktop-menu-panel__panel-toggle__label">
    
    druid's avatar
    druid committed
                    <span class="hy-desktop-menu-panel__panel-toggle__label__title">CLOSE</span>
    
                    <hy-icon icon={'hy-icon-remove'} size={20} fill={ColorVariant.black} />
                  </span>
                </button>
              </div>
            </li>
    
    druid's avatar
    druid committed
        });
    
    
        this.menuLinkItems = menuLinkItems;
    
    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.menuLinkItems}</ul>
    
    shamalainen's avatar
    shamalainen committed
          </nav>
    
    druid's avatar
    druid committed
        );