export interface SearchSpecialTools { url: string; label: string; } import {Component, Prop, h, Watch, State, Listen, Host, Event, EventEmitter, Element} from '@stencil/core'; import {ComponentLabels} from '../site-header'; import {ColorVariant} from '../../../utils/utils'; @Component({ tag: 'hy-site-search', styleUrl: 'site-search.scss', shadow: true, }) export class SiteSearch { @Element() el: HTMLElement; @Prop() color: ColorVariant = ColorVariant.black; @Prop() isAlternative: boolean = false; @Prop() labels?: ComponentLabels[] | string; @Prop() showLabel: boolean = false; @Prop() size: number; @Prop() dataSearchSpecialTools: string; private _dataSearchSpecialTools: SearchSpecialTools[]; @State() isSearchPanelOpen: boolean = false; @Event() searchPanelToggled: EventEmitter; private _labels: ComponentLabels[]; @Watch('labels') labelsWatcher(data: ComponentLabels[] | string) { this._labels = typeof data === 'string' ? JSON.parse(data) : data; } componentWillLoad() { if (this.dataSearchSpecialTools) { this._dataSearchSpecialTools = JSON.parse(this.dataSearchSpecialTools); } } componentWillRender() { this.labelsWatcher(this.labels); } // CLose the search panel if user opens the desktop menu panel. @Listen('menuDesktopToggled', {target: 'document'}) desktopMenuToggled() { this.isSearchPanelOpen = false; } // CLose the search panel if user opens the language menu. @Listen('menuLanguageToggled', {target: 'document'}) menuLanguageToggled() { this.isSearchPanelOpen = false; } // Close the search panel if user clicks anywhere outside the Search component. @Listen('click', {target: 'window'}) handleWindowClick(event) { if (event.target.tagName.toLowerCase() !== 'hy-site-search') { this.isSearchPanelOpen = false; } event.stopPropagation(); } handleSearchPanelToggle() { this.isSearchPanelOpen = !this.isSearchPanelOpen; if (this.isSearchPanelOpen) { //const searchPanelSelector = this.el as HTMLElement; // Close desktop menu panel and lang menu panel if they are open. this.searchPanelToggled.emit(); let hyHeader = this.el.closest('.hy-site-header') as HTMLElement; let rectHeader = hyHeader.getBoundingClientRect(); const headerHeight = `${rectHeader.bottom}px`; const searchPanel = this.el.shadowRoot.querySelectorAll(`.site-search__panel`)[0] as HTMLElement; searchPanel.style.top = headerHeight; } //event.stopPropagation(); } handleSearchPanelClose() { this.isSearchPanelOpen = false; } render() { return ( <Host class={{ 'site-search': true, 'site-search__is-open': this.isSearchPanelOpen, }} > <button aria-label={this._labels['open']} class={{ 'button--search': true, 'is-open--menu': this.isAlternative, 'is-open': this.isSearchPanelOpen, }} onClick={() => this.handleSearchPanelToggle()} > {this.showLabel ? <span class={'button--search__label'}>{this._labels['label']}</span> : ''} <hy-icon icon={'hy-icon-search'} size={this.size} fill={this.color} /> </button> <div class={{ 'site-search__panel': true, 'site-search__panel__is-open': this.isSearchPanelOpen, }} > <div class="site-search__panel__title"> <div class="site-search__panel__title__label"> <h1>Search</h1> <div>web pages, study options, people, research groups, etc…</div> </div> <button onClick={() => this.handleSearchPanelClose()} class={{ 'site-search__panel__panel-toggle': true, }} aria-label="Exit Search" > <span class="site-search__panel__panel-toggle__label"> <span class="site-search__panel__panel-toggle__label__title">Exit Search</span> <hy-icon icon={'hy-icon-remove'} size={20} fill={ColorVariant.black} /> </span> </button> </div> <div class="site-search__panel__input"> <hy-search-field input-id="search" label="Search degree programmes" /> </div> <div class="site-search__panel__results"> <div class="filters"></div> <div class="results"></div> </div> {this.dataSearchSpecialTools && this._dataSearchSpecialTools.length > 0 && ( <div class="site-search__panel__tools"> <div>Special Search tools</div> {this._dataSearchSpecialTools.map((i) => { return ( <a class={'search-special-tool'} href={i.url}> <hy-icon icon={'hy-icon-arrow-to-right'} size={14} fill={ColorVariant.black} /> <span class={'search-special-tool__label'}>{i.label}</span> </a> ); })} </div> )} </div> </Host> ); } }