Newer
Older
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() {
// 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];
(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();
}
// 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>
);