From cf081ce55ddc35d09dfae9ac53ab7cfa80cf660b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aliz=C3=A9=20Debray?=
<33580481+alizedebray@users.noreply.github.com>
Date: Thu, 11 Jul 2024 11:37:54 +0200
Subject: [PATCH] feat(internet-header): expose CSS custom properties (#3200)
Co-authored-by: Philipp Gfeller <1659006+gfellerph@users.noreply.github.com>
---
.changeset/flat-gifts-report.md | 6 ++++
.../.storybook/styles/preview.scss | 1 +
.../header-css-variables.docs.mdx | 17 ++++++++++
.../header-css-variables.stories.ts | 32 +++++++++++++++++++
.../internet-header/internet-header.docs.mdx | 22 +++++++++++--
packages/internet-header/package.json | 2 +-
.../post-internet-header.scss | 17 ++++------
.../post-internet-header.tsx | 6 ++++
packages/internet-header/src/root.scss | 8 +++++
.../internet-header/src/utils/mixins.scss | 32 +++++++++++++++++++
.../internet-header/src/utils/variables.scss | 21 ++++++++++++
.../internet-header/stencil.config.dev.ts | 13 ++++++++
packages/internet-header/stencil.config.ts | 2 +-
13 files changed, 164 insertions(+), 15 deletions(-)
create mode 100644 .changeset/flat-gifts-report.md
create mode 100644 packages/documentation/src/stories/components/internet-header/header/overrides-stories/header-css-variables.docs.mdx
create mode 100644 packages/documentation/src/stories/components/internet-header/header/overrides-stories/header-css-variables.stories.ts
create mode 100644 packages/internet-header/src/root.scss
create mode 100644 packages/internet-header/src/utils/variables.scss
create mode 100644 packages/internet-header/stencil.config.dev.ts
diff --git a/.changeset/flat-gifts-report.md b/.changeset/flat-gifts-report.md
new file mode 100644
index 0000000000..266c7f488b
--- /dev/null
+++ b/.changeset/flat-gifts-report.md
@@ -0,0 +1,6 @@
+---
+'@swisspost/internet-header': minor
+'@swisspost/design-system-documentation': minor
+---
+
+Added a new stylesheet containing `:root` CSS custom properties to facilitate implementing styles relative to the header. This will allow putting sticky content right below the header.
diff --git a/packages/documentation/.storybook/styles/preview.scss b/packages/documentation/.storybook/styles/preview.scss
index 1b2cf39544..5eaa9141e8 100644
--- a/packages/documentation/.storybook/styles/preview.scss
+++ b/packages/documentation/.storybook/styles/preview.scss
@@ -3,6 +3,7 @@
@use '@swisspost/design-system-styles/intranet.scss';
@use '@swisspost/design-system-styles/core.scss' as post;
@use '@swisspost/design-system-styles/mixins/utilities';
+@use '@swisspost/internet-header/dist/swisspost-internet-header/swisspost-internet-header.css';
@use './components';
#storybook-root,
diff --git a/packages/documentation/src/stories/components/internet-header/header/overrides-stories/header-css-variables.docs.mdx b/packages/documentation/src/stories/components/internet-header/header/overrides-stories/header-css-variables.docs.mdx
new file mode 100644
index 0000000000..a93f37dfbe
--- /dev/null
+++ b/packages/documentation/src/stories/components/internet-header/header/overrides-stories/header-css-variables.docs.mdx
@@ -0,0 +1,17 @@
+import { Meta, Canvas, Controls } from '@storybook/blocks';
+import * as HeaderStories from './header-css-variables.stories';
+import '../header.scss';
+
+
+
+
+
Internet Header CSS Variables
+
When you need to implement styling relative to the header.
+
+
+
+
+## Style Imports
+
+To access the CSS variables for the header, you need to install an optional stylesheet into your project.
+Learn more in the header CSS variables stylesheet documentation.
diff --git a/packages/documentation/src/stories/components/internet-header/header/overrides-stories/header-css-variables.stories.ts b/packages/documentation/src/stories/components/internet-header/header/overrides-stories/header-css-variables.stories.ts
new file mode 100644
index 0000000000..7bb135c8e2
--- /dev/null
+++ b/packages/documentation/src/stories/components/internet-header/header/overrides-stories/header-css-variables.stories.ts
@@ -0,0 +1,32 @@
+import meta from '@/stories/components/internet-header/header/header.stories';
+import * as HeaderStories from '@/stories/components/internet-header/header/header.stories';
+import { Args } from '@storybook/web-components';
+import { html } from 'lit';
+
+export default {
+ ...HeaderStories.default,
+ id: 'bfdf4e7c-37d3-40f8-a5d0-734f3e6612b5',
+ title: 'Components/Internet Header/Header/CSS Variables',
+};
+
+export const Default = {
+ render: (args: Args, context: any) => {
+ return html`
+
+ ${meta.render && meta.render(args, context)}
+
+ I am sticky! I am always positioned right below the header when you scroll up and down.
+
+ `;
+ },
+};
diff --git a/packages/documentation/src/stories/getting-started/packages/internet-header/internet-header.docs.mdx b/packages/documentation/src/stories/getting-started/packages/internet-header/internet-header.docs.mdx
index 01df1a5d20..2639b1b6fb 100644
--- a/packages/documentation/src/stories/getting-started/packages/internet-header/internet-header.docs.mdx
+++ b/packages/documentation/src/stories/getting-started/packages/internet-header/internet-header.docs.mdx
@@ -21,9 +21,11 @@ import { SourceDarkMode } from '@/../.storybook/preview';
The header for client-facing applications.
## Preparation
@@ -99,6 +101,22 @@ Available CDNs:
+## CSS Variables
+
+The internet header package provides a stylesheet aimed at facilitating the use of key CSS variables beyond the header itself.
+This stylesheet allows you to access CSS variables to implement styling relative to the header as needed, but it is completely optional.
+
+
+ Sass Import
+
+
+
+ HTML Import
+
+ `} dark={SourceDarkMode} language="html" />
+
+
+
## Usage with Angular
For Angular user, please have a look at [How to integrate Web Components inside Angular](/?path=/docs/8426deb2-3d6d-4fcc-90e6-1ca9737b2ed0--docs#usage-of-web-components)
diff --git a/packages/internet-header/package.json b/packages/internet-header/package.json
index 8368897950..c0b5beea10 100644
--- a/packages/internet-header/package.json
+++ b/packages/internet-header/package.json
@@ -27,7 +27,7 @@
"loader/"
],
"scripts": {
- "dev": "stencil build --serve --port 9310 --watch --docs-readme --dev",
+ "dev": "stencil build --serve --port 9310 --watch --docs-readme --dev --config stencil.config.dev.ts",
"start": "stencil build --watch --docs-readme",
"build": "stencil build --docs-readme",
"clean": "rimraf www dist loader",
diff --git a/packages/internet-header/src/components/post-internet-header/post-internet-header.scss b/packages/internet-header/src/components/post-internet-header/post-internet-header.scss
index beed680f81..6c32f688e2 100644
--- a/packages/internet-header/src/components/post-internet-header/post-internet-header.scss
+++ b/packages/internet-header/src/components/post-internet-header/post-internet-header.scss
@@ -2,6 +2,7 @@
@use '@swisspost/design-system-styles/placeholders/color' as color-ph;
@use '../../utils/utils.scss';
@use '../../utils/mixins.scss';
+@use '../../utils/variables.scss';
@use './logo-animation/logo-animation.scss';
:host {
@@ -13,18 +14,10 @@
font-weight: 300;
z-index: var(--header-z-index, 10);
- --header-height: 3.5rem; // 56px
- --meta-header-height: 0px; // Not visible on mobile
--language-dropdown-margin-top: 0px;
- @include mixins.min(lg) {
- --meta-header-height: 3rem; // 48px
- --header-height: 4rem; // 64px
- }
-
- @include mixins.min(xl) {
- --header-height: 4.5rem; // 72px
- }
+ @include mixins.set-custom-property(--meta-header-height, variables.$meta-header-height);
+ @include mixins.set-custom-property(--header-height, variables.$header-height);
}
// Set height to 0 if meta is never visible
@@ -62,7 +55,9 @@
:host(.stickyness-minimal.scrolling-up),
:host(.stickyness-minimal.dropdown-open) {
top: calc(var(--meta-header-height, 0px) * -1);
- transition: top 200ms ease-out;
+
+ @include mixins.set-custom-property(--header-slide-in-transition, variables.$header-slide-in-transition);
+ transition: var(--header-slide-in-transition);
}
}
diff --git a/packages/internet-header/src/components/post-internet-header/post-internet-header.tsx b/packages/internet-header/src/components/post-internet-header/post-internet-header.tsx
index c1b2b84af9..a55d3fced6 100644
--- a/packages/internet-header/src/components/post-internet-header/post-internet-header.tsx
+++ b/packages/internet-header/src/components/post-internet-header/post-internet-header.tsx
@@ -223,6 +223,12 @@ export class PostInternetHeader {
this.host.classList.add('header-loaded');
if (this.meta && this.metaNav) {
this.updateLogoAnimation = registerLogoAnimationObserver(this.metaNav, this.host);
+ } else {
+ // Set height to 0 if meta is never visible and global variables are defined
+ const rootStyles = window.getComputedStyle(document.documentElement);
+ if (rootStyles.getPropertyValue('--post-meta-header-height') !== '') {
+ document.documentElement.style.setProperty('--post-meta-header-height', '0px');
+ }
}
});
diff --git a/packages/internet-header/src/root.scss b/packages/internet-header/src/root.scss
new file mode 100644
index 0000000000..80d0448b48
--- /dev/null
+++ b/packages/internet-header/src/root.scss
@@ -0,0 +1,8 @@
+@use 'utils/mixins';
+@use 'utils/variables';
+
+:root {
+ @include mixins.set-custom-property(--post-meta-header-height, variables.$meta-header-height);
+ @include mixins.set-custom-property(--post-header-height, variables.$header-height);
+ @include mixins.set-custom-property(--post-header-slide-in-transition, variables.$header-slide-in-transition);
+}
diff --git a/packages/internet-header/src/utils/mixins.scss b/packages/internet-header/src/utils/mixins.scss
index bae29f2bc2..68d4ca39ae 100644
--- a/packages/internet-header/src/utils/mixins.scss
+++ b/packages/internet-header/src/utils/mixins.scss
@@ -1,4 +1,6 @@
@use "sass:map";
+@use 'sass:selector';
+@use 'sass:string';
@use "@swisspost/design-system-styles/variables/breakpoints";
@mixin min($point) {
@@ -45,3 +47,33 @@
padding-left: 40px;
}
}
+
+@mixin set-custom-property($var, $value) {
+ @if (type-of($value) == 'map') {
+ @include _responsive-custom-property($var, $value);
+ } @else {
+ @include _custom-property($var, $value);
+ }
+}
+
+@mixin _responsive-custom-property($var, $values) {
+ $previous-value: null;
+ @each $breakpoint, $value in $values {
+ @if($value == $previous-value) {
+ // no styles
+ } @else if($breakpoint == xs) {
+ @include _custom-property($var, $value);
+ } @else {
+ @include min($breakpoint) {
+ @include _custom-property($var, $value);
+ }
+ }
+
+ $previous-value: $value;
+ }
+}
+
+@mixin _custom-property($var, $value) {
+ $is-root: selector.is-superselector(&, ':root');
+ #{$var}: if($is-root, $value, var(#{string.insert($var, "post-", 3)}, $value));
+}
diff --git a/packages/internet-header/src/utils/variables.scss b/packages/internet-header/src/utils/variables.scss
new file mode 100644
index 0000000000..c54317dc2d
--- /dev/null
+++ b/packages/internet-header/src/utils/variables.scss
@@ -0,0 +1,21 @@
+$meta-header-height: (
+ xs: 0px,
+ sm: 0px,
+ rg: 0px,
+ md: 0px,
+ lg: 3rem,
+ xl: 3rem,
+ xxl: 3rem,
+);
+
+$header-height: (
+ xs: 3.5rem,
+ sm: 3.5rem,
+ rg: 3.5rem,
+ md: 3.5rem,
+ lg: 4rem,
+ xl: 4.5rem,
+ xxl: 4.5rem,
+);
+
+$header-slide-in-transition: top 200ms ease-out;
diff --git a/packages/internet-header/stencil.config.dev.ts b/packages/internet-header/stencil.config.dev.ts
new file mode 100644
index 0000000000..7c3a2205a8
--- /dev/null
+++ b/packages/internet-header/stencil.config.dev.ts
@@ -0,0 +1,13 @@
+import { Config } from '@stencil/core';
+import { sass } from '@stencil/sass';
+import { config as prodConfig } from './stencil.config';
+
+export const config: Config = {
+ ...prodConfig,
+ globalStyle: 'src/styles.scss',
+ plugins: [
+ sass({
+ includePaths: ['node_modules'],
+ }),
+ ],
+};
diff --git a/packages/internet-header/stencil.config.ts b/packages/internet-header/stencil.config.ts
index a2a32d5e43..ad811cdbb2 100644
--- a/packages/internet-header/stencil.config.ts
+++ b/packages/internet-header/stencil.config.ts
@@ -4,7 +4,7 @@ import scss from 'rollup-plugin-scss';
export const config: Config = {
namespace: 'swisspost-internet-header',
- globalStyle: 'src/styles.scss',
+ globalStyle: 'src/root.scss',
buildEs5: 'prod',
sourceMap: false,
bundles: [