diff --git a/package.json b/package.json index 0d9ac6f8bc6cdace7361203f7fc4fac69d50bd42..d424ca8f30c6d9c251a1e2e7b19b129fdd5c58cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@itcenteratunihelsinki/huds-lib", - "version": "0.0.71", + "version": "0.0.72", "description": "Helsinki University Design System library", "main": "dist/index.js", "module": "dist/index.mjs", diff --git a/src/components.d.ts b/src/components.d.ts index 668ae9da32cd87c760bd51cfd83d49a86f0462a2..ed8f66b6f7890ff5f0694b637d89b0f37c24afa0 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -2039,6 +2039,7 @@ declare namespace LocalJSX { menuLabelClose?: string; menuLabelOpen?: string; menuType?: MenuType; + onHeaderScrollUp?: (event: CustomEvent<any>) => void; } interface HySiteLogo { color?: ColorVariant; diff --git a/src/components/navigation/menu-language/menu-language.tsx b/src/components/navigation/menu-language/menu-language.tsx index ed0386d3465febec4893f8625cdcde3d9d50a4fc..60d8c8f21f6d7fdc861324082f7b34a2b3bedec8 100644 --- a/src/components/navigation/menu-language/menu-language.tsx +++ b/src/components/navigation/menu-language/menu-language.tsx @@ -67,14 +67,10 @@ export class MenuLanguage { this.menuLanguageToggled.emit(); let hyHeader = this.el.closest('.hy-site-header') as HTMLElement; - const headerHeight = `${ - languageMenuSelector.offsetHeight + - hyHeader.offsetTop + - hyHeader.offsetHeight + - 8 - - languageMenuSelector.offsetTop - - languageMenuSelector.offsetHeight - }px`; + let rectHeader = hyHeader.getBoundingClientRect(); + let rectLangMenu = languageMenuSelector.getBoundingClientRect(); + + const headerHeight = `${languageMenuSelector.offsetHeight + rectHeader.bottom + 8 - rectLangMenu.bottom}px`; const languagePanel = languageMenuSelector.shadowRoot.querySelectorAll( `.menu--language__dropdown` )[0] as HTMLElement; 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 79c57ecaaa987885f29b1b7b29191f343161b42e..a17bbe74a2a66780a5d3a95f758dd7ee79fc666f 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 @@ -79,10 +79,16 @@ } hy-icon { - display: inline-block !important; - padding-left: 3px; + //display: inline-block !important; + display: flex; + height: 8px; + margin-left: 3px; + width: 10px; + @include breakpoint($xlarge) { - padding-left: 4px; + height: 8.44px; + margin-left: 4px; + width: 12px; } svg { @@ -98,7 +104,7 @@ // On hover: heading icon is turned 180deg and grows bigger. &--is-active { - position: relative; + //position: relative; &:hover, &:focus { color: var(--link-blue); @@ -157,7 +163,14 @@ border: none; position: absolute; right: 10px; - top: 10px; + top: 0; + + @include breakpoint($extrawide) { + padding: 22px 32px 17px 32px; + } + @include breakpoint($xlarge) { + padding: 30px 32px 30px 32px; + } &__label { @include font-size(18px, 22px); @@ -197,11 +210,6 @@ &:focus { box-shadow: 0 0 16px 0 rgba(0, 83, 121, 0.2); color: var(--link-blue); - - svg { - //height: 42px; - //width: 42px; - } } @include breakpoint($extrawide) { 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 7b40f935f0fb1e6e83147646d58e4bf592210fb7..35bd9d81615a0b919596bbf2c0cef6edfc857c06 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 @@ -21,6 +21,7 @@ export interface DesktopLinks { import {ColorVariant} from '../../../utils/utils'; import {Component, h, Element, Prop, State, Watch, EventEmitter, Event, Listen} from '@stencil/core'; +import ResizeObserver from 'resize-observer-polyfill'; @Component({ tag: 'hy-desktop-menu-links', @@ -48,6 +49,8 @@ export class HyDesktopMenuLinks { private _hoverTimer = null; private _fadeOutTimer = null; + private ro: ResizeObserver; + @Watch('dataDesktopLinks') dataDesktopLinksWatcher(data: DesktopLinks[] | string) { this._dataDesktopLinks = typeof data === 'string' ? JSON.parse(data) : data; @@ -57,16 +60,27 @@ export class HyDesktopMenuLinks { this.dataDesktopLinksWatcher(this.dataDesktopLinks); } + removeBackdropShadow(size: number) { + // Close backdrop shadow if the screen is < 1200px + if (size < 1200) { + this.showBackdropShadow(); + } + } + showBackdropShadow(state = 'close', top = 0) { let hyHeader = this.el.closest('.hy-site-header') as HTMLElement; let hyBackdropDiv = hyHeader.children[0] as HTMLElement; if (hyBackdropDiv) { if (state === 'open') { - hyBackdropDiv.classList.add('is-active'); + let me = window.outerHeight - top; + hyBackdropDiv.style.height = `${me}px`; hyBackdropDiv.style.top = `${top}px`; + hyBackdropDiv.style.position = 'absolute'; + hyBackdropDiv.classList.add('is-active'); + //console.log(document.body.clientHeight + ' ' + window.outerHeight + ' ' + top); } else { - hyBackdropDiv.style.top = '0'; + hyBackdropDiv.removeAttribute('style'); hyBackdropDiv.classList.remove('is-active'); } } @@ -125,11 +139,14 @@ export class HyDesktopMenuLinks { // Add shadow backdrop let rect = activeMenuItemSibling.getBoundingClientRect(); - this.showBackdropShadow('open', rect.bottom); + //this.showBackdropShadow('open', rect.bottom); + let shadowTop = this.el.parentElement.classList.contains('hy-site-header--sticky-active') + ? this.el.parentElement.offsetHeight + this._headerBorderOffset + rect.height + : this.el.parentElement.offsetTop + this.el.parentElement.offsetHeight + this._headerBorderOffset + rect.height; + this.showBackdropShadow('open', shadowTop); // Position submenu block under the activated top menu item. - let activeButtonRect = activeMenuItem.getBoundingClientRect(); - const menuPanelLeftPosition = activeButtonRect.left - this._submenuLeftMargin; + const menuPanelLeftPosition = activeMenuItem.offsetLeft - this._submenuLeftMargin; activeMenuItemSibling.style.paddingLeft = `${menuPanelLeftPosition}px`; // Position shortcuts block. @@ -214,6 +231,13 @@ export class HyDesktopMenuLinks { this.closePanel(fadeOut); } + // CLose the desktop menu panel if user scrolls Sticky Header till the very top. + @Listen('headerScrollUp', {target: 'document'}) + headerScrollUp() { + let fadeOut = false; + this.closePanel(fadeOut); + } + handleDesktopMenuEnter(event, id) { clearTimeout(this._fadeOutTimer); @@ -236,7 +260,6 @@ export class HyDesktopMenuLinks { let hyHeader = this.el.closest('.hy-site-header') as HTMLElement; const headerHeight = hyHeader.offsetTop + hyHeader.offsetHeight; - console.log('leave ' + leaveEvent.clientY + ' ' + headerHeight); if (leaveEvent.clientY < headerHeight - 4) { this.closePanel(); } @@ -258,8 +281,7 @@ export class HyDesktopMenuLinks { if (this.currenOpenMenuId == id) { // Mouse moving around the same menu link - if (moveEvent.clientY < topBorder - 8) { - console.log(topBorder + ' ' + moveEvent.clientY); + if (moveEvent.clientY < topBorder - 4) { this.closePanel(); } } @@ -289,6 +311,14 @@ export class HyDesktopMenuLinks { } componentDidLoad() { + // Set the browser resize observer to gather information about browser width. + this.ro = new ResizeObserver((entries) => { + for (const entry of entries) { + this.removeBackdropShadow(entry.contentRect.width); + } + }); + this.ro.observe(document.body); + let hyToolbar = document.querySelectorAll('#toolbar-administration')[0]; if (hyToolbar) { this.hasToolbar = true; diff --git a/src/components/site-header/readme.md b/src/components/site-header/readme.md index 3436d38d4374540bb1aa4295fb77fd3e733b0e2c..b1e105e5db393afca0118d046713ce057b6b2504 100644 --- a/src/components/site-header/readme.md +++ b/src/components/site-header/readme.md @@ -17,6 +17,12 @@ | `menuLabelOpen` | `menu-label-open` | | `string` | `undefined` | | `menuType` | `menu-type` | | `MenuType.desktop \| MenuType.mobile \| MenuType.sidenav \| MenuType.sidepanel \| MenuType.tablet` | `MenuType.default` | +## Events + +| Event | Description | Type | +| ---------------- | ----------- | ------------------ | +| `headerScrollUp` | | `CustomEvent<any>` | + ## Dependencies ### Depends on diff --git a/src/components/site-header/site-header.scss b/src/components/site-header/site-header.scss index e55a3ac5a0f27f4f2ac02349cb57e83140b5a882..26292ff750eaf43096feda54e00f2b5b17ebd925 100644 --- a/src/components/site-header/site-header.scss +++ b/src/components/site-header/site-header.scss @@ -21,8 +21,10 @@ &--sticky-visible { left: 0; position: fixed; + right: 0; transform: translateY(0) translateZ(0); - width: 100%; + //width: 100%; + width: inherit; //?? } &--sticky-hidden { top: 0; @@ -165,6 +167,7 @@ background-color: rgba(0, 0, 0, 0.4); transition: background-color 300ms; visibility: visible; + width: inherit; //?? z-index: 99; } } diff --git a/src/components/site-header/site-header.tsx b/src/components/site-header/site-header.tsx index d6dec40165ac7f86f582216791674c1586c41b4a..3cb0d93b536d177b7beb2f588cda05fb24f2ac53 100644 --- a/src/components/site-header/site-header.tsx +++ b/src/components/site-header/site-header.tsx @@ -14,7 +14,7 @@ export interface ComponentLabels { label?: string; } -import {Component, Element, h, Listen, Prop, State} from '@stencil/core'; +import {Component, Element, Event, EventEmitter, h, Listen, Prop, State} from '@stencil/core'; import ResizeObserver from 'resize-observer-polyfill'; import {MenuType, ColorVariant, SiteLogoSize} from '../../utils/utils'; @@ -41,6 +41,8 @@ export class SiteHeader { @State() isMobile: boolean; @State() isMenuOpen: boolean = false; @State() isDesktopMenuOpen: boolean = false; + + @Event() headerScrollUp: EventEmitter; private ro: ResizeObserver; private donateLink: DonateLink[]; private menuLabels: ComponentLabels[]; @@ -131,7 +133,6 @@ export class SiteHeader { // If current position > last position AND scrolled past navbar... if (st > this.lastScrollTop && st > this.navbarHeight) { // 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'); @@ -141,10 +142,13 @@ export class SiteHeader { hySiteHeader.classList.remove('hy-site-header--sticky-active'); hySiteHeader.classList.remove('hy-site-header--sticky-visible'); hySiteHeader.classList.remove('hy-site-header--sticky-hidden'); + + // Close desktop menu panel if it's open. + this.headerScrollUp.emit(); } 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'); + hySiteHeader.classList.add('hy-site-header--sticky-visible'); } } this.lastScrollTop = st;