;
+
+export const Default: Story = {};
+
+export const CustomItems: Story = {
+ args: {
+ customItems: customItems,
+ },
+};
diff --git a/packages/documentation/src/stories/internet-header/components/breadcrumbs/overrides/breadcrumbs-config.docs.mdx b/packages/documentation/src/stories/internet-header/components/breadcrumbs/overrides/breadcrumbs-config.docs.mdx
new file mode 100644
index 0000000000..bd0d52c9e3
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/breadcrumbs/overrides/breadcrumbs-config.docs.mdx
@@ -0,0 +1,12 @@
+import { Canvas, Controls, Meta } from '@storybook/blocks';
+import * as BreadcrumbStories from './breadcrumbs-config.stories';
+
+
+
+# Breadcrumbs with custom items
+
+When you need to add your own breadcrumb items.
+
+
+
+
diff --git a/packages/documentation/src/stories/internet-header/components/breadcrumbs/overrides/breadcrumbs-config.stories.ts b/packages/documentation/src/stories/internet-header/components/breadcrumbs/overrides/breadcrumbs-config.stories.ts
new file mode 100644
index 0000000000..8910bb5603
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/breadcrumbs/overrides/breadcrumbs-config.stories.ts
@@ -0,0 +1,5 @@
+import * as BreadcrumbsStories from '../breadcrumbs.stories';
+
+export default { ...BreadcrumbsStories.default, title: 'Internet Header/Breadcrumbs/Custom Items' };
+
+export const Default = BreadcrumbsStories.CustomItems;
diff --git a/packages/documentation/src/stories/internet-header/components/breadcrumbs/overrides/custom-items.ts b/packages/documentation/src/stories/internet-header/components/breadcrumbs/overrides/custom-items.ts
new file mode 100644
index 0000000000..232ed0e40b
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/breadcrumbs/overrides/custom-items.ts
@@ -0,0 +1,5 @@
+export default [
+ { text: 'X', url: '/x' },
+ { text: 'XY', url: '/x/xy' },
+ { text: 'XYZ', url: '/x/xy/xyz' },
+];
diff --git a/packages/documentation/src/stories/internet-header/components/footer/custom-config/custom-footer-config.ts b/packages/documentation/src/stories/internet-header/components/footer/custom-config/custom-footer-config.ts
new file mode 100644
index 0000000000..bb1ec76180
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/footer/custom-config/custom-footer-config.ts
@@ -0,0 +1,23 @@
+const footerBlock = (lang: string) => ({
+ footer: {
+ block: {
+ title: `Eigene Footer-Konfiguration (${lang})`,
+ links: [
+ { url: 'https://fireship.io', text: 'Fireship.io', target: '_blank' },
+ { url: 'https://css-tricks.com', text: 'CSS-Tricks', target: '_blank' },
+ { url: 'https://web.dev', text: 'web.dev', target: '_blank' },
+ { url: 'https://developer.mozilla.org', text: 'MDN Web Docs', target: '_blank' },
+ { url: 'https://getbootstrap.com', text: 'Bootstrap', target: '_blank' },
+ { url: 'https://google.com', text: 'Google', target: '_blank' },
+ { url: 'https://microsoft.com', text: 'Microsoft', target: '_blank' },
+ ],
+ },
+ },
+});
+
+export default {
+ de: footerBlock('de'),
+ fr: footerBlock('fr'),
+ it: footerBlock('it'),
+ en: footerBlock('en'),
+};
diff --git a/packages/documentation/src/stories/internet-header/components/footer/custom-config/footer-config.docs.mdx b/packages/documentation/src/stories/internet-header/components/footer/custom-config/footer-config.docs.mdx
new file mode 100644
index 0000000000..7f766f5766
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/footer/custom-config/footer-config.docs.mdx
@@ -0,0 +1,15 @@
+import { Canvas, Controls, Meta } from '@storybook/blocks';
+import * as FooterConfig from './footer-config.stories';
+
+
+
+
+
Footer with custom config
+
When you need to add your own footer links.
+
+
+
+
+
+
+
diff --git a/packages/documentation/src/stories/internet-header/components/footer/custom-config/footer-config.stories.ts b/packages/documentation/src/stories/internet-header/components/footer/custom-config/footer-config.stories.ts
new file mode 100644
index 0000000000..8dfd91db51
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/footer/custom-config/footer-config.stories.ts
@@ -0,0 +1,5 @@
+import * as FooterStories from '../footer.stories';
+
+export default { ...FooterStories.default, title: 'Internet Header/Footer/Custom Config' };
+
+export const Default = FooterStories.CustomConfig;
diff --git a/packages/documentation/src/stories/internet-header/components/footer/footer.docs.mdx b/packages/documentation/src/stories/internet-header/components/footer/footer.docs.mdx
new file mode 100644
index 0000000000..2b6b4eeaba
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/footer/footer.docs.mdx
@@ -0,0 +1,18 @@
+import { Canvas, Controls, Meta } from '@storybook/blocks';
+import * as FooterStories from './footer.stories';
+
+
+
+
+
Footer
+
+ Provides key app-wide information such as contact details and legal links.
+
+
The footer comes with its own container and can be placed at the end of your content.
+
+
+
+
+
+
+
diff --git a/packages/documentation/src/stories/internet-header/components/footer/footer.stories.ts b/packages/documentation/src/stories/internet-header/components/footer/footer.stories.ts
new file mode 100644
index 0000000000..e18dedc762
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/footer/footer.stories.ts
@@ -0,0 +1,61 @@
+import { Args, Meta, StoryContext, StoryObj } from '@storybook/web-components';
+import { html } from 'lit';
+import { BADGE } from '../../../../../.storybook/constants';
+import customFooterConfig from './custom-config/custom-footer-config';
+import { spread } from '@open-wc/lit-helpers';
+
+const meta: Meta = {
+ title: 'Internet Header/Footer',
+ component: 'swisspost-internet-footer',
+ render: renderInternetFooter,
+ decorators: [hiddenHeader],
+ parameters: {
+ layout: 'fullscreen',
+ badges: [BADGE.STABLE],
+ },
+ argTypes: {
+ customConfig: {
+ control: 'object',
+ table: {
+ type: {
+ summary: 'ICustomConfig',
+ detail: JSON.stringify(customFooterConfig),
+ },
+ },
+ },
+ },
+};
+
+export default meta;
+
+// DECORATORS
+function hiddenHeader(story: any, { args }: StoryContext) {
+ return html`
+
+ ${story()}
+ `;
+}
+
+// RENDERER
+function renderInternetFooter(args: Args) {
+ const props = args.customConfig ? { 'custom-config': JSON.stringify(args.customConfig) } : {};
+ return html`
+
+
+ `;
+}
+
+// STORIES
+type Story = StoryObj;
+
+export const Default: Story = {};
+
+export const CustomConfig: Story = {
+ args: {
+ customConfig: customFooterConfig,
+ },
+};
diff --git a/packages/documentation/src/stories/internet-header/components/header/config/custom-config.ts b/packages/documentation/src/stories/internet-header/components/header/config/custom-config.ts
new file mode 100644
index 0000000000..0d6f1cb1b4
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/config/custom-config.ts
@@ -0,0 +1,82 @@
+export default {
+ de: {
+ header: {
+ navMain: [
+ {
+ title: 'Meine Links (custom config)',
+ text: 'Meine Links',
+ url: '#',
+ flyout: [
+ {
+ title: 'Google',
+ linkList: [
+ { url: 'https://maps.google.com', title: 'Google Maps', target: '_blank' },
+ { url: 'https://translate.google.com', title: 'Google Translate' },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ },
+ fr: {
+ header: {
+ navMain: [
+ {
+ title: 'Meine Links (custom config)',
+ text: 'Meine Links',
+ url: '#',
+ flyout: [
+ {
+ title: 'Google',
+ linkList: [
+ { url: 'https://maps.google.com', title: 'Google Maps', target: '_blank' },
+ { url: 'https://translate.google.com', title: 'Google Translate' },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ },
+ it: {
+ header: {
+ navMain: [
+ {
+ title: 'Meine Links (custom config)',
+ text: 'Meine Links',
+ url: '#',
+ flyout: [
+ {
+ title: 'Google',
+ linkList: [
+ { url: 'https://maps.google.com', title: 'Google Maps', target: '_blank' },
+ { url: 'https://translate.google.com', title: 'Google Translate' },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ },
+ en: {
+ header: {
+ navMain: [
+ {
+ title: 'Meine Links (custom config)',
+ text: 'Meine Links',
+ url: '#',
+ flyout: [
+ {
+ title: 'Google',
+ linkList: [
+ { url: 'https://maps.google.com', title: 'Google Maps', target: '_blank' },
+ { url: 'https://translate.google.com', title: 'Google Translate' },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ },
+};
diff --git a/packages/documentation/src/stories/internet-header/components/header/config/language-switch-overrides.ts b/packages/documentation/src/stories/internet-header/components/header/config/language-switch-overrides.ts
new file mode 100644
index 0000000000..6fa4d1eeb6
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/config/language-switch-overrides.ts
@@ -0,0 +1,6 @@
+export default [
+ { lang: 'de', url: '/?lang=de' },
+ { lang: 'fr', url: '/?lang=fr' },
+ { lang: 'it', url: '/?lang=it' },
+ { lang: 'en', url: '/?lang=en' },
+];
diff --git a/packages/documentation/src/stories/internet-header/components/header/config/os-flyout-overrides.ts b/packages/documentation/src/stories/internet-header/components/header/config/os-flyout-overrides.ts
new file mode 100644
index 0000000000..2628118b80
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/config/os-flyout-overrides.ts
@@ -0,0 +1,25 @@
+export default {
+ title: 'Custom OS Flyout',
+ text: 'Custom OS Flyout',
+ url: '#',
+ flyout: [
+ {
+ title: 'A title',
+ linkList: [
+ {
+ url: '#bla',
+ title: 'Another link',
+ },
+ ],
+ },
+ {
+ title: 'Another column',
+ linkList: [
+ {
+ url: '#foo',
+ title: 'Foo',
+ },
+ ],
+ },
+ ],
+};
diff --git a/packages/documentation/src/stories/internet-header/components/header/header.docs.mdx b/packages/documentation/src/stories/internet-header/components/header/header.docs.mdx
new file mode 100644
index 0000000000..a935f7a30f
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/header.docs.mdx
@@ -0,0 +1,17 @@
+import { Meta, Canvas, Controls } from '@storybook/blocks';
+import { BADGE } from '../../../../../.storybook/constants';
+import * as HeaderStories from './header.stories';
+import './header.scss';
+
+
+
+
+
Internet Header
+
For external, client facing applications.
+
+
+
+
+
+
+
diff --git a/packages/documentation/src/stories/internet-header/components/internet-header.styles.scss b/packages/documentation/src/stories/internet-header/components/header/header.scss
similarity index 60%
rename from packages/documentation/src/stories/internet-header/components/internet-header.styles.scss
rename to packages/documentation/src/stories/internet-header/components/header/header.scss
index 9b64d999be..5b321be1a9 100644
--- a/packages/documentation/src/stories/internet-header/components/internet-header.styles.scss
+++ b/packages/documentation/src/stories/internet-header/components/header/header.scss
@@ -1,10 +1,12 @@
-.docs-story {
- > div:first-child {
- overflow: hidden;
+.container {
+ div {
+ overflow: visible;
}
+}
- > div:nth-child(2) {
- z-index: 1000;
+#storybook-docs {
+ .header-story-wrapper {
+ max-height: 20rem !important;
}
}
@@ -13,10 +15,10 @@
position: relative;
min-height: calc(1.6rem * 8);
background: repeating-linear-gradient(
- rgb(230, 230, 230),
- rgb(230, 230, 230) 1rem,
- transparent 1rem,
- transparent 1.6rem
+ rgb(230, 230, 230),
+ rgb(230, 230, 230) 1rem,
+ transparent 1rem,
+ transparent 1.6rem
);
&::after {
diff --git a/packages/documentation/src/stories/internet-header/components/header/header.stories.ts b/packages/documentation/src/stories/internet-header/components/header/header.stories.ts
new file mode 100644
index 0000000000..b4dd7ad7f8
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/header.stories.ts
@@ -0,0 +1,213 @@
+import { Args, Meta, StoryObj } from '@storybook/web-components';
+import { BADGE } from '../../../../../.storybook/constants';
+import { html } from 'lit';
+import { spread } from '@open-wc/lit-helpers';
+import { getAttributes } from '../../../../utils';
+import customConfig from './config/custom-config';
+import osFlyoutOverrides from './config/os-flyout-overrides';
+import languageSwitchOverrides from './config/language-switch-overrides';
+
+const meta: Meta = {
+ title: 'Internet Header/Header',
+ component: 'swisspost-internet-header',
+ parameters: {
+ badges: [BADGE.STABLE],
+ layout: 'fullscreen',
+ controls: { sort: 'alpha' },
+ },
+ render,
+ args: {
+ project: 'test',
+ environment: 'int01',
+ language: 'en',
+ },
+ argTypes: {
+ project: {
+ control: false,
+ table: {
+ category: 'Required props',
+ },
+ type: {
+ name: 'string',
+ required: true,
+ },
+ },
+ environment: {
+ control: false,
+ table: {
+ category: 'Optional props',
+ },
+ },
+ fullWidth: {
+ control: {
+ type: 'boolean',
+ },
+ table: {
+ category: 'Optional props',
+ },
+ },
+ activeRoute: {
+ control: {
+ type: 'text',
+ },
+ table: {
+ category: 'Optional props',
+ },
+ },
+ configProxy: {
+ control: false,
+ table: {
+ category: 'Deprecated',
+ },
+ },
+ languageCookieKey: {
+ control: false,
+ table: {
+ category: 'Optional props',
+ },
+ },
+ languageLocalStorageKey: {
+ control: false,
+ table: {
+ category: 'Optional props',
+ },
+ },
+ login: {
+ table: {
+ category: 'Optional props',
+ },
+ },
+ meta: {
+ table: {
+ category: 'Optional props',
+ },
+ },
+ search: {
+ table: {
+ category: 'Optional props',
+ },
+ },
+ skiplinks: {
+ table: {
+ category: 'Optional props',
+ },
+ },
+ stickyness: {
+ control: {
+ labels: {
+ full: 'full (deprecated, use "main")',
+ minimal: 'minimal',
+ main: 'main',
+ none: 'none',
+ },
+ },
+ table: {
+ category: 'Optional props',
+ },
+ },
+ language: {
+ table: {
+ category: 'Optional props',
+ },
+ },
+ customConfig: {
+ control: 'object',
+ table: {
+ category: 'Optional props',
+ subcategory: 'Overrides',
+ type: {
+ summary: 'ICustomConfig',
+ detail: JSON.stringify(customConfig),
+ },
+ },
+ },
+ languageSwitchOverrides: {
+ control: {
+ type: 'object',
+ },
+ table: {
+ category: 'Optional props',
+ subcategory: 'Overrides',
+ type: {
+ summary: 'IAvailableLanguage[]',
+ detail: JSON.stringify(languageSwitchOverrides),
+ },
+ },
+ },
+ osFlyoutOverrides: {
+ control: 'object',
+ table: {
+ category: 'Optional props',
+ subcategory: 'Overrides',
+ type: {
+ summary: 'NavMainEntity',
+ detail: JSON.stringify(osFlyoutOverrides),
+ },
+ },
+ },
+ },
+ decorators: [
+ story =>
+ html`
+
+ `,
+ ],
+};
+
+function render(args: Args) {
+ const attributes = getAttributes(args, arg => arg !== null && arg !== undefined);
+ return html`
+
+ `;
+}
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Default: Story = {};
+
+export const LanguageSwitchOverrides: Story = {
+ args: {
+ languageSwitchOverrides,
+ },
+ parameters: {
+ controls: {
+ include: ['languageSwitchOverrides'],
+ },
+ },
+};
+
+export const CustomConfig: Story = {
+ args: {
+ customConfig,
+ },
+ parameters: {
+ controls: {
+ include: ['customConfig'],
+ },
+ },
+};
+
+export const OSFlyoutOverrides: Story = {
+ args: {
+ osFlyoutOverrides,
+ },
+ parameters: {
+ controls: {
+ include: ['osFlyoutOverrides'],
+ },
+ },
+};
diff --git a/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-custom-config.docs.mdx b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-custom-config.docs.mdx
new file mode 100644
index 0000000000..a567fc003a
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-custom-config.docs.mdx
@@ -0,0 +1,17 @@
+import { Meta, Canvas, Controls } from '@storybook/blocks';
+import { BADGE } from '../../../../../../.storybook/constants';
+import * as HeaderStories from './header-custom-config.stories';
+import '../header.scss';
+
+
+
+
+
Internet Header with Custom Config
+
When you need to add your own navigation entries.
+
+
+
+
+
+
+
diff --git a/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-custom-config.stories.ts b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-custom-config.stories.ts
new file mode 100644
index 0000000000..54095bded0
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-custom-config.stories.ts
@@ -0,0 +1,5 @@
+import * as HeaderStories from '../header.stories';
+
+export default { ...HeaderStories.default, title: 'Internet Header/Header/Custom Config' };
+
+export const Default = HeaderStories.CustomConfig;
diff --git a/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-language-switch-overrides.docs.mdx b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-language-switch-overrides.docs.mdx
new file mode 100644
index 0000000000..efb026d77d
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-language-switch-overrides.docs.mdx
@@ -0,0 +1,17 @@
+import { Meta, Canvas, Controls } from '@storybook/blocks';
+import { BADGE } from '../../../../../../.storybook/constants';
+import * as HeaderStories from './header-language-switch-overrides.stories';
+import '../header.scss';
+
+
+
+
+
Internet Header with language switch overrides
+
Customizing where the links in the language switch point to.
+
+
+
+
+
+
+
diff --git a/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-language-switch-overrides.stories.ts b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-language-switch-overrides.stories.ts
new file mode 100644
index 0000000000..c2a53a22e9
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-language-switch-overrides.stories.ts
@@ -0,0 +1,8 @@
+import * as HeaderStories from '../header.stories';
+
+export default {
+ ...HeaderStories.default,
+ title: 'Internet Header/Header/Language Switch Overrides',
+};
+
+export const Default = HeaderStories.LanguageSwitchOverrides;
diff --git a/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-os-flyout-overrides.docs.mdx b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-os-flyout-overrides.docs.mdx
new file mode 100644
index 0000000000..1ed0d93a45
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-os-flyout-overrides.docs.mdx
@@ -0,0 +1,17 @@
+import { Meta, Canvas, Controls } from '@storybook/blocks';
+import { BADGE } from '../../../../../../.storybook/constants';
+import * as HeaderStories from './header-os-flyout-overrides.stories';
+import '../header.scss';
+
+
+
+
+
Internet Header with OS overrides
+
Customising the online service flyout.
+
+
+
+
+
+
+
diff --git a/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-os-flyout-overrides.stories.ts b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-os-flyout-overrides.stories.ts
new file mode 100644
index 0000000000..9047146cd2
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/components/header/overrides-stories/header-os-flyout-overrides.stories.ts
@@ -0,0 +1,8 @@
+import * as HeaderStories from '../header.stories';
+
+export default {
+ ...HeaderStories.default,
+ title: 'Internet Header/Header/Os Flyout Overrides',
+};
+
+export const Default = HeaderStories.OSFlyoutOverrides;
diff --git a/packages/documentation/src/stories/internet-header/components/internet-header.docs.mdx b/packages/documentation/src/stories/internet-header/components/internet-header.docs.mdx
deleted file mode 100644
index 4be69ee0f9..0000000000
--- a/packages/documentation/src/stories/internet-header/components/internet-header.docs.mdx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { Canvas, ArgTypes, Meta } from '@storybook/blocks';
-import * as InternetHeaderStories from './internet-header.stories';
-
-
-
-# Header
-
-
- Customizable navigation header tailored for Swiss Post customer-facing applications,
- ensuring complete accessibility and responsiveness.
-
-
-The `` element needs
-to be nested directly inside the `` for the sticky scrolling to work.
-
-If you want to render the header element with Angular,
-have a look at [portals](https://medium.com/angular-in-depth/how-do-cdk-portals-work-7c097c14a494).
-
-
- Open Header in New Tab
-
-
-
-
-
-
-## Examples
-
-### Custom Navigation Item
-
-
-
-### Custom Online Service Flyout
-
-
-
-### Full Width
-
-By default, on viewports with a width greater than 1440px, header content is padded right and left.
-To make the header span the full width of the viewport, set the `full-width` property to `true`.
-
-
- See Fullwidth Header
-
diff --git a/packages/documentation/src/stories/internet-header/components/internet-header.stories.tsx b/packages/documentation/src/stories/internet-header/components/internet-header.stories.tsx
deleted file mode 100644
index 3f1d2b2e92..0000000000
--- a/packages/documentation/src/stories/internet-header/components/internet-header.stories.tsx
+++ /dev/null
@@ -1,243 +0,0 @@
-import { Args, Meta, StoryObj } from '@storybook/web-components';
-import { html } from 'lit';
-import { spread } from '@open-wc/lit-helpers';
-import { BADGE } from '../../../../.storybook/constants';
-import './internet-header.styles.scss';
-
-const meta: Meta = {
- title: 'Internet Header/Header Component',
- component: 'swisspost-internet-header',
- render: renderInternetHeader,
- parameters: {
- layout: 'fullscreen',
- actions: {
- handles: ['headerLoaded', 'languageChanged'],
- },
- badges: [BADGE.STABLE],
- controls: {
- exclude: ['config-proxy'],
- },
- },
- args: {
- project: 'test',
- language: 'de',
- },
- argTypes: {
- activeRoute: {
- name: 'active-route',
- control: 'text',
- },
- customConfig: {
- name: 'custom-config',
- control: 'object',
- },
- language: {
- control: 'select',
- options: ['de', 'fr', 'it', 'en'],
- },
- languageCookieKey: {
- name: 'language-cookie-key',
- control: 'text',
- },
- languageLocalStorageKey: {
- name: 'language-local-storage-key',
- control: 'text',
- },
- languageSwitchOverrides: {
- name: 'language-switch-overrides',
- control: 'object',
- },
- osFlyoutOverrides: {
- name: 'os-flyout-overrides',
- control: 'object',
- },
- stickyness: {
- control: 'select',
- },
- },
-};
-
-export default meta;
-
-// DECORATORS
-function mockPage(story: any) {
- return html`
-
- ${story()}
-
-
- Swiss Post Internet Header
-
-
-
-
-
- `;
-}
-
-// RENDERER
-function renderInternetHeader(args: HTMLSwisspostInternetHeaderElement) {
- const attributes = getAttributes(args, arg => arg !== null && arg !== undefined);
- return html`
-
- `;
-}
-
-// STORIES
-type Story = StoryObj;
-
-export const Default: Story = {
- decorators: [mockPage],
- parameters: {
- docs: {
- story: {
- inline: false,
- height: '40em',
- },
- },
- },
-};
-
-export const FullWidth: Story = {
- decorators: [mockPage],
- args: {
- fullWidth: true,
- },
-};
-
-export const CustomNavigation: Story = {
- args: {
- customConfig: {
- de: {
- header: {
- navMain: [
- {
- title: 'Meine Links (custom config)',
- text: 'Meine Links',
- url: '#',
- flyout: [
- {
- title: 'Google',
- linkList: [
- { url: 'https://maps.google.com', title: 'Google Maps', target: '_blank' },
- { url: 'https://translate.google.com', title: 'Google Translate' },
- ],
- },
- ],
- },
- ],
- },
- },
- fr: {
- header: {
- navMain: [
- {
- title: 'Meine Links (custom config)',
- text: 'Meine Links',
- url: '#',
- flyout: [
- {
- title: 'Google',
- linkList: [
- { url: 'https://maps.google.com', title: 'Google Maps', target: '_blank' },
- { url: 'https://translate.google.com', title: 'Google Translate' },
- ],
- },
- ],
- },
- ],
- },
- },
- it: {
- header: {
- navMain: [
- {
- title: 'Meine Links (custom config)',
- text: 'Meine Links',
- url: '#',
- flyout: [
- {
- title: 'Google',
- linkList: [
- { url: 'https://maps.google.com', title: 'Google Maps', target: '_blank' },
- { url: 'https://translate.google.com', title: 'Google Translate' },
- ],
- },
- ],
- },
- ],
- },
- },
- en: {
- header: {
- navMain: [
- {
- title: 'Meine Links (custom config)',
- text: 'Meine Links',
- url: '#',
- flyout: [
- {
- title: 'Google',
- linkList: [
- { url: 'https://maps.google.com', title: 'Google Maps', target: '_blank' },
- { url: 'https://translate.google.com', title: 'Google Translate' },
- ],
- },
- ],
- },
- ],
- },
- },
- },
- },
-};
-
-export const CustomOnlineServiceFlyout: Story = {
- decorators: [mockPage],
- args: {
- osFlyoutOverrides: {
- title: 'Custom OS Flyout',
- text: 'Custom OS Flyout',
- url: '#',
- flyout: [
- {
- title: 'A title',
- linkList: [
- {
- url: '#bla',
- title: 'Another link',
- },
- ],
- },
- {
- title: 'Another column',
- linkList: [
- {
- url: '#foo',
- title: 'Foo',
- },
- ],
- },
- ],
- },
- },
-};
-
-// TODO: move to utils
-const getAttributes = (args: Args, condition?: (arg: any) => boolean): Args => {
- const attrs: { [key: string]: any } = {};
-
- for (const key in args) {
- if (args.hasOwnProperty(key) && condition && condition(args[key])) {
- const attrKey = key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
-
- // Cast boolean false to string so it's displayed in the docs code block. False values are otherwise omitted
- attrs[attrKey] = args[key] === false ? 'false' : args[key];
- if (typeof args[key] === 'object') {
- attrs[attrKey] = JSON.stringify(args[key]);
- }
- }
- }
-
- return attrs;
-};
diff --git a/packages/documentation/src/stories/internet-header/getting-started.docs.mdx b/packages/documentation/src/stories/internet-header/getting-started.docs.mdx
index 17aaa19cb3..e158682793 100644
--- a/packages/documentation/src/stories/internet-header/getting-started.docs.mdx
+++ b/packages/documentation/src/stories/internet-header/getting-started.docs.mdx
@@ -1,16 +1,13 @@
import { Meta, Source } from '@storybook/blocks';
-import { BADGE } from '../../../.storybook/constants';
import SampleFrameworks from './internet-header-frameworks.sample.html?raw';
import SampleLazyLoaded from './internet-header-lazy-loaded.sample.js?raw';
import SampleBareComponent from './internet-header-bare-component.sample.js?raw';
import SampleCDNLazyLoaded from './internet-header-cdn-lazy-loaded.sample.html?raw';
import SampleCDNBareComponent from './internet-header-cdn-bare-component.sample.html?raw';
import { SourceDarkMode } from '../../../.storybook/preview';
+import * as GettingStartedStories from './getting-started.stories';
-
+
# @swisspost/internet-header
@@ -30,8 +27,8 @@ The header for client-facing applications.
Internet-header package provide two versions:
- * Lazy-loaded (default): it allows better performance by dynamically load the component when used, so it reduces bundle size, startup time and first paint.
- * Bare component: if you already manage the lazy-loading or don't need it for any reason, you can use the component without any overhead.
+- Lazy-loaded (default): it allows better performance by dynamically load the component when used, so it reduces bundle size, startup time and first paint.
+- Bare component: if you already manage the lazy-loading or don't need it for any reason, you can use the component without any overhead.
### Angular, Vue.js, React (or any other bundler setup)
@@ -41,33 +38,17 @@ bundle and deliver the header with your own code.
When working with Angular or any other framework, the easiest installation method is via npm.
-
+
-
+
#### Lazy-loaded
-
+
#### Bare component
-
+
### Include from a CDN
@@ -76,24 +57,16 @@ Make sure to replace `{version}` with the version you want to use or remove `@{v
Available CDNs:
-* [jsDelivr](https://www.jsdelivr.com/): replace `{cdnURL}` with [https://cdn.jsdelivr.net/npm/@swisspost/internet-header](https://cdn.jsdelivr.net/npm/@swisspost/internet-header).
-* [unpkg](https://unpkg.com/): replace `{cdnURL}` with [https://unpkg.com/@swisspost/internet-header](https://unpkg.com/@swisspost/internet-header).
+- [jsDelivr](https://www.jsdelivr.com/): replace `{cdnURL}` with [https://cdn.jsdelivr.net/npm/@swisspost/internet-header](https://cdn.jsdelivr.net/npm/@swisspost/internet-header).
+- [unpkg](https://unpkg.com/): replace `{cdnURL}` with [https://unpkg.com/@swisspost/internet-header](https://unpkg.com/@swisspost/internet-header).
#### Lazy-loaded
-
+
#### Bare component
-
+
## Configuration
diff --git a/packages/documentation/src/stories/internet-header/getting-started.stories.ts b/packages/documentation/src/stories/internet-header/getting-started.stories.ts
new file mode 100644
index 0000000000..f4620ec745
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/getting-started.stories.ts
@@ -0,0 +1,15 @@
+import { Meta, StoryObj } from '@storybook/web-components';
+import { BADGE } from '../../../.storybook/constants';
+
+const meta: Meta = {
+ title: 'Internet Header/Getting Started',
+ parameters: {
+ badges: [BADGE.STABLE],
+ },
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/packages/documentation/src/stories/internet-header/migration-guide.docs.mdx b/packages/documentation/src/stories/internet-header/migration-guide.docs.mdx
index ff37b21428..c3c94091c4 100644
--- a/packages/documentation/src/stories/internet-header/migration-guide.docs.mdx
+++ b/packages/documentation/src/stories/internet-header/migration-guide.docs.mdx
@@ -5,11 +5,9 @@ import SampleInstall from './internet-header-install.sample.html?raw';
import SampleFixAppStyles from './internet-header-fix-app-styles.sample.html?raw';
import SampleOld from './internet-header-old.sample.html?raw';
import { SourceDarkMode } from '../../../.storybook/preview';
+import * as MigrationGuideStories from './migration-guide.stories';
-
+
# Migration from the old header
@@ -45,11 +43,7 @@ One to load static assets, one to configure it and one to load it.
- You can remove the configuration and the loader scripts, but remember your `serviceid`.
- Try to remove the `staticassets` script to check if you still need it
-
+
## 2. Fix your app styles
@@ -58,11 +52,7 @@ The new header does not provide those wrappers.
Instead, every page has control over the main markup structure.
A possible replacement of the above code could be:
-
+
- Likely you'll need the class `container` around your main content to align it properly in the center.
- For bonus points on semantic markup, use the [`` tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main) around the main page content
@@ -86,11 +76,7 @@ Please refer to the [Internet Header installation instructions](/story/getting-s
After installation, you're ready to add the new tags to your markup:
-
+
Place the new elements as described (and needed) as shown above.
The breadcrumbs need a `container` wrapper to align themselves with the content of your page,
@@ -101,11 +87,6 @@ If you don't have breadcrumbs, you can just delete the `` and the `
-
+
At the [Internet Header configuration page](/story/header - usage--page) you can find a list of possible options.
diff --git a/packages/documentation/src/stories/internet-header/migration-guide.stories.ts b/packages/documentation/src/stories/internet-header/migration-guide.stories.ts
new file mode 100644
index 0000000000..732fc5ea9c
--- /dev/null
+++ b/packages/documentation/src/stories/internet-header/migration-guide.stories.ts
@@ -0,0 +1,15 @@
+import { Meta, StoryObj } from '@storybook/web-components';
+import { BADGE } from '../../../.storybook/constants';
+
+const meta: Meta = {
+ title: 'Internet Header/Migration Guide',
+ parameters: {
+ badges: [BADGE.STABLE],
+ },
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/packages/documentation/src/utils/get-attributes.ts b/packages/documentation/src/utils/get-attributes.ts
new file mode 100644
index 0000000000..1df5b958e8
--- /dev/null
+++ b/packages/documentation/src/utils/get-attributes.ts
@@ -0,0 +1,19 @@
+import { Args } from '@storybook/web-components';
+
+export const getAttributes = (args: Args, condition?: (arg: any) => boolean): Args => {
+ const attrs: { [key: string]: any } = {};
+
+ for (const key in args) {
+ if (args.hasOwnProperty(key) && condition && condition(args[key])) {
+ const attrKey = key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
+
+ // Cast boolean false to string, so it's displayed in the docs code block. False values are otherwise omitted
+ attrs[attrKey] = args[key] === false ? 'false' : args[key];
+ if (typeof args[key] === 'object') {
+ attrs[attrKey] = JSON.stringify(args[key]);
+ }
+ }
+ }
+
+ return attrs;
+};
diff --git a/packages/documentation/src/utils/index.ts b/packages/documentation/src/utils/index.ts
index 540d902d4f..72410b3996 100644
--- a/packages/documentation/src/utils/index.ts
+++ b/packages/documentation/src/utils/index.ts
@@ -1,2 +1,3 @@
export * from './component-properties';
+export * from './get-attributes';
export * from './map-classes';
diff --git a/packages/internet-header/cypress/e2e/breadcrumbs.cy.ts b/packages/internet-header/cypress/e2e/breadcrumbs.cy.ts
index 94ad310d89..e402efb333 100644
--- a/packages/internet-header/cypress/e2e/breadcrumbs.cy.ts
+++ b/packages/internet-header/cypress/e2e/breadcrumbs.cy.ts
@@ -22,15 +22,6 @@ describe('breadcrumb', () => {
}
describe('configuration', () => {
- it(`should not be rendered if no header present`, () => {
- // Need to revisit storybook to make sure new story is loaded correctly
- prepare('Internet Header/Components/Breadcrumbs', 'NonExistentHeader');
-
- cy.get('swisspost-internet-breadcrumbs').should('not.be.visible');
- cy.get('.page-wrapper').should('be.visible');
- cy.get('div.breadcrumbs').should('not.exist');
- });
-
it(`should not rendered if no config present`, () => {
// Cast the imported JSON object to the IPortalConfig interface
const config: IPortalConfig = testConfiguration;
@@ -42,15 +33,15 @@ describe('breadcrumb', () => {
modifiedConfig.fr.breadcrumb = undefined;
modifiedConfig.it.breadcrumb = undefined;
- prepare('Internet Header/Components/Breadcrumbs', 'NonExistentHeader', modifiedConfig);
+ prepare('Internet Header/Breadcrumbs', 'Default', modifiedConfig);
cy.get('swisspost-internet-breadcrumbs').should('exist');
cy.get('div.breadcrumbs').should('not.exist');
});
it(`should add custom elements`, () => {
- prepare('Internet Header/Components/Breadcrumbs', 'Custom-Items');
+ prepare('Internet Header/Breadcrumbs/Custom Items', 'Default');
- (cy as any).changeArg('custom-items', [
+ cy.changeArg('custom-items', [
{ text: 'Test1', url: '/x/y/z' },
{ text: 'Test2', url: '/a/b/c' },
]);
@@ -72,7 +63,7 @@ describe('breadcrumb', () => {
describe('open/close overlay buttons', () => {
beforeEach(() => {
- prepare('Internet Header/Components/Breadcrumbs', 'Default');
+ prepare('Internet Header/Breadcrumbs', 'Default');
cy.get('div.breadcrumbs').as('breadcrumbs');
cy.intercept(
'https://post.ch/de/kundencenter/onlinedienste/standorte-und-oeffnungszeiten/**',
@@ -105,7 +96,7 @@ describe('breadcrumb', () => {
describe('mobile', () => {
beforeEach(() => {
cy.viewport('iphone-6+');
- prepare('Internet Header/Components/Breadcrumbs', 'Default');
+ prepare('Internet Header/Breadcrumbs', 'Default');
cy.get('div.breadcrumbs').as('breadcrumbs');
});
@@ -117,7 +108,7 @@ describe('breadcrumb', () => {
it(`should not break line for long elements`, () => {
const itemText = 'Veeeeeeeeery loooooooong element';
- (cy as any).changeArg('custom-items', [{ text: itemText, url: '/x/y/z' }]);
+ cy.changeArg('custom-items', [{ text: itemText, url: '/x/y/z' }]);
cy.get('div.breadcrumbs > nav > ol li').as('breadcrumbItems');
diff --git a/packages/internet-header/cypress/e2e/footer.cy.ts b/packages/internet-header/cypress/e2e/footer.cy.ts
index dd0a086150..fdd972c771 100644
--- a/packages/internet-header/cypress/e2e/footer.cy.ts
+++ b/packages/internet-header/cypress/e2e/footer.cy.ts
@@ -2,21 +2,9 @@ import { prepare } from '../support/prepare-story';
describe('footer', () => {
describe('config', () => {
- describe('footer config not set', () => {
- it(`removes footer control`, () => {
- prepare('Internet Header/Components/Footer', 'Default');
-
- // Assert the header is hydrated
- cy.get('swisspost-internet-footer').should('have.class', 'hydrated');
-
- // With the modified configuration the footer should be removed from the DOM
- cy.get('.post-internet-footer').should('not.exist');
- });
- });
-
describe('custom footer config set', () => {
it(`shows custom footer links`, async () => {
- prepare('Internet Header/Components/Footer', 'Default');
+ prepare('Internet Header/Footer', 'Default');
const customFooterConfig = {
de: {
@@ -51,25 +39,14 @@ describe('footer', () => {
});
});
- describe('header element non-existent', () => {
- it(`removes footer control`, () => {
- // Visit the story with non-existent header
- prepare('Internet Header/Components/Footer', 'Non-existent-header');
-
- // Without the header, the footer should be removed from the DOM as well
- cy.get('swisspost-internet-footer').should('exist');
- cy.get('.post-internet-footer').should('not.exist');
- });
- });
-
describe('external functions test', () => {
it('should not show cookie settings link when UC_UI is not defined', () => {
- prepare('Internet Header/Components/Footer', 'Default');
+ prepare('Internet Header/Footer', 'Default');
cy.get('.footer-meta-links').should('exist').get('.cookie-settings').should('not.exist');
});
it('should show cookie settings when UC_UI is defined', () => {
- prepare('Internet Header/Components/Footer', 'Default');
+ prepare('Internet Header/Footer', 'Default');
cy.window().then(win => {
win['UC_UI'] = { showSecondLayer: () => 'second layer mock' };
cy.get('.footer-meta-links').should('exist').get('.cookie-settings').should('exist');
diff --git a/packages/internet-header/cypress/e2e/header.cy.ts b/packages/internet-header/cypress/e2e/header.cy.ts
index 07ea692d15..23b53103ff 100644
--- a/packages/internet-header/cypress/e2e/header.cy.ts
+++ b/packages/internet-header/cypress/e2e/header.cy.ts
@@ -2,7 +2,8 @@ import { prepare } from '../support/prepare-story';
describe('header', () => {
beforeEach(() => {
- prepare('Internet Header/Header Component', 'Default');
+ prepare('Internet Header/Header', 'Default');
+ cy.changeArg('language', 'de');
});
context('initial state', () => {
@@ -10,10 +11,6 @@ describe('header', () => {
cy.get('swisspost-internet-header').should('have.class', 'hydrated');
});
- it(`has title 'Swiss Post Internet Header'`, () => {
- cy.get('h1').should('contain.text', 'Swiss Post Internet Header');
- });
-
it(`has nav item 'Briefe versenden' selected`, () => {
cy.changeArg('active-route', 'https://post.ch/de/briefe-versenden');
cy.get('swisspost-internet-header')
diff --git a/packages/internet-header/cypress/e2e/language-detection.cy.ts b/packages/internet-header/cypress/e2e/language-detection.cy.ts
index 1bfbfce648..6823c7d823 100644
--- a/packages/internet-header/cypress/e2e/language-detection.cy.ts
+++ b/packages/internet-header/cypress/e2e/language-detection.cy.ts
@@ -3,7 +3,7 @@ import { prepare } from '../support/prepare-story';
describe('language detection from storybook', () => {
it('should not render the header without languages in the config', () => {
- prepare('Internet Header/Header Component', 'Default', {});
+ prepare('Internet Header/Header', 'Default', {});
cy.get('swisspost-internet-header').should('exist');
cy.get('.post-internet-header').should('not.exist');
});
@@ -15,7 +15,7 @@ describe('language detection from storybook', () => {
delete customConfig.fr;
delete customConfig.en;
- prepare('Internet Header/Header Component', 'Default', customConfig);
+ prepare('Internet Header/Header', 'Default', customConfig);
cy.get('swisspost-internet-header')
.shadow()
diff --git a/packages/internet-header/cypress/e2e/language-switch.cy.ts b/packages/internet-header/cypress/e2e/language-switch.cy.ts
index a1a40ba17a..640e07027f 100644
--- a/packages/internet-header/cypress/e2e/language-switch.cy.ts
+++ b/packages/internet-header/cypress/e2e/language-switch.cy.ts
@@ -7,11 +7,10 @@ describe('language-switch', () => {
const languageSwitcherDesktop = '#post-language-switch-desktop';
const languageSwitchDropdown = 'nav.language-switch-dropdown';
- before(() => {});
-
beforeEach(() => {
cy.viewport(1024, 800);
- prepare('Internet Header/Header Component', 'Default');
+ prepare('Internet Header/Header', 'Default');
+ cy.changeArg('language', 'de');
});
describe('meta menu', () => {
@@ -91,8 +90,8 @@ describe('language-switch', () => {
cy.get(languageSwitcherDesktop)
.shadow()
.find('button.lang-btn')
- .click()
- .get('button[lang="en"]')
+ .click();
+ cy.get('button[lang="en"]')
.first()
.click()
.then(() => {
@@ -144,7 +143,7 @@ describe('language-switch', () => {
url: '',
};
config.en!.header.navLang = [navLangEntry];
- prepare('Internet Header/Header Component', 'Default', config);
+ prepare('Internet Header/Header', 'Default', config);
cy.get('#post-language-switch-desktop').should('not.exist');
});
diff --git a/packages/internet-header/cypress/e2e/login.cy.ts b/packages/internet-header/cypress/e2e/login.cy.ts
index 588c912fec..7941fe2ff7 100644
--- a/packages/internet-header/cypress/e2e/login.cy.ts
+++ b/packages/internet-header/cypress/e2e/login.cy.ts
@@ -6,7 +6,7 @@ describe('login', () => {
describe('args', () => {
describe('login: true', () => {
it(`adds login control`, () => {
- prepare('Internet Header/Header Component', 'Default');
+ prepare('Internet Header/Header', 'Default');
cy.changeArg('login', true);
cy.get('post-klp-login-widget').should('exist').and('be.visible');
});
@@ -14,7 +14,7 @@ describe('login', () => {
describe('login: false', () => {
it(`removes login control`, () => {
- prepare('Internet Header/Header Component', 'Default');
+ prepare('Internet Header/Header', 'Default');
cy.changeArg('login', false);
cy.get('post-klp-login-widget').should('not.exist');
});
@@ -31,7 +31,8 @@ describe('login', () => {
config.de!.header.loginWidgetOptions = undefined;
// Intercept the request to the config API and return a static response
- prepare('Internet Header/Header Component', 'Default', config);
+ prepare('Internet Header/Header', 'Default', config);
+ cy.changeArg('language', 'de');
// Assert the header is hydrated
cy.get('swisspost-internet-header').should('have.class', 'hydrated');
@@ -48,7 +49,8 @@ describe('login', () => {
let config: IPortalConfig = JSON.parse(JSON.stringify(testConfiguration));
config.de!.header.showJobsLoginWidget = true;
config.de!.header.isLoginWidgetHidden = false;
- prepare('Internet Header/Header Component', 'Default', config);
+ prepare('Internet Header/Header', 'Default', config);
+ cy.changeArg('language', 'de');
console.warn(config.de?.header.loginWidgetOptions);
cy.get('swisspost-internet-header').should('have.class', 'hydrated');
cy.get('a.login-button').should('exist').and('be.visible');
@@ -61,7 +63,8 @@ describe('login', () => {
let config: IPortalConfig = JSON.parse(JSON.stringify(testConfiguration));
config.de!.header.showJobsLoginWidget = false;
config.de!.header.isLoginWidgetHidden = false;
- prepare('Internet Header/Header Component', 'Default', config);
+ prepare('Internet Header/Header', 'Default', config);
+ cy.changeArg('language', 'de');
cy.get('swisspost-internet-header').should('have.class', 'hydrated');
cy.get('.klp-widget-anonymous').should('exist');
});
diff --git a/packages/internet-header/cypress/e2e/main-navigation.cy.ts b/packages/internet-header/cypress/e2e/main-navigation.cy.ts
index 97b7ae0f8d..55e2756313 100644
--- a/packages/internet-header/cypress/e2e/main-navigation.cy.ts
+++ b/packages/internet-header/cypress/e2e/main-navigation.cy.ts
@@ -3,7 +3,8 @@ import { prepare } from '../support/prepare-story';
describe('main-navigation', () => {
beforeEach(() => {
- prepare('Internet Header/Header Component', 'Default');
+ prepare('Internet Header/Header', 'Default');
+ cy.changeArg('language', 'de');
});
it('should not have any highlight when active route is false', async () => {
@@ -27,7 +28,8 @@ describe('main-navigation', () => {
it('should have an active route when config defines an active route', () => {
const activeConfig = JSON.parse(JSON.stringify(testConfiguration));
activeConfig.de.header.navMain[0].isActive = true;
- prepare('Internet Header/Header Component', 'Default', activeConfig);
+ prepare('Internet Header/Header', 'Default', activeConfig);
+ cy.changeArg('language', 'de');
cy.get('swisspost-internet-header')
.shadow()
.find('.flyout-link.active, .main-link.active')
@@ -46,7 +48,7 @@ describe('main-navigation', () => {
});
it('Changes active link also in custom config nav links', () => {
- prepare('Internet Header/Header Component', 'Custom Navigation');
+ prepare('Internet Header/Header/Custom Config', 'Default');
cy.changeArg('language', 'en');
cy.changeArg('active-route', 'https://maps.google.com');
cy.get('swisspost-internet-header')
diff --git a/packages/internet-header/cypress/e2e/meta-navigation.cy.ts b/packages/internet-header/cypress/e2e/meta-navigation.cy.ts
index 83b088c0e7..0240242573 100644
--- a/packages/internet-header/cypress/e2e/meta-navigation.cy.ts
+++ b/packages/internet-header/cypress/e2e/meta-navigation.cy.ts
@@ -4,7 +4,8 @@ import { prepare } from '../support/prepare-story';
describe('meta-navigation', () => {
beforeEach(() => {
- prepare('Internet Header/Header Component', 'Default');
+ prepare('Internet Header/Header', 'Default');
+ cy.changeArg('language', 'de');
cy.viewport(1024, Cypress.config('viewportHeight'));
});
@@ -95,7 +96,8 @@ describe('meta-navigation', () => {
// Clear meta navigation config
config.de!.header.navMeta = undefined;
- prepare('Internet Header/Header Component', 'Default', config);
+ prepare('Internet Header/Header', 'Default', config);
+ cy.changeArg('language', 'de');
// Assert the header is hydrated
cy.get('swisspost-internet-header').should('have.class', 'hydrated');
@@ -120,7 +122,8 @@ describe('meta-navigation', () => {
},
];
- prepare('Internet Header/Header Component', 'Default', config);
+ prepare('Internet Header/Header', 'Default', config);
+ cy.changeArg('language', 'de');
// Assert the header is hydrated
cy.get('swisspost-internet-header').should('have.class', 'hydrated');
diff --git a/packages/internet-header/cypress/e2e/os-flyout.cy.ts b/packages/internet-header/cypress/e2e/os-flyout.cy.ts
index c31d28037a..097d30ada6 100644
--- a/packages/internet-header/cypress/e2e/os-flyout.cy.ts
+++ b/packages/internet-header/cypress/e2e/os-flyout.cy.ts
@@ -2,7 +2,7 @@ import { prepare } from '../support/prepare-story';
describe('os-flyout', () => {
beforeEach(() => {
- prepare('Internet Header/Header Component', 'Default');
+ prepare('Internet Header/Header', 'Default');
});
it('should customize the os flyout title', () => {
const title = 'Test OS Flyout';
diff --git a/packages/internet-header/cypress/e2e/search.cy.ts b/packages/internet-header/cypress/e2e/search.cy.ts
index eaf58cdec3..a60c0ceffa 100644
--- a/packages/internet-header/cypress/e2e/search.cy.ts
+++ b/packages/internet-header/cypress/e2e/search.cy.ts
@@ -17,12 +17,14 @@ describe('search', () => {
cy.intercept('**/StandortSuche/StaoCacheService/Types**', mockStaoCacheTypes).as(
'StaoCacheTypes',
);
+
+ prepare('Internet Header/Header', 'Default');
+ cy.changeArg('language', 'de');
});
describe('config', () => {
describe('default', () => {
it('Search button should not be displayed if the config does not provide a search config', () => {
- prepare('Internet Header/Header Component', 'Default');
cy.changeArg('search', false);
cy.get('swisspost-internet-header').should('exist');
cy.get('post-search').should('not.exist');
@@ -33,14 +35,12 @@ describe('search', () => {
describe('args', () => {
describe('search: true', () => {
it(`adds search control`, () => {
- prepare('Internet Header/Header Component', 'Default');
cy.get('post-search').should('exist').and('be.visible');
});
});
describe('search: false', () => {
it(`removes search control`, () => {
- prepare('Internet Header/Header Component', 'Default');
cy.changeArg('search', false);
cy.get('post-search').should('not.exist');
});
@@ -48,7 +48,6 @@ describe('search', () => {
describe('Search button should be hidden if header.search = false is set during runtime', () => {
it(`change during runtime`, () => {
- prepare('Internet Header/Header Component', 'Default');
cy.changeArg('search', false);
cy.get('post-search').should('not.exist');
cy.changeArg('search', true);
@@ -60,14 +59,12 @@ describe('search', () => {
describe('open & close', () => {
describe('open search', () => {
it('search should open on search button click', () => {
- prepare('Internet Header/Header Component', 'Default');
cy.changeArg('search', true);
cy.get(searchButton).click({ force: true });
cy.get('.flyout').should('exist').should('have.class', 'open');
});
it('Coveo suggestions should be loaded when search is opened', () => {
- prepare('Internet Header/Header Component', 'Default');
cy.changeArg('search', true);
cy.get(searchButton).click();
cy.get('#searchBox').type('s', { force: true });
@@ -78,7 +75,8 @@ describe('search', () => {
it('Coveo suggestions should be turned off with isCustomSuggestionHidden', () => {
const config = copyConfig();
config.de!.header.search.isCustomSuggestionHidden = true;
- prepare('Internet Header/Header Component', 'Default', config);
+ prepare('Internet Header/Header', 'Default', config);
+ cy.changeArg('language', 'de');
cy.get(searchButton).click();
cy.get('#searchBox').type('s', { force: true });
cy.get('.suggestions').should('exist');
@@ -88,7 +86,6 @@ describe('search', () => {
describe('close search', () => {
it('Search should close on esc key click', () => {
- prepare('Internet Header/Header Component', 'Default');
cy.changeArg('search', true);
cy.get(searchButton).click();
cy.get('#searchBox')
@@ -99,7 +96,6 @@ describe('search', () => {
});
it('Search should close on search button click', () => {
- prepare('Internet Header/Header Component', 'Default');
cy.changeArg('search', true);
cy.get(searchButton).click({ force: true });
cy.get('.flyout').should('exist');
@@ -117,7 +113,6 @@ describe('search', () => {
);
});
it('Search should redirect to search page on enter if search input has a value', () => {
- prepare('Internet Header/Header Component', 'Default');
cy.changeArg('search', true);
cy.get(searchButton).click({ force: true });
// workaround type error disabled with this https://github.com/cypress-io/cypress/issues/5827
@@ -129,7 +124,6 @@ describe('search', () => {
});
it('With suggestions and focus on the search input, pressing arrow down should focus the first suggestion', () => {
- prepare('Internet Header/Header Component', 'Default');
let value: string;
cy.changeArg('search', true);
cy.get(searchButton).click();
@@ -144,7 +138,6 @@ describe('search', () => {
});
it('Should render geolocation results', () => {
- prepare('Internet Header/Header Component', 'Default');
cy.changeArg('search', true);
cy.get(searchButton).click();
cy.get('#searchBox').click();
@@ -154,7 +147,6 @@ describe('search', () => {
});
it('redirects to the correct search page', () => {
- prepare('Internet Header/Header Component', 'Default');
cy.changeArg('search', true);
cy.get(searchButton).click();
cy.get('#searchBox').click().type('{downArrow}', { force: true });
diff --git a/packages/internet-header/cypress/e2e/skiplinks.cy.ts b/packages/internet-header/cypress/e2e/skiplinks.cy.ts
index 068769bc5b..b6e6405b9d 100644
--- a/packages/internet-header/cypress/e2e/skiplinks.cy.ts
+++ b/packages/internet-header/cypress/e2e/skiplinks.cy.ts
@@ -2,7 +2,8 @@ import { prepare } from '../support/prepare-story';
describe('skiplinks', () => {
beforeEach(() => {
- prepare('Internet Header/Header Component', 'Default');
+ prepare('Internet Header/Header', 'Default');
+ cy.changeArg('language', 'de')
});
it(`adds and removes skiplinks control`, () => {
diff --git a/packages/internet-header/cypress/e2e/stickyness.cy.ts b/packages/internet-header/cypress/e2e/stickyness.cy.ts
index cf1d0f88d0..37187ce37b 100644
--- a/packages/internet-header/cypress/e2e/stickyness.cy.ts
+++ b/packages/internet-header/cypress/e2e/stickyness.cy.ts
@@ -2,29 +2,33 @@ import { prepare } from '../support/prepare-story';
describe('stickyness', () => {
beforeEach(() => {
- prepare('Internet Header/Header Component', 'Default');
+ prepare('Internet Header/Header', 'Default');
});
it('should not show header when scrolling when stickyness is none', () => {
cy.get('swisspost-internet-header').should('be.inViewport');
cy.changeArg('stickyness', 'none');
cy.wait(10);
- cy.scrollTo('bottom');
+ cy.get('.header-story-wrapper').scrollTo('bottom');
cy.get('swisspost-internet-header').should('not.be.inViewport');
});
it('should not show header when scrolling down with stickyness minimal, should show header without meta when scrolling up a little', () => {
cy.changeArg('stickyness', 'minimal');
cy.get('post-meta-navigation').should('be.inViewport');
- cy.scrollTo('bottom');
- cy.get('swisspost-internet-footer').should('be.inViewport');
+ cy.get('.header-story-wrapper').scrollTo('bottom');
+ cy.get('.fake-content:last-of-type').should('be.inViewport');
cy.get('swisspost-internet-header').should('not.be.inViewport');
cy.get('post-meta-navigation').should('not.be.inViewport');
- cy.scrollTo('center');
- cy.scrollTo(0, -20);
+ cy.get('.header-story-wrapper').scrollTo('center', { duration: 10 });
+ cy.get('.header-story-wrapper').then($el => {
+ const el = $el.get(0); //native DOM element
+ el.scrollTo(0, el.scrollTop - 20);
+ });
+ cy.get('post-main-navigation').should('be.visible');
cy.get('post-main-navigation').should('be.inViewport');
cy.get('post-meta-navigation').should('not.be.inViewport');
- cy.scrollTo('top');
+ cy.get('.header-story-wrapper').scrollTo('top');
cy.get('swisspost-internet-header').should('be.inViewport');
cy.get('post-meta-navigation').should('be.inViewport');
});
@@ -33,7 +37,7 @@ describe('stickyness', () => {
cy.changeArg('stickyness', 'main');
cy.get('swisspost-internet-header').should('be.inViewport');
cy.get('post-meta-navigation').should('be.inViewport');
- cy.scrollTo('bottom');
+ cy.get('.header-story-wrapper').scrollTo('bottom');
cy.get('swisspost-internet-header').should('be.inViewport');
cy.get('post-meta-navigation').should('not.be.inViewport');
});
@@ -42,7 +46,7 @@ describe('stickyness', () => {
cy.changeArg('stickyness', 'full');
cy.get('swisspost-internet-header').should('be.inViewport');
cy.get('post-meta-navigation').should('be.inViewport');
- cy.scrollTo('bottom');
+ cy.get('.header-story-wrapper').scrollTo('bottom');
cy.get('swisspost-internet-header').should('be.inViewport');
cy.get('post-meta-navigation').should('be.inViewport');
});
diff --git a/packages/internet-header/cypress/support/prepare-story.ts b/packages/internet-header/cypress/support/prepare-story.ts
index c7b0dfd3ba..deaec1446e 100644
--- a/packages/internet-header/cypress/support/prepare-story.ts
+++ b/packages/internet-header/cypress/support/prepare-story.ts
@@ -15,10 +15,9 @@ export const prepare = (
) => {
installInterceptors(config);
cy.visitStorybook();
- cy.get('[class=sb-nopreview_main]', { timeout: 30000 }).should('be.visible'); // Wait until vite is ready (initial loading is longer)
+ cy.get('.sb-nopreview_main', { timeout: 30000 }).should('be.visible'); // Wait until vite is ready (initial loading is longer)
cy.loadStory(storyTitle, storyName);
- cy.get('[id=storybook-root]', { timeout: 30000 }).should('be.visible'); // Ensure that we have a storybook component loaded, before going further
- cy.changeArg('language', 'de');
+ cy.get('#root-inner', { timeout: 30000 }).should('exist'); // Ensure that we have a storybook component loaded, before going further
};
export const copyConfig = (): IPortalConfig => {
diff --git a/packages/internet-header/src/components.d.ts b/packages/internet-header/src/components.d.ts
index 699c0c7dff..a15b739486 100644
--- a/packages/internet-header/src/components.d.ts
+++ b/packages/internet-header/src/components.d.ts
@@ -102,7 +102,7 @@ export namespace Components {
/**
* Initial language to be used. Overrides automatic language detection.
*/
- "language"?: string;
+ "language"?: 'de' | 'fr' | 'it' | 'en';
/**
* The header uses this cookie to set the language. Disables automatic language detection.
*/
@@ -287,7 +287,7 @@ declare namespace LocalJSX {
/**
* Initial language to be used. Overrides automatic language detection.
*/
- "language"?: string;
+ "language"?: 'de' | 'fr' | 'it' | 'en';
/**
* The header uses this cookie to set the language. Disables automatic language detection.
*/
diff --git a/packages/internet-header/src/components/post-internet-header/logo-animation/logo-animation.ts b/packages/internet-header/src/components/post-internet-header/logo-animation/logo-animation.ts
index ce95ceadcd..310e6dbd23 100644
--- a/packages/internet-header/src/components/post-internet-header/logo-animation/logo-animation.ts
+++ b/packages/internet-header/src/components/post-internet-header/logo-animation/logo-animation.ts
@@ -1,10 +1,13 @@
import { debounce } from 'throttle-debounce';
import { state } from '../../../data/store';
+import { getScrollParent } from '../../../utils/scrollparent';
export const registerLogoAnimationObserver = (
target: HTMLElement,
headerRef: HTMLSwisspostInternetHeaderElement,
) => {
+ const scrollParent = getScrollParent(headerRef);
+
/**
* Set intersection ratio as CSS custom property
*/
@@ -13,7 +16,8 @@ export const registerLogoAnimationObserver = (
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;
+ const scrollDistance = scrollParent instanceof Element ? scrollParent.scrollTop : scrollParent.documentElement.scrollTop;
+ const scrollY = fullStickyness ? 0 : scrollDistance;
// If meta navigation is not visible (mobile, not configured), scale should just be 1
if (target.clientHeight > 0) {
@@ -36,13 +40,13 @@ export const registerLogoAnimationObserver = (
entries => {
entries.forEach(entry => {
if (entry.isIntersecting && entry.intersectionRatio > 0) {
- window.addEventListener('scroll', handleScroll, { passive: true });
+ scrollParent.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);
+ scrollParent.removeEventListener('scroll', handleScroll);
window.removeEventListener('resize', debounced);
window.requestAnimationFrame(handleScroll);
}
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 20e8bf286b..2610ab463e 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
@@ -1,15 +1,15 @@
import {
Component,
- Host,
Element,
+ Event,
+ EventEmitter,
h,
- State,
- Prop,
- Watch,
+ Host,
Listen,
- EventEmitter,
- Event,
Method,
+ Prop,
+ State,
+ Watch,
} from '@stencil/core';
import { debounce, throttle } from 'throttle-debounce';
import {
@@ -17,17 +17,18 @@ import {
getLocalizedCustomConfig,
isValidProjectId,
} from '../../services/config.service';
-import { state, dispose } from '../../data/store';
+import { dispose, state } from '../../data/store';
import { DropdownElement, DropdownEvent, NavMainEntity } from '../../models/header.model';
import { SvgSprite } from '../../utils/svg-sprite.component';
import { SvgIcon } from '../../utils/svg-icon.component';
import { StickynessOptions } from '../../models/implementor.model';
import { ActiveRouteProp, Environment, ICustomConfig } from '../../models/general.model';
import { IAvailableLanguage } from '../../models/language.model';
-import { translate } from '../../services/language.service';
+import { getUserLang, translate } from '../../services/language.service';
import { If } from '../../utils/if.component';
import packageJson from '../../../package.json';
import { registerLogoAnimationObserver } from './logo-animation/logo-animation';
+import { getScrollParent } from '../../utils/scrollparent';
@Component({
tag: 'swisspost-internet-header',
@@ -48,7 +49,7 @@ export class PostInternetHeader {
/**
* Initial language to be used. Overrides automatic language detection.
*/
- @Prop() language?: string;
+ @Prop() language?: 'de' | 'fr' | 'it' | 'en';
/**
* Toggle the meta navigation.
@@ -142,6 +143,7 @@ export class PostInternetHeader {
private debouncedResize: debounce<() => void>;
private lastWindowWidth: number = window.innerWidth;
private updateLogoAnimation: () => void;
+ private scrollParent: Element | Document;
constructor() {
if (this.project === undefined || this.project === '' || !isValidProjectId(this.project)) {
@@ -154,19 +156,21 @@ export class PostInternetHeader {
connectedCallback() {
this.throttledScroll = throttle(300, () => this.handleScrollEvent());
this.debouncedResize = debounce(200, () => this.handleResize());
- window.addEventListener('scroll', this.throttledScroll, { passive: true });
- window.addEventListener('resize', this.debouncedResize, { passive: true });
}
disconnectedCallback() {
- window.removeEventListener('scroll', this.throttledScroll);
- window.removeEventListener('resize', this.debouncedResize);
+ this.scrollParent.removeEventListener('scroll', this.throttledScroll);
+ this.scrollParent.removeEventListener('resize', this.debouncedResize);
// Reset the store to its original state
dispose();
}
async componentWillLoad() {
+ this.scrollParent = getScrollParent(this.host);
+ this.scrollParent.addEventListener('scroll', this.throttledScroll, { passive: true });
+ this.scrollParent.addEventListener('resize', this.debouncedResize, { passive: true });
+
// Wait for the config to arrive, then render the header
try {
state.projectId = this.project;
@@ -182,11 +186,12 @@ export class PostInternetHeader {
? JSON.parse(this.osFlyoutOverrides)
: this.osFlyoutOverrides;
- if (this.customConfig !== undefined && state.currentLanguage !== null) {
- state.localizedCustomConfig = getLocalizedCustomConfig(
- this.customConfig,
- state.currentLanguage,
+ if (this.customConfig !== undefined) {
+ const langs = Object.keys(
+ typeof this.customConfig === 'string' ? JSON.parse(this.customConfig) : this.customConfig,
);
+ const lang = state.currentLanguage || getUserLang(langs, this.language);
+ state.localizedCustomConfig = getLocalizedCustomConfig(this.customConfig, lang);
}
state.localizedConfig = await getLocalizedConfig({
@@ -309,7 +314,7 @@ export class PostInternetHeader {
@Watch('stickyness')
handleStickynessChange(newValue: StickynessOptions) {
state.stickyness = newValue;
- this.updateLogoAnimation();
+ if (typeof this.updateLogoAnimation === 'function') this.updateLogoAnimation();
}
private handleClickOutsideBound = this.handleClickOutside.bind(this);
@@ -334,7 +339,10 @@ export class PostInternetHeader {
private handleScrollEvent() {
// Credits: "https://github.com/qeremy/so/blob/master/so.dom.js#L426"
- const st = window.scrollY || document.documentElement.scrollTop;
+ const st =
+ this.scrollParent instanceof Document
+ ? this.scrollParent.documentElement.scrollTop
+ : this.scrollParent.scrollTop;
// Toggle class without re-rendering the component if stickyness is minimal
// the other stickyness modes do not need the class
diff --git a/packages/internet-header/src/components/post-internet-header/readme.md b/packages/internet-header/src/components/post-internet-header/readme.md
index 43c821fa9e..7c4106d1d3 100644
--- a/packages/internet-header/src/components/post-internet-header/readme.md
+++ b/packages/internet-header/src/components/post-internet-header/readme.md
@@ -14,7 +14,7 @@
| `customConfig` | `custom-config` | Customize the header config loaded from the post portal. | `ICustomConfig \| string \| undefined` | `undefined` |
| `environment` | `environment` | Target environment. Choose 'int01' for local testing. | `"dev01" \| "dev02" \| "devs1" \| "int01" \| "int02" \| "prod" \| "test"` | `'prod'` |
| `fullWidth` | `full-width` | Displays the header at full width for full-screen applications | `boolean \| undefined` | `false` |
-| `language` | `language` | Initial language to be used. Overrides automatic language detection. | `string \| undefined` | `undefined` |
+| `language` | `language` | Initial language to be used. Overrides automatic language detection. | `"de" \| "en" \| "fr" \| "it" \| undefined` | `undefined` |
| `languageCookieKey` | `language-cookie-key` | The header uses this cookie to set the language. Disables automatic language detection. | `string \| undefined` | `undefined` |
| `languageLocalStorageKey` | `language-local-storage-key` | The header uses this local storage key to set the language. Disables automatic language selection. | `string \| undefined` | `'swisspost-internet-header-language'` |
| `languageSwitchOverrides` | `language-switch-overrides` | Override the language switch links with custom URLs. Helpful when your application contains sub-pages and you would like to stay on subpages when the user changes language. | `IAvailableLanguage[] \| string \| undefined` | `undefined` |
diff --git a/packages/internet-header/src/services/language.service.ts b/packages/internet-header/src/services/language.service.ts
index 9a24181a73..d2317b32ce 100644
--- a/packages/internet-header/src/services/language.service.ts
+++ b/packages/internet-header/src/services/language.service.ts
@@ -9,7 +9,7 @@ export const getUserLang = (
) => {
// If there are no supported languages, well...
if (supportedLanguages.length === 0) {
- return undefined;
+ return 'de';
}
// If there is only one language in the config, use this
diff --git a/packages/internet-header/src/utils/scrollparent.ts b/packages/internet-header/src/utils/scrollparent.ts
new file mode 100644
index 0000000000..b7eb61838b
--- /dev/null
+++ b/packages/internet-header/src/utils/scrollparent.ts
@@ -0,0 +1,21 @@
+const isScrollable = (node: Element) => {
+ if (!(node instanceof HTMLElement || node instanceof SVGElement)) {
+ return false;
+ }
+ const style = getComputedStyle(node);
+ return ['overflow', 'overflow-x', 'overflow-y'].some(propertyName => {
+ const value = style.getPropertyValue(propertyName);
+ return value === 'auto' || value === 'scroll';
+ });
+};
+
+export const getScrollParent = (node: Element): Element | Document => {
+ let currentParent = node.parentElement;
+ while (currentParent) {
+ if (isScrollable(currentParent)) {
+ return currentParent;
+ }
+ currentParent = currentParent.parentElement;
+ }
+ return document;
+};
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 625939ca9e..f5817b6521 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -511,7 +511,7 @@ importers:
version: 7.4.3(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0)
'@storybook/addon-designs':
specifier: 7.0.5
- version: 7.0.5(@storybook/addon-docs@7.4.0)(@storybook/addons@7.4.3)(@storybook/components@7.4.3)(@storybook/manager-api@7.4.3)(@storybook/preview-api@7.4.3)(@storybook/theming@7.4.3)(react-dom@18.2.0)(react@18.2.0)
+ version: 7.0.5(@storybook/addon-docs@7.4.3)(@storybook/addons@7.4.3)(@storybook/components@7.4.3)(@storybook/manager-api@7.4.3)(@storybook/preview-api@7.4.3)(@storybook/theming@7.4.3)(react-dom@18.2.0)(react@18.2.0)
'@storybook/addon-essentials':
specifier: 7.4.3
version: 7.4.3(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0)
@@ -6978,7 +6978,7 @@ packages:
- supports-color
dev: true
- /@storybook/addon-designs@7.0.5(@storybook/addon-docs@7.4.0)(@storybook/addons@7.4.3)(@storybook/components@7.4.3)(@storybook/manager-api@7.4.3)(@storybook/preview-api@7.4.3)(@storybook/theming@7.4.3)(react-dom@18.2.0)(react@18.2.0):
+ /@storybook/addon-designs@7.0.5(@storybook/addon-docs@7.4.3)(@storybook/addons@7.4.3)(@storybook/components@7.4.3)(@storybook/manager-api@7.4.3)(@storybook/preview-api@7.4.3)(@storybook/theming@7.4.3)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-yB1YwkVhnTI28mS+00avAf7vPAppZi2pdXQF91725g+RoiM7llY87q+c1z2/YiQNQYNm2QXpYcrcYiLQzyr0NQ==}
peerDependencies:
'@storybook/addon-docs': ^7.0.0
@@ -6996,7 +6996,7 @@ packages:
optional: true
dependencies:
'@figspec/react': 1.0.3(react@18.2.0)
- '@storybook/addon-docs': 7.4.0(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0)
+ '@storybook/addon-docs': 7.4.3(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0)
'@storybook/addons': 7.4.3(react-dom@18.2.0)(react@18.2.0)
'@storybook/components': 7.4.3(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0)
'@storybook/manager-api': 7.4.3(react-dom@18.2.0)(react@18.2.0)
@@ -7006,40 +7006,6 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: true
- /@storybook/addon-docs@7.4.0(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-LJE92LUeVTgi8W4tLBEbSvCqF54snmBfTFCr46vhCFov2CE2VBgEvIX1XT3dfUgYUOtPu3RXR2C89fYgU6VYZw==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- dependencies:
- '@jest/transform': 29.6.4
- '@mdx-js/react': 2.3.0(react@18.2.0)
- '@storybook/blocks': 7.4.0(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0)
- '@storybook/client-logger': 7.4.0
- '@storybook/components': 7.4.0(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0)
- '@storybook/csf-plugin': 7.4.0
- '@storybook/csf-tools': 7.4.0
- '@storybook/global': 5.0.0
- '@storybook/mdx2-csf': 1.1.0
- '@storybook/node-logger': 7.4.0
- '@storybook/postinstall': 7.4.0
- '@storybook/preview-api': 7.4.0
- '@storybook/react-dom-shim': 7.4.0(react-dom@18.2.0)(react@18.2.0)
- '@storybook/theming': 7.4.0(react-dom@18.2.0)(react@18.2.0)
- '@storybook/types': 7.4.0
- fs-extra: 11.1.1
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- remark-external-links: 8.0.0
- remark-slug: 6.1.0
- ts-dedent: 2.2.0
- transitivePeerDependencies:
- - '@types/react'
- - '@types/react-dom'
- - encoding
- - supports-color
- dev: true
-
/@storybook/addon-docs@7.4.3(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-c6r1nJY4fj/Uj9p7jHdicAS7quiK9RY0LJw+aB++FvcO1KavX33BlD2mxPIVU8a9oLJ3X4RUfNQz+OSABGy0xw==}
peerDependencies:
@@ -7278,44 +7244,6 @@ packages:
util-deprecate: 1.0.2
dev: true
- /@storybook/blocks@7.4.0(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-YQznNjJm+l32fCfPxrZso9+MbcyG0pWZSpx3RKI1+pxDMsAs4mbXsIw4//jKfjoDP/6/Cz/FJcSx8LT7i4BJ2w==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- dependencies:
- '@storybook/channels': 7.4.0
- '@storybook/client-logger': 7.4.0
- '@storybook/components': 7.4.0(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0)
- '@storybook/core-events': 7.4.0
- '@storybook/csf': 0.1.0
- '@storybook/docs-tools': 7.4.0
- '@storybook/global': 5.0.0
- '@storybook/manager-api': 7.4.0(react-dom@18.2.0)(react@18.2.0)
- '@storybook/preview-api': 7.4.0
- '@storybook/theming': 7.4.0(react-dom@18.2.0)(react@18.2.0)
- '@storybook/types': 7.4.0
- '@types/lodash': 4.14.194
- color-convert: 2.0.1
- dequal: 2.0.3
- lodash: 4.17.21
- markdown-to-jsx: 7.2.1(react@18.2.0)
- memoizerific: 1.11.3
- polished: 4.2.2
- react: 18.2.0
- react-colorful: 5.6.1(react-dom@18.2.0)(react@18.2.0)
- react-dom: 18.2.0(react@18.2.0)
- telejson: 7.2.0
- tocbot: 4.21.0
- ts-dedent: 2.2.0
- util-deprecate: 1.0.2
- transitivePeerDependencies:
- - '@types/react'
- - '@types/react-dom'
- - encoding
- - supports-color
- dev: true
-
/@storybook/blocks@7.4.3(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-uyZVx3er1qOPFpKJtsbozBwt1Os3zqiq+2se7xDBK6ERr07zaRHLgRci7+kI8T5mdlCxYiGV+kzx5Vx5/7XaXg==}
peerDependencies:
@@ -7427,17 +7355,6 @@ packages:
util-deprecate: 1.0.2
dev: true
- /@storybook/channels@7.4.0:
- resolution: {integrity: sha512-/1CU0s3npFumzVHLGeubSyPs21O3jNqtSppOjSB9iDTyV2GtQrjh5ntVwebfKpCkUSitx3x7TkCb9dylpEZ8+w==}
- dependencies:
- '@storybook/client-logger': 7.4.0
- '@storybook/core-events': 7.4.0
- '@storybook/global': 5.0.0
- qs: 6.11.2
- telejson: 7.2.0
- tiny-invariant: 1.3.1
- dev: true
-
/@storybook/channels@7.4.3:
resolution: {integrity: sha512-lIoRX3EV0wKPX8ojIrJUtsOv4+Gv8r9pfJpam/NdyYd+rs0AjDK13ieINRfBMnJkfjsWa3vmZtGMBEVvDKwTMw==}
dependencies:
@@ -7508,12 +7425,6 @@ packages:
global: 4.4.0
dev: true
- /@storybook/client-logger@7.4.0:
- resolution: {integrity: sha512-4pBnf7+df1wXEVcF1civqxbrtccGGHQkfWQkJo49s53RXvF7SRTcif6XTx0V3cQV0v7I1C5mmLm0LNlmjPRP1Q==}
- dependencies:
- '@storybook/global': 5.0.0
- dev: true
-
/@storybook/client-logger@7.4.3:
resolution: {integrity: sha512-Nhngo9X4HjN00aRhgIVGWbwkWPe0Fz8PySuxnd8nAxSsz7KpdLFyYo2TbZZ3TX51FG5Fxcb0G5OHuunItP7EWQ==}
dependencies:
@@ -7541,29 +7452,6 @@ packages:
- supports-color
dev: true
- /@storybook/components@7.4.0(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-GGnQrI4NXwri/PqNjhO1vNv4tC7RBjY87ce9WHBq1ueat3kBakdqV97NzScoldXarkkKK6grBqmhw9jE5PfzhQ==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- dependencies:
- '@radix-ui/react-select': 1.2.2(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0)
- '@radix-ui/react-toolbar': 1.0.4(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0)
- '@storybook/client-logger': 7.4.0
- '@storybook/csf': 0.1.0
- '@storybook/global': 5.0.0
- '@storybook/theming': 7.4.0(react-dom@18.2.0)(react@18.2.0)
- '@storybook/types': 7.4.0
- memoizerific: 1.11.3
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- use-resize-observer: 9.1.0(react-dom@18.2.0)(react@18.2.0)
- util-deprecate: 1.0.2
- transitivePeerDependencies:
- - '@types/react'
- - '@types/react-dom'
- dev: true
-
/@storybook/components@7.4.3(@types/react@18.2.22)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-qwRW8wGUuM+H6oKUXXoIDrZECXh/lzowrWXFAzZiocovYEhPtZfl/yvJLWHjOwtka3n7lA7J7EtcjWe8/tueJQ==}
peerDependencies:
@@ -7594,36 +7482,6 @@ packages:
'@storybook/preview-api': 7.4.3
dev: true
- /@storybook/core-common@7.4.0:
- resolution: {integrity: sha512-QKrBL46ZFdfTjlZE3f7b59Q5+frOHWIJ64sC9BZ2PHkZkGjFeYRDdJJ6EHLYBb+nToynl33dYN1GQz+hQn2vww==}
- dependencies:
- '@storybook/node-logger': 7.4.0
- '@storybook/types': 7.4.0
- '@types/find-cache-dir': 3.2.1
- '@types/node': 16.18.39
- '@types/node-fetch': 2.6.5
- '@types/pretty-hrtime': 1.0.1
- chalk: 4.1.2
- esbuild: 0.18.17
- esbuild-register: 3.4.2(esbuild@0.18.17)
- file-system-cache: 2.3.0
- find-cache-dir: 3.3.2
- find-up: 5.0.0
- fs-extra: 11.1.1
- glob: 10.3.5
- handlebars: 4.7.7
- lazy-universal-dotenv: 4.0.0
- node-fetch: 2.7.0
- picomatch: 2.3.1
- pkg-dir: 5.0.0
- pretty-hrtime: 1.0.3
- resolve-from: 5.0.0
- ts-dedent: 2.2.0
- transitivePeerDependencies:
- - encoding
- - supports-color
- dev: true
-
/@storybook/core-common@7.4.3:
resolution: {integrity: sha512-jwIBUnWitZzw0VfKC77yN8DvTyePLVnAjbA2lPMbMIdO9ZY2lfD4AQ4QpuWsxJyAllFC4slOFDNgCDHx2AlYWw==}
dependencies:
@@ -7661,12 +7519,6 @@ packages:
core-js: 3.32.2
dev: true
- /@storybook/core-events@7.4.0:
- resolution: {integrity: sha512-JavEo4dw7TQdF5pSKjk4RtqLgsG2R/eWRI8vZ3ANKa0ploGAnQR/eMTfSxf6TUH3ElBWLJhi+lvUCkKXPQD+dw==}
- dependencies:
- ts-dedent: 2.2.0
- dev: true
-
/@storybook/core-events@7.4.3:
resolution: {integrity: sha512-FRfipCijMnVbGxL1ZjOLM836lyd/TGQcUFeVjTQWW/+pIGHELqDHiYeq68hqoGTKl0G0np59CJPWYTUZA4Dl9Q==}
dependencies:
@@ -7725,15 +7577,6 @@ packages:
- utf-8-validate
dev: true
- /@storybook/csf-plugin@7.4.0:
- resolution: {integrity: sha512-X1L3l/dpz2UYjCEQlFLkW7w1A13pmzDZpJ0lotkV79PALlakMXBeoX3I2E0VMjJATV8wC9RSj56COBAs6HsPeg==}
- dependencies:
- '@storybook/csf-tools': 7.4.0
- unplugin: 1.4.0
- transitivePeerDependencies:
- - supports-color
- dev: true
-
/@storybook/csf-plugin@7.4.3:
resolution: {integrity: sha512-xQCimGsrGD1JxvyFc0LrH10WZWb181r0beF19aGIAadczs/JWhT+nxF8OhfP1LK4wHj9jH+F4nIXEMpm9yI9Qg==}
dependencies:
@@ -7743,22 +7586,6 @@ packages:
- supports-color
dev: true
- /@storybook/csf-tools@7.4.0:
- resolution: {integrity: sha512-bKyOmWPyvT50Neq2wCRr2PmVGLVVm6pOw8WL5t5jueD8sRRzo9QdfhEkqmuSyqdsBdt3SiJKL5oA6dqY5Vl9ww==}
- dependencies:
- '@babel/generator': 7.22.10
- '@babel/parser': 7.22.11
- '@babel/traverse': 7.22.11
- '@babel/types': 7.22.11
- '@storybook/csf': 0.1.0
- '@storybook/types': 7.4.0
- fs-extra: 11.1.1
- recast: 0.23.2
- ts-dedent: 2.2.0
- transitivePeerDependencies:
- - supports-color
- dev: true
-
/@storybook/csf-tools@7.4.3:
resolution: {integrity: sha512-nkVakGx2kzou91lGcxnyFNiSEdnpx1a53lQTl/DLm0QpDbqQuu3ZbZWXZCpXV97t/6YPeCCnGLXodnI7PZyZBA==}
dependencies:
@@ -7791,20 +7618,6 @@ packages:
resolution: {integrity: sha512-JDaBR9lwVY4eSH5W8EGHrhODjygPd6QImRbwjAuJNEnY0Vw4ie3bPkeGfnacB3OBW6u/agqPv2aRlR46JcAQLg==}
dev: true
- /@storybook/docs-tools@7.4.0:
- resolution: {integrity: sha512-DzXmt4JorAOePoS+sjQznf8jLPI9D5mdB1eSXjfvmGBQyyehKTZv5+TXuxYvT3iPN4rW4OPrIrQCSIrbULFdwA==}
- dependencies:
- '@storybook/core-common': 7.4.0
- '@storybook/preview-api': 7.4.0
- '@storybook/types': 7.4.0
- '@types/doctrine': 0.0.3
- doctrine: 3.0.0
- lodash: 4.17.21
- transitivePeerDependencies:
- - encoding
- - supports-color
- dev: true
-
/@storybook/docs-tools@7.4.3:
resolution: {integrity: sha512-T9oU10vIY3mC6Up+9rjN5LfBydhhIFhKzHPtUT9PfN1iEa0lO2TkT4m+vf2kcokPppUZNVbqiGjy9t/WYnpeZg==}
dependencies:
@@ -7823,31 +7636,6 @@ packages:
resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==}
dev: true
- /@storybook/manager-api@7.4.0(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-sBfkkt0eZGTozeKrbzMtWLEOQrgqdk24OUJlkc2IDaucR1CBNjoCMjNeYg7cLDw0rXE8W3W3AdWtJnfsUbLMAQ==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- dependencies:
- '@storybook/channels': 7.4.0
- '@storybook/client-logger': 7.4.0
- '@storybook/core-events': 7.4.0
- '@storybook/csf': 0.1.0
- '@storybook/global': 5.0.0
- '@storybook/router': 7.4.0(react-dom@18.2.0)(react@18.2.0)
- '@storybook/theming': 7.4.0(react-dom@18.2.0)(react@18.2.0)
- '@storybook/types': 7.4.0
- dequal: 2.0.3
- lodash: 4.17.21
- memoizerific: 1.11.3
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- semver: 7.5.4
- store2: 2.14.2
- telejson: 7.2.0
- ts-dedent: 2.2.0
- dev: true
-
/@storybook/manager-api@7.4.3(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-o5oiL2cJKlY+HNBCdUo5QKT8yXTyYYvBKibSS3YfDKcjeR9RXP+RhdF5lLLh6TzPwfdtLrXQoVI4A/61v2kurQ==}
peerDependencies:
@@ -7881,41 +7669,14 @@ packages:
resolution: {integrity: sha512-TXJJd5RAKakWx4BtpwvSNdgTDkKM6RkXU8GK34S/LhidQ5Pjz3wcnqb0TxEkfhK/ztbP8nKHqXFwLfa2CYkvQw==}
dev: true
- /@storybook/node-logger@7.4.0:
- resolution: {integrity: sha512-tWSWkYyAvp6SxjIBaTklg29avzv/3Lv4c0dOG2o5tz79PyZkq9v6sQtwLLoI8EJA9Mo8Z08vaJp8NZyDQ9RCuA==}
- dev: true
-
/@storybook/node-logger@7.4.3:
resolution: {integrity: sha512-pL13PPMUttflTWKVeDIKxPIJtBRl50Fzck12/7uiNROtBIrSV9DZSgOjInAazjo4tl+7fDj9lgkGeMEz00E8aQ==}
dev: true
- /@storybook/postinstall@7.4.0:
- resolution: {integrity: sha512-ZVBZggqkuj7ysfuHSCd/J7ovWV06zY9uWf+VU+Zw7ZeojDT8QHFrCurPsN7D9679j9vRU1/kSzqvAiStALS33g==}
- dev: true
-
/@storybook/postinstall@7.4.3:
resolution: {integrity: sha512-6NMaAvL4a26jR50UPz+Q6VATY3lHZWw1ru/weFgiV0rat632RFdiFyrMMrjbUWu9HDJE4fbCzrIZU0jGVs1wlQ==}
dev: true
- /@storybook/preview-api@7.4.0:
- resolution: {integrity: sha512-ndXO0Nx+eE7ktVE4EqHpQZ0guX7yYBdruDdJ7B739C0+OoPWsJN7jAzUqq0NXaBcYrdaU5gTy+KnWJUt8R+OyA==}
- dependencies:
- '@storybook/channels': 7.4.0
- '@storybook/client-logger': 7.4.0
- '@storybook/core-events': 7.4.0
- '@storybook/csf': 0.1.0
- '@storybook/global': 5.0.0
- '@storybook/types': 7.4.0
- '@types/qs': 6.9.7
- dequal: 2.0.3
- lodash: 4.17.21
- memoizerific: 1.11.3
- qs: 6.11.2
- synchronous-promise: 2.0.17
- ts-dedent: 2.2.0
- util-deprecate: 1.0.2
- dev: true
-
/@storybook/preview-api@7.4.3:
resolution: {integrity: sha512-qKwfH2+qN1Zpz2UX6dQLiTU5x2JH3o/+jOY4GYF6c3atTm5WAu1OvCYAJVb6MdXfAhZNuPwDKnJR8VmzWplWBg==}
dependencies:
@@ -7939,16 +7700,6 @@ packages:
resolution: {integrity: sha512-dItyGcql/rD6CWTKGUm58MguWC7L4KjlfNJmxxaHXnHRbaEjXPaRi9ztfmimIpAaBdBmreAZrZJYhLvOGG3CfA==}
dev: true
- /@storybook/react-dom-shim@7.4.0(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-TLpb8a2hnWJoRLqoXpMADh82BFfRZll6JI2Waf1FjnvJ4SF9eS0zBbxybrjW3lFAHWy2XJi+rwcK8FiPj0iBoQ==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- dependencies:
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- dev: true
-
/@storybook/react-dom-shim@7.4.3(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-d8kkZU4kqmNluuOx65l5H0L9lRn8Ji5rVxu+4MUCWrn82dxRLvVcFG0sfGUzOTNfX1/yajL2MxVJ2hx9fzLutQ==}
peerDependencies:
@@ -7974,19 +7725,6 @@ packages:
regenerator-runtime: 0.13.11
dev: true
- /@storybook/router@7.4.0(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-IATdtFL5C3ryjNQSwaQfrmiOZiVFoVNMevMoBGDC++g0laSW40TGiNK6fUjUDBKuOgbuDt4Svfbl29k21GefEg==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- dependencies:
- '@storybook/client-logger': 7.4.0
- memoizerific: 1.11.3
- qs: 6.11.2
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- dev: true
-
/@storybook/router@7.4.3(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-1ab1VTYzzOsBGKeT8xm1kLriIsIsiB/l3t7DdARJxLmPbddKyyXE018w17gfrARCWQ8SM99Ko6+pLmlZ2sm8ug==}
peerDependencies:
@@ -8047,20 +7785,6 @@ packages:
regenerator-runtime: 0.13.11
dev: true
- /@storybook/theming@7.4.0(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-eLjEf6G3cqlegfutF/iUrec9LrUjKDj7K4ZhGdACWrf7bQcODs99EK62e9/d8GNKr4b+QMSEuM6XNGaqdPnuzQ==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=18
- dependencies:
- '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0)
- '@storybook/client-logger': 7.4.0
- '@storybook/global': 5.0.0
- memoizerific: 1.11.3
- react: 18.2.0
- react-dom: 18.2.0(react@18.2.0)
- dev: true
-
/@storybook/theming@7.4.3(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-u5wLwWmhGcTmkcs6f2wDGv+w8wzwbNJat0WaIIbwdJfX7arH6nO5HkBhNxvl6FUFxX0tovp/e9ULzxVPc356jw==}
peerDependencies:
@@ -8075,16 +7799,6 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: true
- /@storybook/types@7.4.0:
- resolution: {integrity: sha512-XyzYkmeklywxvElPrIWLczi/PWtEdgTL6ToT3++FVxptsC2LZKS3Ue+sBcQ9xRZhkRemw4HQHwed5EW3dO8yUg==}
- dependencies:
- '@storybook/channels': 7.4.0
- '@types/babel__core': 7.20.0
- '@types/express': 4.17.17
- '@types/react': 16.14.46
- file-system-cache: 2.3.0
- dev: true
-
/@storybook/types@7.4.3:
resolution: {integrity: sha512-DrHC1hIiw9TqDILLokDnvbUPNxGz5iJaYFEv30uvYE0s9MvgEUPblCChEUjaHOps7zQTznMPf8ULfoXlgqxk2A==}
dependencies:
@@ -8539,14 +8253,6 @@ packages:
'@types/react': 18.2.22
dev: true
- /@types/react@16.14.46:
- resolution: {integrity: sha512-Am4pyXMrr6cWWw/TN3oqHtEZl0j+G6Up/O8m65+xF/3ZaUgkv1GAtTPWw4yNRmH0HJXmur6xKCKoMo3rBGynuw==}
- dependencies:
- '@types/prop-types': 15.7.5
- '@types/scheduler': 0.16.3
- csstype: 3.1.2
- dev: true
-
/@types/react@18.2.22:
resolution: {integrity: sha512-60fLTOLqzarLED2O3UQImc/lsNRgG0jE/a1mPW9KjMemY0LMITWEsbS4VvZ4p6rorEHd5YKxxmMKSDK505GHpA==}
dependencies: