diff --git a/.changeset/new-pianos-mix.md b/.changeset/new-pianos-mix.md
new file mode 100644
index 0000000000..e811033863
--- /dev/null
+++ b/.changeset/new-pianos-mix.md
@@ -0,0 +1,6 @@
+---
+'@swisspost/design-system-documentation': minor
+'@swisspost/design-system-styles': minor
+---
+
+Added list mixins `list-bullet`, `list-revert` and `list-unstyled`.
diff --git a/packages/documentation/.storybook/styles/preview.scss b/packages/documentation/.storybook/styles/preview.scss
index 35c5a3f0f3..17ad69d1f9 100644
--- a/packages/documentation/.storybook/styles/preview.scss
+++ b/packages/documentation/.storybook/styles/preview.scss
@@ -52,7 +52,8 @@ $monospace: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier
.table-fit-content {
width: fit-content;
- th, td {
+ th,
+ td {
padding-inline: 2rem;
}
}
@@ -110,9 +111,8 @@ $monospace: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier
top: -0.1em;
margin: 0 0.1em;
padding: 0.15em 0.4em 0.1em;
- background-color: tokens.get('utility-surface-accent1');
- border: 1px solid tokens.get('utility-surface-accent2');
- color: 1px solid tokens.get('utility-surface-accent4');
+ background-color: rgba(#fff, 0.75);
+ border: 1px solid rgba(#000, 0.3);
border-radius: 0.2em;
font-family: $monospace;
font-size: 0.75em;
@@ -128,6 +128,13 @@ $monospace: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier
}
}
+ [data-color-scheme='dark'] {
+ code {
+ background-color: rgba(#000, 0.75);
+ border-color: rgba(#fff, 0.3);
+ }
+ }
+
.sbdocs-wrapper {
padding-right: 0;
padding-bottom: 0;
diff --git a/packages/documentation/cypress/e2e/components/list.cy.ts b/packages/documentation/cypress/e2e/components/list.cy.ts
index af988242ea..3aed76e35d 100644
--- a/packages/documentation/cypress/e2e/components/list.cy.ts
+++ b/packages/documentation/cypress/e2e/components/list.cy.ts
@@ -1,7 +1,7 @@
describe('List', () => {
describe('Accessibility', () => {
beforeEach(() => {
- cy.visit('/iframe.html?id=snapshots--list');
+ cy.visit('/iframe.html?id=snapshots--lists');
cy.get('ol', { timeout: 30000 }).should('be.visible');
cy.injectAxe();
});
diff --git a/packages/documentation/cypress/snapshots/components/list.snapshot.ts b/packages/documentation/cypress/snapshots/components/list.snapshot.ts
index fa0320ecdb..a49515ac7f 100644
--- a/packages/documentation/cypress/snapshots/components/list.snapshot.ts
+++ b/packages/documentation/cypress/snapshots/components/list.snapshot.ts
@@ -1,6 +1,6 @@
describe('List', () => {
it('default', () => {
- cy.visit('/iframe.html?id=snapshots--list');
+ cy.visit('/iframe.html?id=snapshots--lists');
cy.get('ol', { timeout: 30000 }).should('be.visible');
cy.percySnapshot('Lists', { widths: [1440] });
});
diff --git a/packages/documentation/src/stories/foundations/typography/list/list-bullet.sample.scss b/packages/documentation/src/stories/foundations/typography/list/list-bullet.sample.scss
new file mode 100644
index 0000000000..4c106961d7
--- /dev/null
+++ b/packages/documentation/src/stories/foundations/typography/list/list-bullet.sample.scss
@@ -0,0 +1,7 @@
+@use '@swisspost/design-system-styles/core' as post;
+
+.my-component {
+ ul {
+ @include post.list-bullet();
+ }
+}
diff --git a/packages/documentation/src/stories/foundations/typography/list/list-inline.sample.scss b/packages/documentation/src/stories/foundations/typography/list/list-inline.sample.scss
new file mode 100644
index 0000000000..e6e5e1de5b
--- /dev/null
+++ b/packages/documentation/src/stories/foundations/typography/list/list-inline.sample.scss
@@ -0,0 +1,7 @@
+@use '@swisspost/design-system-styles/core' as post;
+
+.my-component {
+ ul {
+ @include post.list-inline();
+ }
+}
diff --git a/packages/documentation/src/stories/foundations/typography/list/list-reset.sample.scss b/packages/documentation/src/stories/foundations/typography/list/list-reset.sample.scss
deleted file mode 100644
index 8bc5b24f1c..0000000000
--- a/packages/documentation/src/stories/foundations/typography/list/list-reset.sample.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-@use '../../../../../node_modules/@swisspost/design-system-styles/core' as post;
-
-ul.my-list {
- @include post.reset-list();
-}
diff --git a/packages/documentation/src/stories/foundations/typography/list/list-unstyled.sample.scss b/packages/documentation/src/stories/foundations/typography/list/list-unstyled.sample.scss
new file mode 100644
index 0000000000..58dcd275e3
--- /dev/null
+++ b/packages/documentation/src/stories/foundations/typography/list/list-unstyled.sample.scss
@@ -0,0 +1,13 @@
+@use '@swisspost/design-system-styles/core' as post;
+
+.my-component {
+ ul {
+ @include post.list-unstyled() {
+ // custom styles for the ul element
+ }
+
+ > li {
+ // custom styles for child elements
+ }
+ }
+}
diff --git a/packages/documentation/src/stories/foundations/typography/list/list.docs.mdx b/packages/documentation/src/stories/foundations/typography/list/list.docs.mdx
index 23b66f1480..5ca305d9b5 100644
--- a/packages/documentation/src/stories/foundations/typography/list/list.docs.mdx
+++ b/packages/documentation/src/stories/foundations/typography/list/list.docs.mdx
@@ -1,6 +1,8 @@
import { Meta, Canvas, Source } from '@storybook/blocks';
import * as ListStories from './list.stories';
-import SampleListReset from './list-reset.sample.scss?raw';
+import SampleListBullet from './list-bullet.sample.scss?raw';
+import SampleListInline from './list-inline.sample.scss?raw';
+import SampleListUnstyled from './list-unstyled.sample.scss?raw';
@@ -18,49 +20,62 @@ It is created using a `
` tag and each list item is preceded by a bullet (sma
-### Unstyled
+#### Sass mixin
+
+
-Remove the default list-style and left margin on list items (immediate children only).
-This only applies to immediate child list items, meaning you will need to add the class for any nested lists as well.
+### Inline
-
+Remove a list’s bullets.
-#### Sass mixin
+
-If you want to use the class above, you can still reset the list styles with the following mixin:
+#### Sass mixin
-### Inline
+### Unstyled List
-Remove a list’s bullets and apply some light margin with a combination of two classes,
-`.list-inline` and `.list-inline-item`.
+Can be used with both, unordered and ordered lists.
+Remove all the styles on a list and make it appear as if it is made out of `` elements.
-
+
+
+#### Sass mixin
+
+
-## Ordered List
+## Ordered
An ordered list groups related items in a specific order.
It is created using a `
` tag and list items are preceded by ascending numbers by default.
All of the above utility classes also apply to ordered lists.
-
+
## Description List
A description list is a list of terms, with a description of each term.
It is created using a `` tag, terms are defined using `` tags, and descriptions are defined using ` ` tags.
-
+
### Alignment
Align terms and descriptions horizontally by using our grid system’s predefined classes.
For longer terms, you can optionally add a `.text-truncate` class to truncate the text with an ellipsis.
-
+
diff --git a/packages/documentation/src/stories/foundations/typography/list/list.snapshot.stories.ts b/packages/documentation/src/stories/foundations/typography/list/list.snapshot.stories.ts
new file mode 100644
index 0000000000..9131673688
--- /dev/null
+++ b/packages/documentation/src/stories/foundations/typography/list/list.snapshot.stories.ts
@@ -0,0 +1,118 @@
+import type { StoryObj } from '@storybook/web-components';
+import { schemes } from '@/shared/snapshots/schemes';
+import meta from './list.stories';
+import { html, TemplateResult } from 'lit';
+import { unsafeHTML } from 'lit/directives/unsafe-html.js';
+
+const { id, ...metaWithoutId } = meta;
+
+export default {
+ ...metaWithoutId,
+ title: 'Snapshots',
+};
+
+type Story = StoryObj;
+
+export const Lists: Story = {
+ render: () => {
+ return schemes(
+ () => html`
+ Lists
+
+ Bullet
+
+ <ul>
+ ${renderList({ el: 'ul' })} ${renderList({ el: 'ul', classList: 'list-revert' })}
+ ${renderList({ el: 'ul', classList: 'list-unstyled' })}
+
+ <ul class="list-inline">
+ ${renderList({
+ el: 'ul',
+ classList: 'list-inline',
+ })}
+ ${renderList({
+ el: 'ul',
+ classList: 'list-inline list-revert',
+ })}
+ ${renderList({
+ el: 'ul',
+ classList: 'list-inline list-unstyled',
+ })}
+
+ <ul class="list-bullet">
+ ${renderList({ el: 'ul', classList: 'list-bullet' })}
+ ${renderList({ el: 'ul', classList: 'list-bullet list-revert' })}
+ ${renderList({ el: 'ul', classList: 'list-bullet list-unstyled' })}
+
+ <ul class="list-bullet list-inline">
+ ${renderList({
+ el: 'ul',
+ classList: 'list-bullet list-inline',
+ })}
+ ${renderList({
+ el: 'ul',
+ classList: 'list-bullet list-inline list-revert',
+ })}
+ ${renderList({
+ el: 'ul',
+ classList: 'list-bullet list-inline list-unstyled',
+ })}
+
+ Number
+
+ <ol>
+ ${renderList({ el: 'ol' })} ${renderList({ el: 'ol', classList: 'list-revert' })}
+ ${renderList({ el: 'ol', classList: 'list-unstyled' })}
+
+ <ul class="list-inline">
+ ${renderList({
+ el: 'ol',
+ classList: 'list-inline',
+ })}
+ ${renderList({
+ el: 'ol',
+ classList: 'list-inline list-revert',
+ })}
+ ${renderList({
+ el: 'ol',
+ classList: 'list-inline list-unstyled',
+ })}
+ `,
+ );
+
+ function renderList({
+ el,
+ classList = '',
+ }: {
+ el: string;
+ classList?: string;
+ }): TemplateResult {
+ const classAttr = classList ? ` class="${classList}"` : '';
+ const modifiers = classList?.split(' ').map(c => c.replace(/^list-/, ''));
+ const modifierStr = modifiers ? modifiers.join(' ') : '';
+
+ const modifierBlock = modifierStr ? `${modifierStr} ` : '';
+ const subListBlock = !modifiers?.some(n => n === 'inline')
+ ? `<${el}${classAttr}>
+ ${modifierBlock} sub-list-item 1
+ ${modifierBlock} sub-list-item 2
+ ${el}>`
+ : '';
+ const listBlock = `<${el}${classAttr}>
+ ${modifierBlock} list-item 1
+ ${modifierBlock} list-item 2 with more text to show how list-inline items wrap to a new line if necessary
+ ${modifierBlock} list-item 3
+
+ ${modifierBlock} list-item 4${subListBlock && ' - text before nested'}
+ ${subListBlock}
+ ${subListBlock && modifierBlock + ' list item 4 - text after nested'}
+
+ ${modifierBlock} list-item 5
+ ${modifierBlock} list-item 6
+ ${modifierBlock} list-item 7 `;
+
+ return html`
+ ${unsafeHTML(listBlock)}`;
+ }
+ },
+};
diff --git a/packages/documentation/src/stories/foundations/typography/list/list.stories.ts b/packages/documentation/src/stories/foundations/typography/list/list.stories.ts
index 89366eeedb..1c8fea98f4 100644
--- a/packages/documentation/src/stories/foundations/typography/list/list.stories.ts
+++ b/packages/documentation/src/stories/foundations/typography/list/list.stories.ts
@@ -32,6 +32,16 @@ export const UnorderedList: Story = {
`,
};
+export const InlineList: Story = {
+ render: () => html`
+
+ This is an inline list item.
+ And another one.
+ And one more.
+
+ `,
+};
+
export const UnstyledList: Story = {
render: () => html`
@@ -51,16 +61,6 @@ export const UnstyledList: Story = {
`,
};
-export const InlineList: Story = {
- render: () => html`
-
- This is an inline list item.
- And another one.
- And one more.
-
- `,
-};
-
export const OrderedList: Story = {
render: () => html`
diff --git a/packages/documentation/src/stories/raw-components/list/list.snapshot.stories.ts b/packages/documentation/src/stories/raw-components/list/list.snapshot.stories.ts
index 99b2c75069..102c74fb4c 100644
--- a/packages/documentation/src/stories/raw-components/list/list.snapshot.stories.ts
+++ b/packages/documentation/src/stories/raw-components/list/list.snapshot.stories.ts
@@ -50,40 +50,3 @@ export const PostList: Story = {
},
],
};
-
-export const List: Story = {
- render: () => {
- return schemes(
- () => html`
-
- This is an ordered list.
- It appears in its default style.
-
- Therefore it should be rendered with sequential numbers at the beginning of each list
- item.
-
-
- Nested list:
-
- This is a nested list
- It is further indented, depending on the depth of nesting.
- Nested lists numbers are independent form the numbers of their parents.
-
- After nested list item
-
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
- incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
- exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
- dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur
-
- Ordered list item
- Ordered list item
- Ordered list item
- Ordered list item
- Ordered list item
-
- `,
- );
- },
-};
diff --git a/packages/styles/src/elements/_index.scss b/packages/styles/src/elements/_index.scss
index 99e605d3a3..4b69076a8c 100644
--- a/packages/styles/src/elements/_index.scss
+++ b/packages/styles/src/elements/_index.scss
@@ -3,7 +3,8 @@
@use 'body';
@use 'anchor';
@use 'list-bullet';
+@use 'list';
+@use 'list-description';
@use 'paragraph';
@use 'fieldset-legend';
-@use 'list';
@use 'heading';
diff --git a/packages/styles/src/elements/list-bullet.scss b/packages/styles/src/elements/list-bullet.scss
index b474dac692..65ff2eebcf 100644
--- a/packages/styles/src/elements/list-bullet.scss
+++ b/packages/styles/src/elements/list-bullet.scss
@@ -1,5 +1,6 @@
@use '../functions/tokens';
@use '../tokens/elements';
+@use '../mixins/list' as list-mx;
tokens.$default-map: elements.$post-listbullet;
@@ -25,36 +26,18 @@ ul {
}
&.list-bullet {
- list-style: none;
-
- > li {
- margin: 0;
- padding-inline: 0;
- padding-block: tokens.get('list-bullet-item-text-padding-block');
-
- ~ li {
- margin-block-start: tokens.get('list-bullet-item-gap-block');
- }
-
- &::before {
- display: block;
- content: '';
- box-sizing: content-box;
- position: absolute;
- margin-block-start: calc(
- (#{tokens.get('body-line-height', elements.$post-body)} * 0.5em) -
- (#{tokens.get('list-bullet-item-icon-bullet-size')} * 0.5)
- );
- margin-inline-start: calc(
- (#{tokens.get('list-bullet-item-icon-size')} * -0.5) +
- (#{tokens.get('list-bullet-item-icon-bullet-size')} * -0.5) +
- (#{tokens.get('post-list-bullet-item-icon-gap-inline')} * -1)
- );
- width: tokens.get('list-bullet-item-icon-bullet-size');
- height: tokens.get('list-bullet-item-icon-bullet-size');
- background-color: currentColor;
- border-radius: 50%;
- }
- }
+ @include list-mx.list-bullet();
+ }
+
+ &.list-inline {
+ @include list-mx.list-inline();
+ }
+
+ &.list-revert {
+ @include list-mx.list-revert();
+ }
+
+ &.list-unstyled {
+ @include list-mx.list-unstyled();
}
}
diff --git a/packages/styles/src/elements/list-description.scss b/packages/styles/src/elements/list-description.scss
new file mode 100644
index 0000000000..b631459401
--- /dev/null
+++ b/packages/styles/src/elements/list-description.scss
@@ -0,0 +1,5 @@
+dl {
+ dd {
+ margin: 0;
+ }
+}
diff --git a/packages/styles/src/mixins/_index.scss b/packages/styles/src/mixins/_index.scss
index 88110fd344..5db656187d 100644
--- a/packages/styles/src/mixins/_index.scss
+++ b/packages/styles/src/mixins/_index.scss
@@ -7,6 +7,7 @@
@forward 'forms';
@forward 'icon-button';
@forward 'icons';
+@forward 'list';
@forward 'notification';
@forward 'scroll-shadows';
@forward 'size';
diff --git a/packages/styles/src/mixins/list.scss b/packages/styles/src/mixins/list.scss
new file mode 100644
index 0000000000..822143ba05
--- /dev/null
+++ b/packages/styles/src/mixins/list.scss
@@ -0,0 +1,93 @@
+@use '../functions/tokens';
+@use '../tokens/elements';
+
+@mixin list-bullet() {
+ list-style: none;
+ margin-block: tokens.get('list-bullet-margin-block', elements.$post-listbullet);
+ padding-inline-start: calc(
+ #{tokens.get('list-bullet-item-icon-size', elements.$post-listbullet)} + #{tokens.get(
+ 'list-bullet-item-icon-gap-inline',
+ elements.$post-listbullet
+ )}
+ );
+
+ > li {
+ margin: 0;
+ padding-inline: 0;
+ padding-block: tokens.get('list-bullet-item-text-padding-block', elements.$post-listbullet);
+
+ ~ li {
+ margin-block-start: tokens.get('list-bullet-item-gap-block', elements.$post-listbullet);
+ }
+
+ &::before {
+ display: block;
+ content: '';
+ box-sizing: content-box;
+ position: absolute;
+ margin-block-start: calc(
+ (#{tokens.get('body-line-height', elements.$post-body)} * 0.5em) -
+ (#{tokens.get('list-bullet-item-icon-bullet-size', elements.$post-listbullet)} * 0.5)
+ );
+ margin-inline-start: calc(
+ (#{tokens.get('list-bullet-item-icon-size', elements.$post-listbullet)} * -0.5) +
+ (#{tokens.get('list-bullet-item-icon-bullet-size', elements.$post-listbullet)} * -0.5) +
+ (#{tokens.get('post-list-bullet-item-icon-gap-inline', elements.$post-listbullet)} * -1)
+ );
+ width: tokens.get('list-bullet-item-icon-bullet-size', elements.$post-listbullet);
+ height: tokens.get('list-bullet-item-icon-bullet-size', elements.$post-listbullet);
+ background-color: currentColor;
+ border-radius: 50%;
+ }
+ }
+}
+
+@mixin list-inline() {
+ @include list-unstyled() {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: tokens.get('list-bullet-item-gap-block', elements.$post-listbullet);
+ column-gap: calc(
+ tokens.get('post-list-bullet-item-icon-gap-inline', elements.$post-listbullet) * 2
+ );
+ margin-block: tokens.get('list-bullet-margin-block', elements.$post-listbullet);
+ }
+}
+
+@mixin list-revert() {
+ all: revert;
+ @content;
+
+ > li {
+ all: revert;
+
+ ~ li {
+ all: revert;
+ }
+
+ &::before {
+ all: revert;
+ }
+ }
+}
+
+@mixin list-unstyled() {
+ all: unset;
+ display: block;
+ list-style: none;
+ @content;
+
+ > li {
+ all: unset;
+ display: list-item;
+
+ ~ li {
+ all: unset;
+ display: list-item;
+ }
+
+ &::before {
+ all: unset;
+ }
+ }
+}