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() menuButtonSubmenuExpand?: string;
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 = data.detail.triggerType != 'remove';
this.assignMenuItemClass(this.el.parentElement.closest('hy-menu-level-container'), data.detail.triggerType);
// Scroll to .hy-menu top.
let hyMenu = this.el.parentElement.closest('hy-menu');
hyMenu.shadowRoot.querySelector('.hy-menu').scrollTop = 0;
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
item.setAttribute('menu-button-submenu-expand', this.menuButtonSubmenuExpand);
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];
switch (this.menuType) {
case 'desktop':
classAttributes = [...classAttributes, 'hy-menu-level-container--desktop'];
<Host class={classAttributes.join(' ')}>
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
case 'mobile':
classAttributes = [...classAttributes, 'hy-menu-level-container--mobile'];
if (this.depth === 1) {
classAttributes = [...classAttributes, 'is-open'];
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}
menu-type={'mobile'}
/>
<slot />
</Host>
);
}
case 'sidebar':
classAttributes = [...classAttributes, 'hy-menu-level-container--sidebar'];
if (this.depth === 1) {
classAttributes = [...classAttributes, 'is-open'];
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}
menu-type={'sidebar'}
/>
<slot />
</Host>
);
}