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