Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(component): improve header overflow handling #4273

Merged
merged 16 commits into from
Jan 30, 2025
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/dull-actors-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@swisspost/design-system-components': minor
---

Improved main navigation overflow display.
19 changes: 0 additions & 19 deletions packages/components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,10 +508,6 @@ export interface PostLanguageOptionCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLPostLanguageOptionElement;
}
export interface PostMainnavigationCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLPostMainnavigationElement;
}
export interface PostMegadropdownCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLPostMegadropdownElement;
Expand Down Expand Up @@ -709,18 +705,7 @@ declare global {
prototype: HTMLPostLogoElement;
new (): HTMLPostLogoElement;
};
interface HTMLPostMainnavigationElementEventMap {
"postToggle": any;
}
interface HTMLPostMainnavigationElement extends Components.PostMainnavigation, HTMLStencilElement {
addEventListener<K extends keyof HTMLPostMainnavigationElementEventMap>(type: K, listener: (this: HTMLPostMainnavigationElement, ev: PostMainnavigationCustomEvent<HTMLPostMainnavigationElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof HTMLPostMainnavigationElementEventMap>(type: K, listener: (this: HTMLPostMainnavigationElement, ev: PostMainnavigationCustomEvent<HTMLPostMainnavigationElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
var HTMLPostMainnavigationElement: {
prototype: HTMLPostMainnavigationElement;
Expand Down Expand Up @@ -1158,10 +1143,6 @@ declare namespace LocalJSX {
"url"?: string | URL;
}
interface PostMainnavigation {
/**
* Gets emitted when a user closes the main navigation on mobile
*/
"onPostToggle"?: (event: PostMainnavigationCustomEvent<any>) => void;
}
interface PostMegadropdown {
/**
Expand Down
72 changes: 47 additions & 25 deletions packages/components/src/components/post-header/post-header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,32 @@
:host {
--global-header-height: 72px;
--global-header-minimal-height: 24px;
--main-header-height: 56px;
--main-header-min-height: 56px;
--header-height: calc(var(--global-header-height) + var(--main-header-height));
--local-header-height: 112px;
--local-header-min-height: 56px;
--header-height: calc(var(--global-header-height) + var(--local-header-height));

@include media.min(lg) {
display: block;
position: sticky;
inset-inline: 0;
inset-block-start: calc(
-1 * (var(--global-header-height) + var(--main-header-height) -
var(--global-header-minimal-height))
);
box-shadow: var(--post-core-elevation-3);
--global-header-reduced-height: 24px;
--main-navigation-height: 56px;
}

@include media.max(lg) {
--global-header-height: 64px;
--main-header-height: 48px;
--main-header-min-height: 48px;
--local-header-height: 48px;
--local-header-min-height: 48px;
--main-navigation-height: 0px;
}
}

:host(:not(:has([slot='title']))) {
--local-header-height: var(--main-navigation-height);

.local-header {
padding-block-start: 0;
}

.local-sub {
display: none;
}
}

Expand Down Expand Up @@ -56,7 +63,7 @@

@include media.min(lg) {
padding-inline-end: var(--post-core-dimension-12);
top: calc((var(--global-header-height) - var(--global-header-minimal-height)) * -1);
inset-block-start: calc((var(--global-header-height) - var(--global-header-reduced-height)) * -1);
}
}

Expand All @@ -78,7 +85,7 @@ slot[name='post-logo'] {
flex: 1 0 auto;
height: var(--global-header-height);
width: var(--global-header-height);
min-height: var(--global-header-minimal-height);
min-height: var(--global-header-reduced-height);
align-self: flex-end;

@include media.min(lg) {
Expand All @@ -95,41 +102,55 @@ slot[name='post-logo'] {
flex-shrink: 0 !important;
}

.title-header {
.local-header {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--post-core-dimension-8);
min-height: var(--main-header-min-height);
justify-content: space-between;
gap: var(--post-core-dimension-8);
min-height: var(--local-header-min-height);
background: var(--post-core-color-brand-white);

@include media.min(lg) {
padding: var(--post-core-dimension-18) var(--post-core-dimension-16)
var(--post-core-dimension-4) var(--post-core-dimension-12);
position: sticky;
inset-block-start: calc(-1 * (var(--local-header-height) - var(--main-navigation-height)) + var(--global-header-reduced-height));
padding-block-start: var(--post-core-dimension-18);
box-shadow: var(--post-core-elevation-3);
}

@include media.max(lg) {
position: sticky;
z-index: 1;
inset-block-start: var(--global-header-height);
padding-inline: var(--post-core-dimension-8) var(--post-core-dimension-16);
padding-block: var(--post-core-dimension-9);
flex-wrap: wrap;

&.title-header-mobile-extended {
&.local-header-mobile-extended {
border-bottom: 1px solid var(--post-core-color-sandgrey-012);
}
}
}

:host(:not(:has([slot='title']))) .title-header {
display: none;
.local-sub {
margin-inline-end: var(--post-core-dimension-16);

::slotted(.list-inline) {
margin: 0 !important;
}
}

::slotted(h1) {
margin: 0 !important;
flex-shrink: 10;

@include media.min(sm) {
margin-inline-start: var(--post-core-dimension-12) !important;
}

@include media.max(sm) {
margin-inline-start: var(--post-core-dimension-8) !important;
}

@include media.min(lg) {
font-size: var(--post-core-font-size-28) !important;
}
Expand All @@ -147,12 +168,13 @@ slot[name='post-logo'] {
}

.navigation {
width: 100%;
background: var(--post-core-color-brand-white);

@include media.min(lg) {
position: sticky;
z-index: 1;
inset-block-start: var(--global-header-minimal-height);
inset-block-start: var(--global-header-reduced-height);
}
}

Expand Down
35 changes: 21 additions & 14 deletions packages/components/src/components/post-header/post-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export class PostHeader {
this.mobileMenuAnimation.finish(); // no animation
}

const mhh = this.host.shadowRoot.querySelector('.title-header')?.clientHeight;
const mhh = this.host.shadowRoot.querySelector('.local-header')?.clientHeight;
this.host.style.setProperty('--main-header-height', `${mhh}px`);

// Apply only on change for doing work only when necessary
Expand All @@ -212,12 +212,27 @@ export class PostHeader {
this.host.querySelector('post-language-switch')?.setAttribute('variant', variant);
}

render() {
private renderNavigation() {
const navigationClasses = ['navigation'];
if (this.mobileMenuExtended) {
navigationClasses.push('extended');
}

return (
<div ref={el => (this.mobileMenu = el)} class={navigationClasses.join(' ')}>
<slot name="post-mainnavigation"></slot>

{(this.device === 'mobile' || this.device === 'tablet') && (
<div class="navigation-footer">
<slot name="meta-navigation"></slot>
<slot name="post-language-switch"></slot>
</div>
)}
</div>
);
}

render() {
return (
<Host version={version}>
<div class="global-header">
Expand All @@ -236,24 +251,16 @@ export class PostHeader {
</div>
</div>
<div
class={'title-header ' + (this.mobileMenuExtended ? 'title-header-mobile-extended' : '')}
class={'local-header ' + (this.mobileMenuExtended ? 'local-header-mobile-extended' : '')}
>
<slot name="title"></slot>
<div class="global-sub">
<div class="local-sub">
<slot name="local-controls"></slot>
<slot></slot>
</div>
{this.device === 'desktop' && this.renderNavigation()}
</div>
<div ref={el => (this.mobileMenu = el)} class={navigationClasses.join(' ')}>
<slot name="post-mainnavigation"></slot>

{(this.device === 'mobile' || this.device === 'tablet') && (
<div class="navigation-footer">
<slot name="meta-navigation"></slot>
<slot name="post-language-switch"></slot>
</div>
)}
</div>
{this.device !== 'desktop' && this.renderNavigation()}
</Host>
);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/components/src/components/post-icon/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ some content
- [post-card-control](../post-card-control)
- [post-closebutton](../post-closebutton)
- [post-language-switch](../post-language-switch)
- [post-mainnavigation](../post-mainnavigation)
- [post-rating](../post-rating)
- [post-tag](../post-tag)

Expand All @@ -44,6 +45,7 @@ graph TD;
post-card-control --> post-icon
post-closebutton --> post-icon
post-language-switch --> post-icon
post-mainnavigation --> post-icon
post-rating --> post-icon
post-tag --> post-icon
style post-icon fill:#f9f,stroke:#333,stroke-width:4px
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
@use '@swisspost/design-system-styles/variables/animation';
@use '@swisspost/design-system-styles/components/header/mixins' as header-mx;

$nav-height: var(--post-core-dimension-56);

post-mainnavigation {
flex: 0 0 auto;

// reset links and buttons
post-list-item {
> a {
Expand All @@ -24,8 +24,9 @@ post-mainnavigation {
}

> a,
> button,
post-megadropdown-trigger button {
flex: 0 0 fit-content;
white-space: nowrap;
display: flex;
align-items: center;
justify-content: space-between;
Expand Down Expand Up @@ -57,11 +58,44 @@ post-mainnavigation {

// desktop styles
@include media.min(lg) {
display: block;

nav {
position: relative;
max-width: 100vw;
max-height: $nav-height;
max-height: var(--main-navigation-height);
user-select: none;
transition: transform animation.$transition-base-timing;
}

.left-scroll-button,
.right-scroll-button {
position: absolute;
inset-block: 0;
overflow: hidden;

button {
@include button.reset-button;
background: var(--post-core-color-brand-white);
padding: var(--post-core-dimension-16);
box-shadow: var(--post-core-elevation-5);
line-height: var(--post-core-line-height-100);
Comment on lines +79 to +82
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I once more recommend: Never use core- or semantic-tokens, but instead use hardcoded values for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First time with me!
Can we discuss this? Currently the whole header is using semantic tokens and I would like to understand why you prefer raw values. Also, I would rather handle this in a separate ticket as it would involve a lot of changes not related to this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, I didn't mean I told you this already in particular, but I keep telling it to everyone that uses something else than component tokens 😉
I've added a DEV Discussion in the daily chat.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conclusion from our discussion during the todays daily meeting: Avoid using core tokens, instead use sass varialbes (or if avilable use component tokens).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, most of these tokens could probably being replaced with utility tokens. Which would be ok for me.

@use '@swisspost/design-system-styles/core' as post;
@use '@swisspost/design-system-styles/functions/tokens';
@use '@swisspost/design-system-styles/mixins/utilities';

button {
  background: post.$white;
  padding: tokens.get('utility.padding.16', utilities.$post-spacing);
  box-shadow: tokens.get('utility.elevation.500', utilities.$post-elevation);
  line-height: tokens.get('utility.line-height.1', utilities.$ost-typo);
}

height: 100%;

post-icon {
font-size: 1rem;
}
}
}

.left-scroll-button {
inset-inline-start: 0;
padding-inline-end: 2rem;
}

.right-scroll-button {
inset-inline-end: 0;
padding-inline-start: 2rem;
}

post-list {
Expand All @@ -79,7 +113,7 @@ post-mainnavigation {
> button,
post-megadropdown-trigger button {
padding-inline: var(--post-core-dimension-12);
height: $nav-height;
height: var(--main-navigation-height);
gap: var(--post-core-dimension-4);
font-size: var(--post-core-font-size-16);
border-block: 0 solid transparent;
Expand Down Expand Up @@ -135,10 +169,15 @@ post-mainnavigation {

// tablet/mobile styles
@include media.max(lg) {
post-list > [role='list'] {
nav {
transform: none !important;
}

.left-scroll-button,
.right-scroll-button {
display: none;
}

post-list-item {
> a,
> button,
Expand Down
Loading
Loading