diff --git a/.changeset/shaggy-weeks-grab.md b/.changeset/shaggy-weeks-grab.md
new file mode 100644
index 0000000000..ef640463f0
--- /dev/null
+++ b/.changeset/shaggy-weeks-grab.md
@@ -0,0 +1,5 @@
+---
+'@swisspost/design-system-documentation': minor
+---
+
+Added documentation for the CSS-only stepper and deprecated the stepper based on ng-bootstrap progress bar.
diff --git a/packages/documentation/cypress/snapshots/components/stepper.snapshot.ts b/packages/documentation/cypress/snapshots/components/stepper.snapshot.ts
new file mode 100644
index 0000000000..6392e9affa
--- /dev/null
+++ b/packages/documentation/cypress/snapshots/components/stepper.snapshot.ts
@@ -0,0 +1,7 @@
+describe('Stepper', () => {
+ it('default', () => {
+ cy.visit('/iframe.html?id=snapshots--stepper');
+ cy.get('.stepper', { timeout: 30000 }).should('be.visible');
+ cy.percySnapshot('Steppers', { widths: [320, 1440] });
+ });
+});
diff --git a/packages/documentation/src/stories/components/stepper/stepper-component.sample.ts b/packages/documentation/src/stories/components/stepper/stepper-component.sample.ts
deleted file mode 100644
index 5df6b5129d..0000000000
--- a/packages/documentation/src/stories/components/stepper/stepper-component.sample.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Component } from '@angular/core';
-
-@Component({
- selector: 'post-stepper',
- templateUrl: 'template.html',
-})
-export class StepperDemoComponent {
- steps = ['Sender', 'Product', 'Other details', 'Order summary'];
- currentIndex = 2;
-
- isCurrent(step: string): boolean {
- return step === this.steps[this.currentIndex];
- }
-
- getPathTo(step: string): string {
- return step.toLowerCase().split(' ').join('-');
- }
-}
diff --git a/packages/documentation/src/stories/components/stepper/stepper-template.sample.html b/packages/documentation/src/stories/components/stepper/stepper-template.sample.html
deleted file mode 100644
index b91caf9142..0000000000
--- a/packages/documentation/src/stories/components/stepper/stepper-template.sample.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
diff --git a/packages/documentation/src/stories/components/stepper/stepper.docs.mdx b/packages/documentation/src/stories/components/stepper/stepper.docs.mdx
index 39be7982fa..bd86917120 100644
--- a/packages/documentation/src/stories/components/stepper/stepper.docs.mdx
+++ b/packages/documentation/src/stories/components/stepper/stepper.docs.mdx
@@ -1,56 +1,54 @@
-import { Meta, Source } from '@storybook/blocks';
-import { PostTabHeader, PostTabPanel, PostTabs } from '@swisspost/design-system-components-react';
-import StylesPackageImport from '@/shared/styles-package-import.mdx';
+import { Canvas, Controls, Meta } from '@storybook/blocks';
import PostComponentDemoLink from '@/shared/post-component-demo-link.mdx';
-import NgbComponentImport from '@/shared/nb-bootstrap/ngb-component-import.mdx';
-import * as stepperStories from './stepper.stories';
-import stepperTemplate from './stepper-template.sample.html?raw';
-import stepperComponent from './stepper-component.sample?raw';
+import StylesPackageImport from '@/shared/styles-package-import.mdx';
+import * as StepperStories from './stepper.stories';
-
+
-Conveys progress through numbered steps.
+The stepped progression component provides an interactive visual overview of a process. It shows at a glance the amount of steps a user is required to go through, and serves as a guide for each step, indicating its status.
-
-
The stepper uses ng-bootstrap's progressbar component.
+
+
The stepper previously used ng-bootstrap's progressbar component, this has been deprecated in favor of the CSS-only stepper documented below.
+
-
+
+
+
+
+
+
+
+## Examples
+
+### Navigational Stepper
+
+You can use a stepper to allow users to navigate to specific steps.
+To do so, use `a` elements for the `.stepper-link` of the steps you want to be navigable, and use `span` for the steps you want not to be navigable.
+Then, wrap the stepper inside a `
`.
+
+However, it is better not to use an `a` for the current step since the user is already on the page.
+
+
-
+### Informational Stepper
-
+If you wish to display the stepper for informational purposes only, you can use `` elements for the `.stepper-link` on all the steps.
+In this case, there's no need to wrap the stepper inside a ``.
-## Example
+
-
- template.html
-
-
-
+### Long Labels
- component.ts
-
-
-
-
+When dealing with longer labels that may wrap into multiple lines, it is recommended to use a `title` attribute for the `.stepper-link`.
+This will truncate the label with an ellipsis if it exceeds two lines, while allowing the user to read the full label by hovering over it with the mouse.
+
diff --git a/packages/documentation/src/stories/components/stepper/stepper.snapshot.stories.ts b/packages/documentation/src/stories/components/stepper/stepper.snapshot.stories.ts
new file mode 100644
index 0000000000..52efed51d4
--- /dev/null
+++ b/packages/documentation/src/stories/components/stepper/stepper.snapshot.stories.ts
@@ -0,0 +1,38 @@
+import type { Args, StoryContext, StoryObj } from '@storybook/web-components';
+import meta from './stepper.stories';
+import { html } from 'lit';
+import { bombArgs } from '@/utils';
+
+const { id, ...metaWithoutId } = meta;
+
+export default {
+ ...metaWithoutId,
+ title: 'Snapshots',
+};
+
+type Story = StoryObj;
+
+export const Stepper: Story = {
+ render: (_args: Args, context: StoryContext) => {
+ const longSteps = [
+ 'Curabitur sed velit ullamcorper, molestie nunc a, dignissim ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
+ 'Ut sed consectetur odio. Curabitur vel pulvinar est. Maecenas quam arcu, sagittis et libero aliquet, egestas luctus nisi.',
+ 'Nam pretium nec neque sed vulputate. Sed non augue libero. Vivamus consequat mauris id ligula cursus, sit amet faucibus ipsum.',
+ 'Sed vulputate lacinia eros, sit amet mattis sem luctus sit amet. Vestibulum pharetra tortor a laoreet malesuada.',
+ ];
+ return html`
+
+ ${['bg-white', 'bg-dark'].map(
+ bg => html`
+
+ ${bombArgs({
+ currentStepNumber: meta.argTypes?.currentStepNumber?.options,
+ }).map((args: Args) => meta.render?.({ ...context.args, ...args }, context))}
+ ${meta.render?.({ ...context.args, ...{ steps: longSteps } }, context)}
+
+ `,
+ )}
+
+ `;
+ },
+};
diff --git a/packages/documentation/src/stories/components/stepper/stepper.stories.ts b/packages/documentation/src/stories/components/stepper/stepper.stories.ts
index 885db5aad0..8c11e38bed 100644
--- a/packages/documentation/src/stories/components/stepper/stepper.stories.ts
+++ b/packages/documentation/src/stories/components/stepper/stepper.stories.ts
@@ -1,22 +1,152 @@
-import type { StoryObj } from '@storybook/web-components';
+import { Args, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import { MetaComponent } from '@root/types';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { useArgs } from '@storybook/preview-api';
+
+const defaultSteps = ['Sender', 'Product', 'Other details', 'Order summary'];
const meta: MetaComponent = {
id: '7dc546d9-e248-4d06-befe-3ad62fcd310f',
title: 'Components/Stepper',
tags: ['package:Angular'],
+ render: renderStepper,
parameters: {
badges: [],
+ controls: {
+ exclude: ['steps'],
+ },
design: {
type: 'figma',
url: 'https://www.figma.com/file/xZ0IW0MJO0vnFicmrHiKaY/Components-Post?type=design&node-id=20952-29106&mode=design&t=38qLaYwWdirTcHdb-4',
},
},
+ args: {
+ currentStepNumber: 3,
+ navigableSteps: 'all',
+ processName: 'Registration Form',
+ steps: defaultSteps,
+ },
+ argTypes: {
+ navigableSteps: {
+ name: 'Navigable Steps',
+ description: 'Defines which steps in the current process the user can navigate to.',
+ control: {
+ type: 'radio',
+ labels: {
+ all: 'All steps',
+ completedOnly: 'Completed Steps only',
+ none: 'None',
+ },
+ },
+ options: ['all', 'completedOnly', 'none'],
+ table: {
+ category: 'General',
+ },
+ },
+ currentStepNumber: {
+ name: 'Current Step Number',
+ description: 'The number of the step the user is currently at in the process.',
+ control: {
+ type: 'select',
+ },
+ options: Object.keys(defaultSteps).map(key => parseInt(key, 10) + 1),
+ table: {
+ category: 'General',
+ },
+ },
+ processName: {
+ name: 'Process Name',
+ description:
+ 'A straightforward, self-explanatory name for the current process, used for assistive technologies.',
+ control: {
+ type: 'text',
+ },
+ table: {
+ category: 'General',
+ },
+ },
+ },
};
-
export default meta;
-export const Default: StoryObj = {
- render: () => html``,
+// RENDERER
+function getStepperItem(args: Args, step: string, index: number) {
+ const currentStepIndex = args.currentStepNumber - 1;
+ const isCompletedStep = index < currentStepIndex;
+ const isCurrentStep = index === currentStepIndex;
+ const isNextStep = index > currentStepIndex;
+ const isLink =
+ (isCompletedStep && args.navigableSteps !== 'none') ||
+ (isNextStep && args.navigableSteps === 'all');
+
+ let status = 'Current';
+ if (isCompletedStep) status = 'Completed';
+ if (isNextStep) status = 'Next';
+
+ const text = html`${status} step: ${step}`;
+ const title = step !== defaultSteps[index] ? step : undefined;
+
+ return html`
+
+ ${isLink
+ ? html`
+
+ ${text}
+
+ `
+ : html`${text} `}
+
+ `;
+}
+
+function renderStepper(args: Args) {
+ const [_, updateArgs] = useArgs();
+
+ setTimeout(() => {
+ const stepperLinks = document.querySelectorAll('.stepper-link');
+ stepperLinks.forEach((link, index) => {
+ if (link.tagName === 'SPAN') return;
+
+ link.addEventListener('click', e => {
+ e.preventDefault();
+ updateArgs({ currentStepNumber: index + 1 });
+ });
+ });
+ });
+
+ const isNav = args.navigableSteps !== 'none';
+ const stepper = html`
+ ${args.steps.map((step: string, index: number) => getStepperItem(args, step, index))}
+ `;
+
+ return args.navigableSteps === 'none'
+ ? stepper
+ : html` ${stepper} `;
+}
+
+export const Default: StoryObj = {};
+
+export const NavigationalStepper: StoryObj = {
+ args: {
+ navigableSteps: 'completedOnly',
+ },
+};
+
+export const InformationalStepper: StoryObj = {
+ args: {
+ navigableSteps: 'none',
+ },
+};
+
+export const LongLabels: StoryObj = {
+ args: {
+ steps: [
+ 'Nullam luctus mi sit amet nisl suscipit, nec tempor justo varius',
+ ...defaultSteps.slice(1),
+ ],
+ },
};