export interface DonateLink { url: string; label: string; } import {Component, Element, Prop, State, h, Listen} from '@stencil/core'; import ResizeObserver from 'resize-observer-polyfill'; @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; @Prop() logoUrl?: string; @Prop() logoLabel?: string; @Prop() searchButtonLabel?: string; @Prop() menuButtonLabel?: string; @Prop({reflect: true}) menuType: string; private ro: ResizeObserver; private donateLink: DonateLink[]; @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(this.el); this.el.children[0].setAttribute('data-menu-language', this.dataMenuLanguage); } componentWillLoad() { 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); } 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)'; 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}} /> <hy-site-logo menu-type={this.menuType} url={this.logoUrl} label={this.logoLabel} /> <div class={'hy-site-header__menu-container'}> <hy-site-search menu-is-open={this.isMenuOpen} menu-type={this.menuType} label={this.searchButtonLabel} /> <button onClick={() => this.mobileMenuToggle()} class={{ 'hy-site-header__panel-toggle': true, 'is-open': this.isMenuOpen }} > {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(' ')}> <hy-site-logo menu-type={this.menuType} url={this.logoUrl} label={this.logoLabel} /> <slot name={'menu'} /> <div class={'menu--secondary'}> <hy-menu-language class={'menu--secondary__item is-first'} is-mobile={false} data-menu-language={this.dataMenuLanguage} /> <hy-site-search class={'menu--secondary__item'} menu-is-open={this.isMenuOpen} menu-type={this.menuType} label={this.searchButtonLabel} /> {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> ); } }