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: [