Newer
Older
export interface DonateLink {
url: string;
label: string;
}
Markus Kalijärvi
committed
export interface ComponentLabels {
open: string;
close: string;
expand?: string;
label?: string;
}
import {Component, Element, Prop, State, h, Listen} from '@stencil/core';
import ResizeObserver from 'resize-observer-polyfill';
import {SiteLogoSize, SiteLogoColor} from '../../utils/utils';
@Component({
tag: 'hy-site-header',
styleUrl: 'site-header.scss',
shadow: true
})
export class SiteHeader {
@Element() el: HTMLElement;
@State() isMobile: boolean;
@State() isMenuOpen: boolean = false;
@Prop() dataMenuLanguage: string;
@Prop() dataMenuDonate: string;
Markus Kalijärvi
committed
@Prop() dataSiteHeaderLabels: string;
@Prop() logoUrl?: string;
@Prop() logoLabel?: string;
@Prop({reflect: true}) menuType: string;
private ro: ResizeObserver;
private donateLink: DonateLink[];
Markus Kalijärvi
committed
private menuLabels: ComponentLabels[];
private searchLabels: ComponentLabels[];
private languageLabels: ComponentLabels[];
@Listen('mobileMenuToggle') mobileMenuToggle() {
this.isMenuOpen = !this.isMenuOpen;
}
componentDidLoad() {
this.ro = new ResizeObserver((entries) => {
for (const entry of entries) {
this.applySizeClasses(entry.contentRect.width);
}
});
this.ro.observe(document.body);
this.el.children[0].setAttribute('data-menu-language', this.dataMenuLanguage);
}
componentWillLoad() {
Markus Kalijärvi
committed
const labels = JSON.parse(this.dataSiteHeaderLabels);
this.menuLabels = labels.menu_labels;
this.languageLabels = labels.language_labels;
this.searchLabels = labels.search_labels;
this.donateLink = JSON.parse(this.dataMenuDonate);
}
componentWillUpdate() {
this.el.children[0].setAttribute('open', this.isMenuOpen.toString());
this.el.children[0].setAttribute('logo-label', this.logoLabel);
this.el.children[0].setAttribute('logo-url', this.logoUrl);
Markus Kalijärvi
committed
this.el.children[0].setAttribute('menu-button-submenu-expand', this.menuLabels['expand']);
this.el.children[0].setAttribute('menu-language-label-open', this.languageLabels['open']);
this.el.children[0].setAttribute('menu-language-label-close', this.languageLabels['close']);
}
componentDidUnload() {
this.ro.disconnect();
}
applySizeClasses(size: number) {
if (size < 768) {
this.el.children[0].setAttribute('menu-type', 'mobile');
this.menuType = 'mobile';
this.isMobile = true;
} else {
this.el.children[0].setAttribute('menu-type', 'desktop');
this.menuType = 'desktop';
this.isMobile = false;
}
}
render() {
const black = 'var(--brand-main-nearly-black)';
const white = 'var(--grayscale-white)';
const logoSize = this.isMobile ? SiteLogoSize.small : SiteLogoSize.big;
const logoColor = this.isMobile ? SiteLogoColor.white : SiteLogoColor.black;
let classAttributes = ['hy-site-header', 'hy-site-header--' + this.menuType];
return this.isMobile ? (
// Mobile
<header class={classAttributes.join(' ')}>
<div class={{'hy-backdrop': true, 'is-active': this.isMenuOpen}} />
<div class={'hy-site-header__logo-container'}>
<hy-site-logo size={logoSize} color={logoColor} url={this.logoUrl} label={this.logoLabel} />
</div>
<div class={'hy-site-header__menu-container'}>
<hy-site-search
is-alternative={this.isMenuOpen}
color={this.isMenuOpen ? black : white}
size={20}
Markus Kalijärvi
committed
labels={this.searchLabels}
/>
<button
onClick={() => this.mobileMenuToggle()}
class={{
'hy-site-header__panel-toggle': true,
'is-open': this.isMenuOpen
}}
Markus Kalijärvi
committed
aria-label={this.isMenuOpen ? this.menuLabels['close'] : this.menuLabels['open']}
>
{this.isMenuOpen ? (
<hy-icon icon={'hy-icon-remove'} size={20} fill={black} />
) : (
<hy-icon icon={'hy-icon-hamburger'} size={20} fill={white} />
)}
</button>
<div
class={{
'is-open': this.isMenuOpen,
'hy-site-header__panel': true
}}
>
<slot name={'menu'} />
</div>
</div>
</header>
) : (
// Desktop
<header class={classAttributes.join(' ')}>
<div class={'hy-site-header__logo-container'}>
<hy-site-logo size={logoSize} color={logoColor} url={this.logoUrl} label={this.logoLabel} />
</div>
<slot name={'menu'} />
<div class={'menu--secondary'}>
<hy-menu-language
class={'menu--secondary__item is-first'}
is-mobile={false}
data-menu-language={this.dataMenuLanguage}
Markus Kalijärvi
committed
labels={this.languageLabels}
/>
<hy-site-search
class={'menu--secondary__item'}
size={14}
color={black}
show-label={true}
Markus Kalijärvi
committed
labels={this.searchLabels}
/>
{this.donateLink.map((i) => {
return (
<a class={'menu--secondary__item hy-link__donate'} href={i.url}>
<hy-icon icon={'hy-icon-euro'} size={14} fill={black} />
<span class={'hy-link__donate__label'}>{i.label}</span>
</a>
);
})}
</div>
</header>
);
}
}