export interface DesktopLinks { label: string; url: string; menuLinkId: string; } 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 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(); } //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'); //@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"> <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 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> ); } }