From 529c915a9d8342aad76429e7999a4404d259f64c Mon Sep 17 00:00:00 2001
From: druid <druid@druids-MBP-2.lan>
Date: Fri, 15 Jan 2021 22:05:35 +0200
Subject: [PATCH] fixed header while scrolling up

---
 .../menu-language/menu-language.tsx           | 12 ----
 .../hy-desktop-menu-links.scss                |  4 ++
 .../hy-desktop-menu-links.tsx                 | 11 +++-
 src/components/site-header/site-header.scss   | 17 ++++++
 src/components/site-header/site-header.tsx    | 59 +++++++++++++++++++
 5 files changed, 88 insertions(+), 15 deletions(-)

diff --git a/src/components/navigation/menu-language/menu-language.tsx b/src/components/navigation/menu-language/menu-language.tsx
index 8ce89f96..644f0d10 100644
--- a/src/components/navigation/menu-language/menu-language.tsx
+++ b/src/components/navigation/menu-language/menu-language.tsx
@@ -32,14 +32,6 @@ export class MenuLanguage {
     this._labels = typeof data === 'string' ? JSON.parse(data) : data;
   }
 
-  @Listen('languageMenuLeave') languageMenuLeave() {
-    this.isMenuOpen = false;
-  }
-
-  @Listen('languageMenuToggle') languageMenuToggle() {
-    //this.isMenuOpen = !this.isMenuOpen;
-  }
-
   @Listen('click')
   handleComponentClick(event) {
     this.isMenuOpen = !this.isMenuOpen;
@@ -89,16 +81,12 @@ export class MenuLanguage {
       </Host>
     ) : (
       <Host
-        //onMouseLeave={() => this.languageMenuLeave()}
         class={{
           'menu--language': true,
           'menu--language__is-open': this.isMenuOpen,
         }}
       >
         <button
-          //onClick={() => this.languageMenuToggle()}
-          //onMouseOver={() => this.languageMenuToggle()}
-          //onFocus={() => this.languageMenuToggle()}
           class={{
             'menu--language__toggle': true,
             'is-open': this.isMenuOpen,
diff --git a/src/components/site-header/hy-desktop-menu-links/hy-desktop-menu-links.scss b/src/components/site-header/hy-desktop-menu-links/hy-desktop-menu-links.scss
index 6b6c6e9f..0aa110e5 100644
--- a/src/components/site-header/hy-desktop-menu-links/hy-desktop-menu-links.scss
+++ b/src/components/site-header/hy-desktop-menu-links/hy-desktop-menu-links.scss
@@ -117,6 +117,10 @@
         right: 0;
         width: 100%;
       }
+
+      &:focus {
+        outline: none;
+      }
     }
 
     // Panel with second level menu items and shortcuts.
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 4bbdde51..baa2ac72 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
@@ -67,6 +67,10 @@ export class HyDesktopMenuLinks {
   }
 
   showPanel(id) {
+    // Close menu lang menu if it's open
+    //this.closeLangMenu();
+
+    // Open desktop menu panel
     this.isDesktopMenuOpen = true;
 
     const menuItems = this.el.shadowRoot.querySelectorAll(`.desktop-menu-link`);
@@ -102,9 +106,10 @@ export class HyDesktopMenuLinks {
     }
 
     // Add panels top value automatically with the correct header height
-    const headerHeight = `${
-      this.el.parentElement.offsetTop + this.el.parentElement.offsetHeight + this._headerBorderOffset
-    }px`;
+    const headerHeight = this.el.parentElement.classList.contains('hy-site-header--sticky-active')
+      ? `${this.el.parentElement.offsetHeight + this._headerBorderOffset}px`
+      : `${this.el.parentElement.offsetTop + this.el.parentElement.offsetHeight + this._headerBorderOffset}px`;
+    console.log(this.el.parentElement.offsetTop + ' ' + this.el.parentElement.offsetHeight);
     activeMenuItemSibling.style.top = headerHeight;
 
     // Add shadow backdrop
diff --git a/src/components/site-header/site-header.scss b/src/components/site-header/site-header.scss
index f303e264..46f01ee1 100644
--- a/src/components/site-header/site-header.scss
+++ b/src/components/site-header/site-header.scss
@@ -11,6 +11,23 @@
   place-content: center space-between;
   z-index: 99;
 
+  &--sticky-active {
+    transition: transform 200ms linear;
+    transform: translateY(-100%);
+    transition-duration: 0.2s;
+    transition-property: transform;
+    will-change: transform;
+  }
+  &--sticky-visible {
+    left: 0;
+    position: fixed;
+    transform: translateY(0) translateZ(0);
+    width: 100%;
+  }
+  &--sticky-hidden {
+    top: 0;
+  }
+
   @include breakpoint($narrow) {
     align-content: center;
     display: flex;
diff --git a/src/components/site-header/site-header.tsx b/src/components/site-header/site-header.tsx
index 56de89f5..d7b0e170 100644
--- a/src/components/site-header/site-header.tsx
+++ b/src/components/site-header/site-header.tsx
@@ -46,11 +46,24 @@ export class SiteHeader {
   private searchLabels: ComponentLabels[];
   private languageLabels: ComponentLabels[];
 
+  @State() lastScrollTop = 0;
+  @State() delta = 5;
+  @State() navbarHeight = 0;
+  @State() didScroll = false;
+  @State() intervalId;
+
   // Listener for toggling mobile menu panel on or off.
   @Listen('mobileMenuToggle') mobileMenuToggle() {
     this.isMenuOpen = !this.isMenuOpen;
   }
 
+  @Listen('scroll', {target: 'window'})
+  handleScroll() {
+    if (this.el.getAttribute('menu-type') === 'desktop') {
+      this.didScroll = true;
+    }
+  }
+
   componentDidLoad() {
     // Set the browser resize observer to gather information about browser width.
     this.ro = new ResizeObserver((entries) => {
@@ -62,6 +75,8 @@ export class SiteHeader {
 
     // Pass the dataMenuLanguage prop to menu component.
     this.el.children[0].setAttribute('data-menu-language', this.dataMenuLanguage);
+
+    this.navbarHeight = this.el.getClientRects()[0].height;
   }
 
   componentWillLoad() {
@@ -92,6 +107,50 @@ export class SiteHeader {
     this.el.children[0].setAttribute('menu-language-label-open', this.languageLabels['open']);
     this.el.children[0].setAttribute('menu-language-label-close', this.languageLabels['close']);
     this.el.children[0].setAttribute('label-front-page', this.menuLabels['front_page']);
+
+    //this.intervalId = setInterval(this.timer, 250);
+    //clearInterval(this.intervalId);
+    this.intervalId = setInterval(() => {
+      this.timer();
+    }, 250);
+    //console.log('willUpdate ' + this.intervalId);
+  }
+
+  timer() {
+    if (this.didScroll) {
+      this.hasScrolled();
+      this.didScroll = false;
+    }
+  }
+
+  hasScrolled() {
+    let st = window.pageYOffset;
+    if (Math.abs(this.lastScrollTop - st) <= this.delta) {
+      return;
+    }
+
+    let hySiteHeader = this.el.shadowRoot.querySelector('.hy-site-header') as HTMLElement;
+    // If current position > last position AND scrolled past navbar...
+    if (st > this.lastScrollTop && st > this.navbarHeight) {
+      // Scroll Down
+      console.log('scroll down');
+
+      hySiteHeader.classList.add('hy-site-header--sticky-active');
+      hySiteHeader.classList.add('hy-site-header--sticky-hidden');
+      hySiteHeader.classList.remove('hy-site-header--sticky-visible');
+    } else {
+      // Scroll Up
+      if (st < this.el.offsetTop + this.navbarHeight) {
+        hySiteHeader.classList.remove('hy-site-header--sticky-active');
+        hySiteHeader.classList.remove('hy-site-header--sticky-visible');
+        hySiteHeader.classList.remove('hy-site-header--sticky-hidden');
+      } else {
+        hySiteHeader.classList.add('hy-site-header--sticky-active');
+        hySiteHeader.classList.add('hy-site-header--sticky-visible');
+        hySiteHeader.classList.remove('hy-site-header--sticky-hidden');
+      }
+    }
+    this.lastScrollTop = st;
   }
 
   componentDidUnload() {
-- 
GitLab