From 5dd697dd7b489fa59cbc9df63278868c87968f18 Mon Sep 17 00:00:00 2001
From: druid <druid@druids-MBP-2.lan>
Date: Fri, 5 Feb 2021 15:15:54 +0200
Subject: [PATCH] add search panel, v.1

---
 src/components.d.ts                           |   3 +
 src/components/hy-search-field/readme.md      |   5 +
 .../menu-language/menu-language.tsx           |   6 +
 .../hy-desktop-menu-links.tsx                 |   7 +
 src/components/site-header/readme.md          |   2 +
 .../site-header/site-search/readme.md         |  24 +++-
 .../site-header/site-search/site-search.scss  |  27 ++++
 .../site-header/site-search/site-search.tsx   | 133 ++++++++++++++++--
 8 files changed, 192 insertions(+), 15 deletions(-)

diff --git a/src/components.d.ts b/src/components.d.ts
index 1c11d510..0b93845a 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -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;
   }
diff --git a/src/components/hy-search-field/readme.md b/src/components/hy-search-field/readme.md
index 1d190e11..6ef6e908 100644
--- a/src/components/hy-search-field/readme.md
+++ b/src/components/hy-search-field/readme.md
@@ -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
 ```
 
diff --git a/src/components/navigation/menu-language/menu-language.tsx b/src/components/navigation/menu-language/menu-language.tsx
index 60d8c8f2..6af56d64 100644
--- a/src/components/navigation/menu-language/menu-language.tsx
+++ b/src/components/navigation/menu-language/menu-language.tsx
@@ -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.
diff --git a/src/components/site-header/hy-desktop-menu-links/hy-desktop-menu-links.tsx b/src/components/site-header/hy-desktop-menu-links/hy-desktop-menu-links.tsx
index 35bd9d81..3ea0d1da 100644
--- a/src/components/site-header/hy-desktop-menu-links/hy-desktop-menu-links.tsx
+++ b/src/components/site-header/hy-desktop-menu-links/hy-desktop-menu-links.tsx
@@ -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() {
diff --git a/src/components/site-header/readme.md b/src/components/site-header/readme.md
index b1e105e5..8bec20a7 100644
--- a/src/components/site-header/readme.md
+++ b/src/components/site-header/readme.md
@@ -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
 ```
 
diff --git a/src/components/site-header/site-search/readme.md b/src/components/site-header/site-search/readme.md
index 646bcbb7..91786f08 100644
--- a/src/components/site-header/site-search/readme.md
+++ b/src/components/site-header/site-search/readme.md
@@ -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
 ```
diff --git a/src/components/site-header/site-search/site-search.scss b/src/components/site-header/site-search/site-search.scss
index f9991d1e..1d91d243 100644
--- a/src/components/site-header/site-search/site-search.scss
+++ b/src/components/site-header/site-search/site-search.scss
@@ -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 {
+      }
+    }
+  }
+}
diff --git a/src/components/site-header/site-search/site-search.tsx b/src/components/site-header/site-search/site-search.tsx
index 14ed05b7..fa498d5a 100644
--- a/src/components/site-header/site-search/site-search.tsx
+++ b/src/components/site-header/site-search/site-search.tsx
@@ -1,4 +1,9 @@
-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>
     );
   }
 }
-- 
GitLab