Skip to content
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

feat(components): create post-list component #3812

Open
wants to merge 44 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
0fb21fa
Merge branch 'main' into chore/2884-switch-hydrated-selector-from-cla…
oliverschuerch Oct 17, 2024
4bcf3c2
chore(components): switch hydrated flag from class to attribute
oliverschuerch Oct 17, 2024
6c13f1d
chore(documentation): remove unnecessary card-control specific docs s…
oliverschuerch Oct 17, 2024
eed1543
chore(documentation): remove hydrated class in popover stories
oliverschuerch Oct 17, 2024
47877e4
chore(documentation): remove hydrated class in tooltip stories
oliverschuerch Oct 17, 2024
e1fe416
refactor(documentation): replace hydrated class selector with data-hy…
oliverschuerch Oct 17, 2024
019c0e6
chore(header): update stencil.config so it uses the attribute data-hy…
oliverschuerch Oct 17, 2024
4839b44
refactor(documentation): update header e2e and snapshot tests, so the…
oliverschuerch Oct 17, 2024
291b98e
test(header): update tests, so they use the attribute data-hydrated i…
oliverschuerch Oct 17, 2024
d5b13e9
test(documentation): update custom commands `getComponents` and `getS…
oliverschuerch Oct 17, 2024
e269d75
chore: add changesets
oliverschuerch Oct 17, 2024
b2914cd
Merge branch 'main' into chore/2884-switch-hydrated-selector-from-cla…
oliverschuerch Oct 17, 2024
16c1016
feat(components): create post-list / post-list-item component
myrta2302 Oct 24, 2024
f4e3f4f
Update post-list-item.tsx
myrta2302 Oct 24, 2024
714f1dc
Update post-list.scss
myrta2302 Oct 24, 2024
3d36361
Update post-list.tsx
myrta2302 Oct 24, 2024
8d7a1ec
removed comments
myrta2302 Oct 24, 2024
116f04e
Merge branch '3544-component-list' of https://github.com/swisspost/de…
myrta2302 Oct 24, 2024
6f2ed41
restored h
myrta2302 Oct 24, 2024
265597f
Merge branch 'main' into 3544-component-list
myrta2302 Oct 24, 2024
19b9f7d
Revert index.html
myrta2302 Oct 24, 2024
27534b4
revert index.html
myrta2302 Oct 24, 2024
fa111f2
Update .changeset/fast-bats-poke.md
myrta2302 Oct 31, 2024
b98702d
Update packages/components/src/components/post-list-item/post-list-it…
myrta2302 Oct 31, 2024
ba074af
Update packages/components/src/components/post-list/post-list.tsx
myrta2302 Oct 31, 2024
3d08b64
Update packages/documentation/src/stories/components/list/list.snapsh…
myrta2302 Oct 31, 2024
8ec6731
Update packages/documentation/src/stories/components/list/list.storie…
myrta2302 Oct 31, 2024
b5f8ec2
Update packages/documentation/src/stories/components/list/list.storie…
myrta2302 Oct 31, 2024
3fed679
review comments updates
myrta2302 Oct 31, 2024
e8b9e27
review comments update
myrta2302 Oct 31, 2024
894a6b4
Merge branch 'main' into 3544-component-list
myrta2302 Oct 31, 2024
b915f96
merged to main
myrta2302 Oct 31, 2024
ad56068
removed file
myrta2302 Oct 31, 2024
4219a99
Delete packages/styles/src/components/validation.scss
myrta2302 Oct 31, 2024
4f82b32
fix linting errors
myrta2302 Oct 31, 2024
f20110e
review comments update
myrta2302 Oct 31, 2024
22e7f79
Merge branch 'main' into 3544-component-list
alizedebray Nov 1, 2024
2c7d761
review comments update
myrta2302 Nov 4, 2024
7bf44b2
removed index.html change
myrta2302 Nov 4, 2024
f677f24
review comments update
myrta2302 Nov 4, 2024
6c8b70d
Revert "review comments update"
myrta2302 Nov 4, 2024
53dc609
review comments update
myrta2302 Nov 4, 2024
4ad3dfa
restored id
myrta2302 Nov 4, 2024
00f1c2e
Merge branch 'main' into 3544-component-list
myrta2302 Nov 4, 2024
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
6 changes: 6 additions & 0 deletions .changeset/fast-bats-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@swisspost/design-system-documentation': minor
'@swisspost/design-system-components': minor
---

Created the `post-list` and `post-list-item` components.
60 changes: 60 additions & 0 deletions packages/components/cypress/e2e/list.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
describe('PostList Component', { baseUrl: null, includeShadowDom: false }, () => {
beforeEach(() => {
// Visit the page where the component is rendered
cy.visit('./cypress/fixtures/post-list.test.html');
});

it('should render the post-list component', () => {
// Check if the post-list component is rendered
cy.get('post-list').should('exist');
});

it('should have an id for the first div in post-list', () => {
// Ensure the first div inside post-list has an id attribute
cy.get('post-list')
.find('div')
.first()
.should('have.attr', 'id')
.and('not.be.empty')
.then($div => {
const id = $div['id'];
cy.log(`First div ID: ${id}`);
});
});

it('should throw an error if the title is missing', () => {
// Check for the mandatory title accessibility error if no title is provided
cy.on('uncaught:exception', err => {
expect(err.message).to.include(
'Please provide a title to the list component. Title is mandatory for accessibility purposes.',
);
return false;
});
cy.get('post-list').within(() => {
cy.get('[slot="post-list-item"]').first().invoke('remove');
});
});

it('should hide the title when title-hidden is set', () => {
// Set the `title-hidden` property and check if the title is hidden
cy.get('post-list').invoke('attr', 'title-hidden', true);
cy.get('post-list div').first().should('have.class', 'visually-hidden');
});

it('should render horizontally when the horizontal attribute is set', () => {
// Set the `horizontal` property and verify if the list has a horizontal layout
cy.get('post-list').invoke('attr', 'horizontal', true);
cy.get('post-list').should('have.attr', 'horizontal', 'true');
});

it('should ensure post-list-item components have the correct slot and role', () => {
// Verify that the `post-list-item` components have the correct slot and role attributes
cy.get('post-list').within(() => {
cy.get('post-list-item').each($el => {
cy.wrap($el)
.should('have.attr', 'slot', 'post-list-item')
.and('have.attr', 'role', 'listitem');
});
});
});
});
19 changes: 19 additions & 0 deletions packages/components/cypress/fixtures/post-list.test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../../dist/post-components/post-components.esm.js" type="module"></script>
</head>
<body>
<post-list>
<h3>TITLE</h3>
<post-list-item><post-tag>Title 1</post-tag></post-list-item>
<post-list-item><post-tag>Title 2</post-tag></post-list-item>
<post-list-item><post-tag>Title 3</post-tag></post-list-item>
<post-list-item><post-tag>Title 4</post-tag></post-list-item>
<post-list-item><post-tag>Title 5</post-tag></post-list-item>
</post-list>
</body>
</html>
42 changes: 42 additions & 0 deletions packages/components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,18 @@ export namespace Components {
*/
"url": string;
}
interface PostList {
/**
* The list can become horizontal by setting `horizontal="true"` or just `horizontal`
*/
"horizontal": boolean;
/**
* If `true`, the list title will be hidden. Otherwise, it will be displayed.`
*/
"titleHidden": boolean;
}
interface PostListItem {
}
interface PostLogo {
/**
* The URL to which the user is redirected upon clicking the logo.
Expand Down Expand Up @@ -500,6 +512,18 @@ declare global {
prototype: HTMLPostLanguageOptionElement;
new (): HTMLPostLanguageOptionElement;
};
interface HTMLPostListElement extends Components.PostList, HTMLStencilElement {
}
var HTMLPostListElement: {
prototype: HTMLPostListElement;
new (): HTMLPostListElement;
};
interface HTMLPostListItemElement extends Components.PostListItem, HTMLStencilElement {
}
var HTMLPostListItemElement: {
prototype: HTMLPostListItemElement;
new (): HTMLPostListItemElement;
};
interface HTMLPostLogoElement extends Components.PostLogo, HTMLStencilElement {
}
var HTMLPostLogoElement: {
Expand Down Expand Up @@ -598,6 +622,8 @@ declare global {
"post-collapsible-trigger": HTMLPostCollapsibleTriggerElement;
"post-icon": HTMLPostIconElement;
"post-language-option": HTMLPostLanguageOptionElement;
"post-list": HTMLPostListElement;
"post-list-item": HTMLPostListItemElement;
"post-logo": HTMLPostLogoElement;
"post-popover": HTMLPostPopoverElement;
"post-popovercontainer": HTMLPostPopovercontainerElement;
Expand Down Expand Up @@ -795,6 +821,18 @@ declare namespace LocalJSX {
*/
"url"?: string;
}
interface PostList {
/**
* The list can become horizontal by setting `horizontal="true"` or just `horizontal`
*/
"horizontal"?: boolean;
/**
* If `true`, the list title will be hidden. Otherwise, it will be displayed.`
*/
"titleHidden"?: boolean;
}
interface PostListItem {
}
interface PostLogo {
/**
* The URL to which the user is redirected upon clicking the logo.
Expand Down Expand Up @@ -919,6 +957,8 @@ declare namespace LocalJSX {
"post-collapsible-trigger": PostCollapsibleTrigger;
"post-icon": PostIcon;
"post-language-option": PostLanguageOption;
"post-list": PostList;
"post-list-item": PostListItem;
"post-logo": PostLogo;
"post-popover": PostPopover;
"post-popovercontainer": PostPopovercontainer;
Expand Down Expand Up @@ -949,6 +989,8 @@ declare module "@stencil/core" {
*/
"post-icon": LocalJSX.PostIcon & JSXBase.HTMLAttributes<HTMLPostIconElement>;
"post-language-option": LocalJSX.PostLanguageOption & JSXBase.HTMLAttributes<HTMLPostLanguageOptionElement>;
"post-list": LocalJSX.PostList & JSXBase.HTMLAttributes<HTMLPostListElement>;
"post-list-item": LocalJSX.PostListItem & JSXBase.HTMLAttributes<HTMLPostListItemElement>;
"post-logo": LocalJSX.PostLogo & JSXBase.HTMLAttributes<HTMLPostLogoElement>;
"post-popover": LocalJSX.PostPopover & JSXBase.HTMLAttributes<HTMLPostPopoverElement>;
"post-popovercontainer": LocalJSX.PostPopovercontainer & JSXBase.HTMLAttributes<HTMLPostPopovercontainerElement>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:host {
display: flex;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Component, Element, Host, h } from '@stencil/core';

/**
* @slot default- Slot for placing the content of the list item.
*/

@Component({
tag: 'post-list-item',
styleUrl: 'post-list-item.scss',
shadow: true,
})
export class PostListItem {
@Element() host: HTMLPostListItemElement;

connectedCallback() {
this.host.setAttribute('slot', 'post-list-item');
}

render() {
return (
<Host role="listitem">
<slot></slot>
</Host>
);
}
}
17 changes: 17 additions & 0 deletions packages/components/src/components/post-list-item/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# post-list-item



<!-- Auto Generated Below -->


## Slots

| Slot | Description |
| ----------------------------------------------------------- | ----------- |
| `"default- Slot for placing the content of the list item."` | |


----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*
27 changes: 27 additions & 0 deletions packages/components/src/components/post-list/post-list.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@use '@swisspost/design-system-styles/core' as post;

post-list {
display: flex;
gap: var(--post-list-title-gap);
flex-direction: column;
align-items: flex-start;

& > div[role='list'] {
flex-direction: column;
display: flex;
gap: var(--post-list-item-gap);
}

&[horizontal]:not([horizontal='false']) {
flex-direction: row;
align-items: baseline;
& > div[role='list'] {
flex-direction: row;
align-items: center;
}
}

> .list-title.visually-hidden {
@include post.visually-hidden();
}
}
69 changes: 69 additions & 0 deletions packages/components/src/components/post-list/post-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Component, Element, Prop, Host, State, h } from '@stencil/core';
import { version } from '@root/package.json';

