Skip to content

chore(docs): add click blocker on stories #5492

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/seven-cars-melt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@swisspost/design-system-documentation': patch
---

Added a click blocker decorator on all of the components that had links to prevent users being redirected to another page.
6 changes: 3 additions & 3 deletions packages/components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export namespace Components {
*/
"name"?: string;
/**
* A public method to reset the controls `checked` and `validity` state. The validity state is set to `null`, so it's neither valid nor invalid.
* A public method to reset the controls `checked` and `validity` state. The validity state is set to `undefined`, so it's neither valid nor invalid.
*/
"reset": () => Promise<void>;
/**
Expand All @@ -158,7 +158,7 @@ export namespace Components {
/**
* Defines the validation `validity` of the control. To reset validity to an undefined state, simply remove the attribute from the control.
*/
"validity"?: 'true' | 'false';
"validity"?: boolean;
/**
* Defines the `value` attribute of the control. <span className="banner banner-sm banner-info">This is a required property, when the control is used with type `radio`.</span>
*/
Expand Down Expand Up @@ -1060,7 +1060,7 @@ declare namespace LocalJSX {
/**
* Defines the validation `validity` of the control. To reset validity to an undefined state, simply remove the attribute from the control.
*/
"validity"?: 'true' | 'false';
"validity"?: boolean;
/**
* Defines the `value` attribute of the control. <span className="banner banner-sm banner-info">This is a required property, when the control is used with type `radio`.</span>
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
| `label` _(required)_ | `label` | Defines the text in the control-label. | `string` | `undefined` |
| `name` | `name` | Defines the `name` attribute of the control. <span className="mb-4 banner banner-sm banner-info">This is a required property, when the control should participate in a native `form`. If not specified, a native `form` will never contain this controls value.</span> <span className="banner banner-sm banner-info">This is a required property, when the control is used with type `radio`.</span> | `string` | `undefined` |
| `type` _(required)_ | `type` | Defines the `type` attribute of the control. | `"checkbox" \| "radio"` | `undefined` |
| `validity` | `validity` | Defines the validation `validity` of the control. To reset validity to an undefined state, simply remove the attribute from the control. | `"false" \| "true"` | `undefined` |
| `validity` | `validity` | Defines the validation `validity` of the control. To reset validity to an undefined state, simply remove the attribute from the control. | `boolean` | `undefined` |
| `value` | `value` | Defines the `value` attribute of the control. <span className="banner banner-sm banner-info">This is a required property, when the control is used with type `radio`.</span> | `string` | `undefined` |


Expand All @@ -41,7 +41,7 @@ Type: `Promise<void>`
### `reset() => Promise<void>`

A public method to reset the controls `checked` and `validity` state.
The validity state is set to `null`, so it's neither valid nor invalid.
The validity state is set to `undefined`, so it's neither valid nor invalid.

#### Returns

Expand Down
21 changes: 21 additions & 0 deletions packages/documentation/src/shared/click-blocker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { StoryContext, StoryFn } from '@storybook/web-components';
import { html } from 'lit';

// Click blocker decorator to prevent clicking on example links
export function clickBlocker(story: StoryFn, context: StoryContext) {
// Generate a custom ID in case there are multiple click blockers on the page
const id = crypto.randomUUID();
setTimeout(() => {
const div = document.getElementById(id);
div?.addEventListener(
'click',
e => {
e.stopPropagation();
e.preventDefault();
},
{ capture: true },
);
}, 0);

return html` <div id="${id}">${story(context.args, context)}</div> `;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaComponent = {
id: 'f1cda0ac-28d4-4afc-b56d-9182bd9bd671',
title: 'Components/App Store Badge',
tags: ['package:HTML'],
decorators: [clickBlocker],
parameters: {
badges: [],
design: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Args, StoryContext, StoryObj } from '@storybook/web-components';
import { MetaComponent } from '@root/types';
import { html, nothing } from 'lit';
import { components } from '@swisspost/design-system-components/dist/docs.json';
import { clickBlocker } from '@/shared/click-blocker';

const AVATAR_ARGTYPES = components.find(c => c.tag === 'post-avatar');
const USERID_ARGTYPE = AVATAR_ARGTYPES?.props.find(p => p.name === 'userid');
Expand Down Expand Up @@ -75,6 +76,7 @@ export const Default: Story = {
};

export const AnchorWrapped: Story = {
decorators: [clickBlocker],
render: (args: Args, context: StoryContext) => {
return html`<a href="#">${Default.render?.(args, context)}</a>`;
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type { Args, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaComponent = {
id: 'b7db7391-f893-4b1e-a125-b30c6f0b028b',
title: 'Components/Breadcrumbs',
tags: ['package:WebComponents'],
decorators: [clickBlocker],
parameters: {
badges: [],
design: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Args, StoryContext, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import { useArgs } from '@storybook/preview-api';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaComponent = {
id: '021d61aa-e039-4858-b4b9-b86a3e772811',
Expand Down Expand Up @@ -127,19 +128,7 @@ const meta: MetaComponent = {
},
},
},
decorators: [
story =>
html`
<div
@click="${(e: Event) => {
const target = e.target as HTMLElement;
if (target.tagName === 'A' || target.tagName === 'BUTTON') e.preventDefault();
}}"
>
${story()}
</div>
`,
],
decorators: [clickBlocker],
};

export default meta;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { html, unsafeStatic } from 'lit/static-html.js';
import { spread } from '@open-wc/lit-helpers';
import { repeat } from 'lit/directives/repeat.js';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaComponent = {
id: 'eb78afcb-ce92-4990-94b6-6536d5ec6af4',
title: 'Components/Button',
tags: ['package:HTML'],
decorators: [clickBlocker],
parameters: {
badges: [],
design: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Args, StoryContext, StoryFn, StoryObj } from '@storybook/web-compo
import { html, unsafeStatic } from 'lit/static-html.js';
import { nothing } from 'lit';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaComponent = {
id: 'b4800d9e-4837-4476-a327-bb4586eb7e97',
Expand Down Expand Up @@ -58,13 +59,6 @@ const meta: MetaComponent = {

export default meta;

// DECORATORS
function clickBlocker(story: StoryFn, context: StoryContext) {
return html`
<div @click=${(e: Event) => e.preventDefault()}>${story(context.args, context)}</div>
`;
}

function paddedContainer(story: StoryFn, context: StoryContext) {
return html` <div class="p-8">${story(context.args, context)}</div> `;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { html, nothing } from 'lit';
import { choose } from 'lit/directives/choose.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaComponent = {
id: '605c788d-3f75-4e6c-8498-be3d546843c2',
Expand Down Expand Up @@ -205,13 +206,6 @@ const meta: MetaComponent = {

export default meta;

// DECORATORS
function clickBlocker(story: StoryFn, context: StoryContext) {
return html`
<div @click=${(e: Event) => e.preventDefault()}>${story(context.args, context)}</div>
`;
}

function gridContainer(story: StoryFn, context: StoryContext) {
return html`
<div class="row gy-16">
Expand All @@ -223,9 +217,7 @@ function gridContainer(story: StoryFn, context: StoryContext) {
// RENDERER
function getCardLinks() {
return html`
${['Link Text', 'More Link'].map(
label => html` <a class="card-link" href="#">${label}</a> `,
)}
${['Link Text', 'More Link'].map(label => html` <a class="card-link" href="#">${label}</a> `)}
`;
}

Expand All @@ -243,7 +235,9 @@ function getCardBody({ customBody, content, action, showTitle, showSubtitle }: A
return html`
<div class="card-body">
${showTitle ? html` <h5 class="card-title">Card Title</h5> ` : nothing}
${showSubtitle ? html` <h6 class="card-subtitle mb-8 text-muted">Card Subtitle</h6> ` : nothing}
${showSubtitle
? html` <h6 class="card-subtitle mb-8 text-muted">Card Subtitle</h6> `
: nothing}
<p class="card-text">${content}</p>
${choose(
action,
Expand Down Expand Up @@ -314,7 +308,7 @@ const renderSimpleInteractiveCard = html`
type Story = StoryObj;

const singleCardStory: Story = {
decorators: [gridContainer],
decorators: [gridContainer, clickBlocker],
render: (args: Args) =>
html`${args.action === 'button' ? renderCardWithInteractiveContainer(args) : renderCard(args)}`,
};
Expand All @@ -324,7 +318,7 @@ export const Default: Story = {
};

export const Foundation: Story = {
decorators: [story => html`<div class="d-flex gap-16">${story()}</div>`],
decorators: [story => html`<div class="d-flex gap-16">${story()}</div>`, clickBlocker],
render: () => html`
<div class="card p-16">
<p>Non-interactive card</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Args, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const GRID_CELLS = [1, 2, 3, 4];
const LINKS_PER_CELL = [6, 8, 8, 5];
Expand All @@ -10,6 +11,7 @@ const meta: MetaComponent = {
title: 'Components/Footer',
component: 'post-footer',
tags: ['package:WebComponents'],
decorators: [clickBlocker],
parameters: {
layout: 'fullscreen',
badges: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Args, StoryObj } from '@storybook/web-components';
import { MetaComponent } from '@root/types';
import { html } from 'lit';
import { fakeContent } from '@/utils';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaComponent = {
id: '27a2e64d-55ba-492d-ab79-5f7c5e818498',
Expand Down Expand Up @@ -247,6 +248,7 @@ export const Default: Story = {
html` <div class="header-story-wrapper">
<div class="virtual-body">${story()} ${fakeContent()}</div>
</div>`,
clickBlocker,
],
};

Expand All @@ -255,5 +257,5 @@ export const WithTargetGroup: Story = {
targetGroup: true,
},
...Template,
decorators: [story => html` <div style="min-height: 400px">${story()}</div>`],
decorators: [story => html` <div style="min-height: 400px">${story()}</div>`, clickBlocker],
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Args, StoryObj } from '@storybook/web-components';
import { html, nothing } from 'lit';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

export interface PostLinkarea {
dataLink?: boolean;
Expand All @@ -14,6 +15,7 @@ const meta: MetaComponent<PostLinkarea> = {
tags: ['package:WebComponents'],
render: renderLinkarea,
component: 'post-linkarea',
decorators: [clickBlocker],
parameters: {
design: {},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { Args, StoryContext, StoryFn, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaComponent = {
id: '5a47ba70-7831-4e59-b83e-81b6e6c32372',
title: 'Components/List Group',
tags: ['package:HTML'],
render: renderListGroup,
decorators: [gridDecorator],
decorators: [gridDecorator, clickBlocker],
parameters: {
design: {
type: 'figma',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Args, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaComponent = {
id: '9a636763-de2d-4f72-bc81-98daf10871f7',
Expand Down Expand Up @@ -53,7 +54,7 @@ const meta: MetaComponent = {
'Value can either be in `vw`, `px` or `%`. If no max-width is defined, the popover will extend to the width of its content.',
table: {
category: 'General',
defaultValue: { summary: '280px' }
defaultValue: { summary: '280px' },
},
},
palette: {
Expand Down Expand Up @@ -91,6 +92,7 @@ const meta: MetaComponent = {
name: 'Placement',
},
},
decorators: [clickBlocker],
};

function render(args: Args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type { StoryObj } from '@storybook/web-components';
import { html } from 'lit/static-html.js';
import { MetaExtended } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaExtended = {
id: '2fc3b456-19ba-4ede-b1bc-499518f829b1',
title: 'Components/Skiplinks',
tags: ['package:HTML'],
decorators: [clickBlocker],
render: renderSkiplinks,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Args, StoryContext, StoryFn, StoryObj } from '@storybook/web-components';
import { Args, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import { MetaComponent } from '@root/types';
import { clickBlocker } from '@/shared/click-blocker';

const meta: MetaComponent = {
id: '87ceabbb-f552-46eb-8a47-4d84e7f8cef0',
Expand Down Expand Up @@ -54,13 +55,6 @@ const meta: MetaComponent = {

export default meta;

// DECORATOR
function clickBlocker(story: StoryFn, context: StoryContext) {
return html`
<div @click=${(e: Event) => e.preventDefault()}>${story(context.args, context)}</div>
`;
}

function renderTest(args: Args) {
return html`
<div class="subnavigation ${args.palette}">
Expand Down
Loading
Loading