Skip to content
Snippets Groups Projects
Commit 5dd697dd authored by druid's avatar druid
Browse files

add search panel, v.1

parent 97839119
No related branches found
No related tags found
No related merge requests found
......@@ -752,6 +752,7 @@ export namespace Components {
}
interface HySiteSearch {
color: ColorVariant;
dataSearchSpecialTools: string;
isAlternative: boolean;
labels?: ComponentLabels[] | string;
showLabel: boolean;
......@@ -2060,8 +2061,10 @@ declare namespace LocalJSX {
}
interface HySiteSearch {
color?: ColorVariant;
dataSearchSpecialTools?: string;
isAlternative?: boolean;
labels?: ComponentLabels[] | string;
onSearchPanelToggled?: (event: CustomEvent<any>) => void;
showLabel?: boolean;
size?: number;
}
......
......@@ -12,6 +12,10 @@
## Dependencies
### Used by
- [hy-site-search](../site-header/site-search)
### Depends on
- [hy-icon](../icon)
......@@ -21,6 +25,7 @@
```mermaid
graph TD;
hy-search-field --> hy-icon
hy-site-search --> hy-search-field
style hy-search-field fill:#f9f,stroke:#333,stroke-width:4px
```
......
......@@ -49,6 +49,12 @@ export class MenuLanguage {
this.isMenuOpen = false;
}
// CLose the language menu if user opens the search panel
@Listen('searchPanelToggled', {target: 'document'})
searchPanelToggled() {
this.isMenuOpen = false;
}
@Listen('focus')
handleComponentFocus(event) {
// Close desktop menu panel if it's open.
......
......@@ -231,6 +231,13 @@ export class HyDesktopMenuLinks {
this.closePanel(fadeOut);
}
// Close the desktop menu panel if user opens search panel
@Listen('searchPanelToggled', {target: 'document'})
searchPanelToggled() {
let fadeOut = true;
this.closePanel(fadeOut);
}
// CLose the desktop menu panel if user scrolls Sticky Header till the very top.
@Listen('headerScrollUp', {target: 'document'})
headerScrollUp() {
......
......@@ -47,6 +47,8 @@ graph TD;
hy-menu-language --> hy-menu-language-item
hy-menu-language --> hy-icon
hy-site-search --> hy-icon
hy-site-search --> hy-search-field
hy-search-field --> hy-icon
style hy-site-header fill:#f9f,stroke:#333,stroke-width:4px
```
......
......@@ -4,13 +4,20 @@
## Properties
| Property | Attribute | Description | Type | Default |
| --------------- | ---------------- | ----------- | ------------------------------------------ | -------------------- |
| `color` | `color` | | `ColorVariant.black \| ColorVariant.white` | `ColorVariant.black` |
| `isAlternative` | `is-alternative` | | `boolean` | `false` |
| `labels` | `labels` | | `ComponentLabels[] \| string` | `undefined` |
| `showLabel` | `show-label` | | `boolean` | `false` |
| `size` | `size` | | `number` | `undefined` |
| Property | Attribute | Description | Type | Default |
| ------------------------ | --------------------------- | ----------- | ------------------------------------------ | -------------------- |
| `color` | `color` | | `ColorVariant.black \| ColorVariant.white` | `ColorVariant.black` |
| `dataSearchSpecialTools` | `data-search-special-tools` | | `string` | `undefined` |
| `isAlternative` | `is-alternative` | | `boolean` | `false` |
| `labels` | `labels` | | `ComponentLabels[] \| string` | `undefined` |
| `showLabel` | `show-label` | | `boolean` | `false` |
| `size` | `size` | | `number` | `undefined` |
## Events
| Event | Description | Type |
| -------------------- | ----------- | ------------------ |
| `searchPanelToggled` | | `CustomEvent<any>` |
## Dependencies
......@@ -21,12 +28,15 @@
### Depends on
- [hy-icon](../../icon)
- [hy-search-field](../../hy-search-field)
### Graph
```mermaid
graph TD;
hy-site-search --> hy-icon
hy-site-search --> hy-search-field
hy-search-field --> hy-icon
hy-site-header --> hy-site-search
style hy-site-search fill:#f9f,stroke:#333,stroke-width:4px
```
......
......@@ -83,3 +83,30 @@
}
}
}
.site-search {
&__panel {
display: none;
&__is-open {
background-color: var(--grayscale-white);
border: 1px solid rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
left: 0;
position: absolute;
width: 100%;
z-index: 520;
}
&__title {
background-color: #f8f8f8;
display: flex;
flex-direction: row;
justify-content: space-between;
.label {
}
.site-search__panel__panel-toggle {
}
}
}
}
import {Component, Prop, h, Watch} from '@stencil/core';
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';
......@@ -8,33 +13,145 @@ import {ColorVariant} from '../../../utils/utils';
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 (
<button
aria-label={this._labels['open']}
<Host
class={{
'button--search': true,
'is-open--menu': this.isAlternative,
'site-search': true,
'site-search__is-open': this.isSearchPanelOpen,
}}
>
{this.showLabel ? <span class={'button--search__label'}>{this._labels['label']}</span> : ''}
<hy-icon icon={'hy-icon-search'} size={this.size} fill={this.color} />
</button>
<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>
);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment