export interface DesktopLinks { label: string; url: string; menuLinkId: string; items: Array<DesktopLinks>; } 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. 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. let hyDesktopPanel = this.el.shadowRoot.querySelectorAll('.hy-desktop-menu-panel')[0]; if (hyDesktopPanel) { // Hide panel, remove class is-active. (hyDesktopPanel as HTMLElement).classList.remove('hy-desktop-menu-panel--is-active'); let menuItems = hyDesktopPanel.querySelectorAll('ul.first'); menuItems.forEach((item) => { (item as HTMLElement).classList.remove('desktop-menu--is-active'); }); } } @Listen('click') handleMenuDesktopLinkClick(event) { this.closeDesktopMenuPanel(); event.stopPropagation(); } //Show desktop menu panel handleMenuDesktopHover(id) { // 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'); 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'); // Show proper subtree on panel based on given menu-link-id. let menuItems = hyDesktopPanel.querySelectorAll('ul.first'); menuItems.forEach((item) => { (item as HTMLElement).classList.remove('desktop-menu--is-active'); }); 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 = []; links.forEach((item) => { let className = 'desktop-menu-link'; firstLevelLinksList.push( <div class={className} link-id={item.menuLinkId} onMouseOver={() => this.handleMenuDesktopHover(item.menuLinkId)} onFocus={() => this.handleMenuDesktopHover(item.menuLinkId)} tabIndex={0} > {item.label} <span class="desktop-menu-link__heading__icon"> <hy-icon icon={'hy-icon-caret-down'} size={16} /> </span> </div> ); }); this.firstLevelLinksList = firstLevelLinksList; } render() { return ( <nav role={'navigation'} class="hy-site-header__menu-desktop"> <ul> {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 ( <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> </a> {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> ); })} </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> ); } }