/**
* @slot default - Slot for placing the list title.
* @slot post-list-item - Slot for placing post-list-item components.
*/

@Component({
tag: 'post-list',
styleUrl: 'post-list.scss',
shadow: false,
})
export class PostList {
@Element() host: HTMLPostListElement;

/**
* The unique title of the list that is also referenced in the labelledby
*/
@State() uuid: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@State() uuid: string;
@State() titleId: string;


/**
* If `true`, the list title will be hidden. Otherwise, it will be displayed.`
*/
@Prop() readonly titleHidden: boolean = false;

/**
* The list can become horizontal by setting `horizontal="true"` or just `horizontal`
*/
@Prop() readonly horizontal: boolean = false;

titleEl: HTMLElement;

componentWillLoad() {
/**
* Get the id set on the host element or use a random id by default
*/
this.uuid = `list-${crypto.randomUUID()}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.uuid = `list-${crypto.randomUUID()}`;
this.titleId= `list-title-${crypto.randomUUID()}`;

}

componentDidLoad() {
this.checkTitle();
}

private checkTitle() {
if (!this.titleEl.innerText) {
throw new Error(
'Please provide a title to the list component. Title is mandatory for accessibility purposes.',
);
}
}

render() {
return (
<Host data-version={version}>
<div
ref={el => (this.titleEl = el)}
id={this.uuid}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
id={this.uuid}
id={this.titleId}

class={`list-title${this.titleHidden ? ' visually-hidden' : ''}`}
>
<slot></slot>
</div>
<div role="list" aria-labelledby={this.uuid}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<div role="list" aria-labelledby={this.uuid}>
<div role="list" aria-labelledby={this.titleId}>

<slot name="post-list-item"></slot>
</div>
</Host>
);
}
}
26 changes: 26 additions & 0 deletions packages/components/src/components/post-list/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# post-list



<!-- Auto Generated Below -->


## Properties

| Property | Attribute | Description | Type | Default |
| ------------- | -------------- | ---------------------------------------------------------------------------------- | --------- | ------- |
| `horizontal` | `horizontal` | The list can become horizontal by setting `horizontal="true"` or just `horizontal` | `boolean` | `false` |
| `titleHidden` | `title-hidden` | If `true`, the list title will be hidden. Otherwise, it will be displayed.` | `boolean` | `false` |


## Slots

| Slot | Description |
| ------------------ | ------------------------------------------- |
| `"default"` | Slot for placing the list title. |
| `"post-list-item"` | Slot for placing post-list-item components. |


----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*
2 changes: 2 additions & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ export { PostTabHeader } from './components/post-tab-header/post-tab-header';
export { PostTabPanel } from './components/post-tab-panel/post-tab-panel';
export { PostTooltip } from './components/post-tooltip/post-tooltip';
export { PostTag } from './components/post-tag/post-tag';
export { PostList } from './components/post-list/post-list';
export { PostListItem } from './components/post-list-item/post-list-item';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
describe('List', () => {
it('default', () => {
cy.visit('/iframe.html?id=snapshots--list');
cy.get('post-list', { timeout: 30000 }).should('be.visible');
cy.percySnapshot('List', { widths: [1440] });
});
});
Loading