Newer
Older
Markus Kalijärvi
committed
import {Component, Element, h, Host, Listen, Prop, State} from '@stencil/core';
@Component({
tag: 'hy-menu-level-container',
styleUrl: 'menu-level-container.scss',
shadow: false
})
export class MenuLevelContainer {
@Element() el: HTMLElement;
@State() open: boolean = false;
@Prop() menuLevel: number;
Markus Kalijärvi
committed
@Prop({mutable: true, reflect: true}) triggerItem: string;
@Prop({mutable: true, reflect: true}) depth: number = 0;
@Prop({reflect: true}) activeTrailTriggered: boolean = false;
@Prop({mutable: true}) headingItem: any;
// Add/Remove is-hidden class from each upper level menu-items
// to make browsing more accessible.
assignMenuItemClass(parentMenu: Element, type: string) {
const items = Array.from(parentMenu.children);
items.forEach((item) => {
if (type === 'remove') {
item.classList.remove('is-hidden');
} else {
item.classList.add('is-hidden');
}
});
}
Markus Kalijärvi
committed
@Listen('menuContainerActiveTrail', {target: 'document', capture: true})
menuContainerActiveTrail(data) {
const currentMenuContainer = this.el.getAttribute('trigger-item');
if (currentMenuContainer === data.detail.triggerItem) {
this.activeTrailTriggered = true;
this.open = true;
this.assignMenuItemClass(this.el.parentElement.closest('hy-menu-level-container'), 'add');
Markus Kalijärvi
committed
}
}
@Listen('menuContainerToggled', {target: 'document', capture: true})
menuContainerToggled(data) {
// Toggle submenu.
if (this.triggerItem == data.detail.triggerItem) {
this.activeTrailTriggered = false;
this.open = !this.open;
this.assignMenuItemClass(this.el.parentElement.closest('hy-menu-level-container'), data.detail.triggerType);
Markus Kalijärvi
committed
}
}
componentWillUpdate() {
if (this.menuType) {
const items = Array.from(this.el.children);
items.forEach((item) => {
item.setAttribute('menu-type', this.menuType);
});
}
}
Markus Kalijärvi
committed
componentWillRender() {
let parentMenu = this.el.closest('hy-menu-level-container');
let nextParentMenu;
this.depth = 0;
while (parentMenu) {
nextParentMenu = parentMenu.parentElement.closest('hy-menu-level-container');
if (nextParentMenu === parentMenu) {
break;
} else {
parentMenu = nextParentMenu;
this.depth = this.depth + 1;
}
}
// Set trigger item for each menu level container and handle only submenus.
// Add a heading element foreach level.
if (this.menuLevel > 1) {
const parentMenuItem = this.el.closest('hy-menu-item');
this.triggerItem = parentMenuItem.getAttribute('menu-link-id');
this.headingItem = {...this.headingItem, url: parentMenuItem.getAttribute('url')};
this.headingItem = {...this.headingItem, label: parentMenuItem.getAttribute('label')};
} else {
this.triggerItem = 'home';
}
}
render() {
let classAttributes = ['hy-menu-level-container', 'hy-menu-level-container--level-' + this.depth];
if (this.menuType === 'desktop') {
classAttributes = [...classAttributes, 'hy-menu--desktop'];
Markus Kalijärvi
committed
return (
<Host class={classAttributes.join(' ')}>
Markus Kalijärvi
committed
<slot />
</Host>
);
}
else {
classAttributes = [...classAttributes, 'hy-menu--mobile'];
Markus Kalijärvi
committed
if (this.depth === 1) {
this.open = true;
classAttributes = [...classAttributes, this.open ? 'is-open' : null];
return (
<Host aria-expanded={this.open.toString()} class={classAttributes.join(' ')} tabindex={'-1'}>
<slot />
</Host>
);
} else {
classAttributes = [...classAttributes, this.open ? 'is-open' : null];
return (
<Host aria-expanded={this.open.toString()} class={classAttributes.join(' ')} tabindex={'-1'}>
<hy-menu-item label={this.headingItem.label} url={this.headingItem.url} isHeading={true} />
<slot />
</Host>
);
}