Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/stupid-pianos-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@swisspost/internet-header': minor
---

Updated the logo size, the post logo now spans the meta-navigation and scales down on scroll.
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ const Template = (args: Args) => {
<swisspost-internet-header {...filteredArgs} />
<main className="container mt-huge-r">
<swisspost-internet-breadcrumbs />
<h1 className="mt-huge-r mb-big-r bold">CWF Internet Header</h1>
<h1 className="mt-huge-r mb-big-r bold">Design System Internet Header</h1>
<p className="fake-content my-big"></p>
<p className="fake-content my-big"></p>
<p className="fake-content my-big"></p>
Expand Down
4 changes: 2 additions & 2 deletions packages/internet-header/cypress/e2e/header.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ describe('header', () => {
cy.get('swisspost-internet-header').should('have.class', 'hydrated');
});

it(`has title 'CWF Internet Header'`, () => {
cy.get('h1').should('contain.text', 'CWF Internet Header');
it(`has title 'Design System Internet Header'`, () => {
cy.get('h1').should('contain.text', 'Design System Internet Header');
});

it(`has nav item 'Briefe versenden' selected`, () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@use '../../../utils/mixins.scss';

/**
* Default position: scrolled
* Logo is being scaled up for the initial view (scrollY = 0). This enables media queries to override
* mobile behaviour without re-calculation
*/
:host {
--logo-scale: 1;

@include mixins.max(lg) {
--logo-scale: 1 !important;
}
}

post-logo {
height: var(--header-height);
transform-origin: bottom left;
transform: scale(var(--logo-scale));
Comment thread
gfellerph marked this conversation as resolved.
}

post-main-navigation {
margin-left: calc((var(--header-height) * var(--logo-scale)) - var(--header-height));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { debounce } from 'throttle-debounce';
import { state } from '../../../data/store';

export const registerLogoAnimationObserver = (
target: HTMLElement,
headerRef: HTMLSwisspostInternetHeaderElement,
) => {
/**
* Set intersection ratio as CSS custom property
*/
const handleScroll = () => {
const fullStickyness = state.stickyness === 'full';
let scale = 1;
// Minus 1px border at the bottom that the logo is not covering
const adjustedHeaderHeight = headerRef.clientHeight - 1;
const scrollY = fullStickyness ? 0 : window.scrollY;

// If meta navigation is not visible (mobile, not configured), scale should just be 1
if (target.clientHeight > 0) {
scale = Math.max(
(adjustedHeaderHeight - Math.max(scrollY, 0)) /
(adjustedHeaderHeight - target.clientHeight),
1,
);
}
headerRef.style.setProperty('--logo-scale', scale.toString());
};

const debounced = debounce(150, handleScroll);
Comment thread
oliverschuerch marked this conversation as resolved.

/**
* Observe the meta navigation in order to not track scroll events throughout the whole page.
* This ensures that the scroll listener is only active while the meta navigation is visible.
*/
const observer = new IntersectionObserver(
Comment thread
gfellerph marked this conversation as resolved.
entries => {
entries.forEach(entry => {
if (entry.isIntersecting && entry.intersectionRatio > 0) {
window.addEventListener('scroll', handleScroll, { passive: true });
window.addEventListener('resize', debounced);

// Ensure callback is called at least once in case main thread is too busy while scrolling up
window.requestAnimationFrame(handleScroll);
} else {
window.removeEventListener('scroll', handleScroll);
window.removeEventListener('resize', debounced);
window.requestAnimationFrame(handleScroll);
}
});
},
{
// Fires when element leaves viewport (0) and when it just about enters it (0.001)
threshold: [0, 0.001],
},
);
observer.observe(target);

return handleScroll;
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@use '@swisspost/design-system-styles/variables/color';
@use '../../utils/utils.scss';
@use '../../utils/mixins.scss';
@use './logo-animation/logo-animation.scss';

:host {
display: block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { IAvailableLanguage } from '../../models/language.model';
import { translate } from '../../services/language.service';
import { If } from '../../utils/if.component';
import packageJson from '../../../package.json';
import { registerLogoAnimationObserver } from './logo-animation/logo-animation';

@Component({
tag: 'swisspost-internet-header',
Expand Down Expand Up @@ -123,7 +124,7 @@ export class PostInternetHeader {

@State() activeFlyout: string | null = null;
@State() activeDropdownElement: DropdownElement | null = null;
@Element() host: HTMLElement;
@Element() host: HTMLSwisspostInternetHeaderElement;

/**
* Get the currently set language as a two letter string ("de", "fr" "it" or "en")
Expand All @@ -135,10 +136,12 @@ export class PostInternetHeader {
}

private mainNav?: HTMLPostMainNavigationElement;
private metaNav?: HTMLPostMetaNavigationElement;
private lastScrollTop = window.scrollY || document.documentElement.scrollTop;
private throttledScroll: throttle<() => void>;
private debouncedResize: debounce<() => void>;
private lastWindowWidth: number = window.innerWidth;
private updateLogoAnimation: () => void;

constructor() {
if (this.project === undefined || this.project === '' || !isValidProjectId(this.project)) {
Expand Down Expand Up @@ -167,6 +170,7 @@ export class PostInternetHeader {
// Wait for the config to arrive, then render the header
try {
state.projectId = this.project;
state.stickyness = this.stickyness;
state.environment = this.environment.toLocaleLowerCase() as Environment;
if (this.language !== undefined) state.currentLanguage = this.language;
state.languageSwitchOverrides =
Expand Down Expand Up @@ -205,6 +209,9 @@ export class PostInternetHeader {
this.handleResize();
this.headerLoaded.emit();
this.host.classList.add('header-loaded');
if (this.meta && this.metaNav) {
this.updateLogoAnimation = registerLogoAnimationObserver(this.metaNav, this.host);
}
});

if (this.stickyness === 'full')
Expand Down Expand Up @@ -299,6 +306,12 @@ export class PostInternetHeader {
this.handleLanguageChange(event.detail);
}

@Watch('stickyness')
handleStickynessChange(newValue: StickynessOptions) {
state.stickyness = newValue;
this.updateLogoAnimation();
}

private handleClickOutsideBound = this.handleClickOutside.bind(this);

private handleClickOutside(event: Event) {
Expand Down Expand Up @@ -439,6 +452,7 @@ export class PostInternetHeader {
orientation="horizontal"
class="hidden-lg"
full-width={this.fullWidth}
ref={el => (this.metaNav = el)}
Comment thread
gfellerph marked this conversation as resolved.
>
<If condition={renderLanguageSwitch === true}>
<post-language-switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
align-self: stretch;

&::before {
position: relative;
content: '';
display: var(--separator-display);
height: var(--separator-height);
border-left: 1px solid color.$gray-10;
content: '';
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

:host {
display: block;
aspect-ratio: 1/1;
}

.logo {
Expand All @@ -13,7 +14,7 @@

svg {
display: block;
width: var(--header-height);
height: var(--header-height);
width: 100%;
height: 100%;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Component, Host, h, State, Element } from '@stencil/core';
import { throttle } from 'throttle-debounce';
import { Component, Host, h, Element } from '@stencil/core';
import { state } from '../../data/store';

@Component({
Expand All @@ -8,40 +7,7 @@ import { state } from '../../data/store';
shadow: true,
})
export class PostLogo {
@State() showFaviconLogo: boolean;
@Element() host: HTMLPostLogoElement;
private throttledResize: throttle<() => void>;
private resizeObserver: ResizeObserver;

constructor() {
// Register window resize event listener and a resize observer on the mainnav controls (they change size while controls are being loaded) to display an accurately sized logo
this.throttledResize = throttle(300, () => this.handleResize());
window.addEventListener('resize', this.throttledResize, { passive: true });
this.resizeObserver = new ResizeObserver(this.handleResize.bind(this));

// Initially call the resize handler
this.handleResize();
}

componentDidLoad() {
const mainNavControls = this.host.parentElement?.querySelector('.main-navigation-controls');
if (mainNavControls) {
this.resizeObserver.observe(mainNavControls);
}
}

disconnectedCallback() {
window.removeEventListener('resize', this.throttledResize);
this.resizeObserver.disconnect();
}

handleResize() {
const mainNavControls = this.host.parentElement?.querySelector('.main-navigation-controls');
const menuButton = this.host.parentElement?.querySelector('.menu-button');
if (mainNavControls && menuButton)
this.showFaviconLogo =
window.innerWidth - (150 + mainNavControls.clientWidth + menuButton.clientWidth) <= 0;
}

render() {
if (state.localizedConfig?.header.logo === undefined) return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
@use "@swisspost/design-system-styles/variables/color";
@use "@swisspost/design-system-styles/functions";
@use "../../utils/utils.scss";
@use "../../utils/mixins.scss";
@use '@swisspost/design-system-styles/variables/color';
@use '@swisspost/design-system-styles/functions';
@use '../../utils/utils.scss';
@use '../../utils/mixins.scss';

:host {
display: block;
background: color.$gray-background-light;
font-size: functions.px-to-rem(14px);
}

Expand All @@ -15,6 +14,8 @@
align-items: center;
min-height: functions.px-to-rem(48px);

background: color.$gray-background-light;

@media (min-width: 1441px) {
&:not(.full-width) {
margin: 0 auto;
Expand All @@ -40,11 +41,23 @@
--separator-display: block;
--separator-height: #{functions.px-to-rem(34px)};
}

&::before {
display: block;
content: '';
Comment thread
gfellerph marked this conversation as resolved.
position: absolute;
top: 0px;
height: var(--meta-header-height);
background-color: color.$gray-background-light;
left: 50%;
width: 50%;
}
}
}

.meta-navigation {
.horizontal & {
position: relative;
padding-right: 1rem;
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/internet-header/src/data/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createStore } from '@stencil/store';
import { Environment, ILocalizedConfig, ILocalizedCustomConfig } from '../models/general.model';
import { NavMainEntity } from '../models/header.model';
import { IAvailableLanguage } from '../models/language.model';
import { StickynessOptions } from '../components';

export interface HeaderState {
localizedConfig: ILocalizedConfig | null;
Expand All @@ -14,6 +15,7 @@ export interface HeaderState {
languageSwitchOverrides?: IAvailableLanguage[];
localizedCustomConfig?: ILocalizedCustomConfig;
osFlyoutOverrides?: NavMainEntity;
stickyness: StickynessOptions;
}

export const { state, reset, dispose } = createStore<HeaderState>({
Expand All @@ -24,4 +26,5 @@ export const { state, reset, dispose } = createStore<HeaderState>({
search: true,
login: true,
meta: true,
stickyness: 'minimal',
});