Skip to content

Commit

Permalink
feat(sbb-teaser): redesign (#2211)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: The property `isStacked` has been removed in favor of `alignment`. Please see the documentation for further info. The `description` is not clamped to two lines anymore (responsibility of consumer). The slotted `image` has now a default width of `300px`. The slot, formerly named `description`, has been replaced by the unnamed slot. Support of nested `p` elements dropped (invalid html).

Closes #1897

---------

Co-authored-by: Jeremias Peier <[email protected]>
  • Loading branch information
federicoisepponfincons and jeripeierSBB authored Jan 18, 2024
1 parent 4688dc7 commit ba5f86c
Show file tree
Hide file tree
Showing 7 changed files with 557 additions and 172 deletions.
224 changes: 224 additions & 0 deletions src/components/teaser/__snapshots__/teaser.spec.snap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
/* @web/test-runner snapshot v1 */
export const snapshots = {};

snapshots["sbb-teaser renders after centered - DOM"] =
`<sbb-teaser
alignment="after-centered"
aria-label="SBB teaser"
dir="ltr"
href="https://github.com/lyne-design-system/lyne-components"
role="link"
tabindex="0"
>
</sbb-teaser>
`;
/* end snapshot sbb-teaser renders after centered - DOM */

snapshots["sbb-teaser renders after centered - ShadowDOM"] =
`<a
class="sbb-teaser"
href="https://github.com/lyne-design-system/lyne-components"
role="presentation"
tabindex="-1"
>
<span class="sbb-teaser__container">
<span class="sbb-teaser__image-wrapper">
<slot name="image">
</slot>
</span>
<span class="sbb-teaser__text">
<sbb-chip
class="sbb-teaser__chip"
color="charcoal"
size="xxs"
>
<slot name="chip">
</slot>
</sbb-chip>
<sbb-title
aria-level="5"
class="sbb-teaser__lead"
level="5"
role="heading"
visual-level="5"
>
<slot name="title">
</slot>
</sbb-title>
<span class="sbb-teaser__description">
<slot>
</slot>
</span>
</span>
</span>
</a>
`;
/* end snapshot sbb-teaser renders after centered - ShadowDOM */

snapshots["sbb-teaser renders after with title level set - DOM"] =
`<sbb-teaser
alignment="after"
aria-label="SBB teaser"
dir="ltr"
href="https://github.com/lyne-design-system/lyne-components"
role="link"
tabindex="0"
title-level="2"
>
</sbb-teaser>
`;
/* end snapshot sbb-teaser renders after with title level set - DOM */

snapshots["sbb-teaser renders after with title level set - ShadowDOM"] =
`<a
class="sbb-teaser"
href="https://github.com/lyne-design-system/lyne-components"
role="presentation"
tabindex="-1"
>
<span class="sbb-teaser__container">
<span class="sbb-teaser__image-wrapper">
<slot name="image">
</slot>
</span>
<span class="sbb-teaser__text">
<sbb-chip
class="sbb-teaser__chip"
color="charcoal"
size="xxs"
>
<slot name="chip">
</slot>
</sbb-chip>
<sbb-title
aria-level="2"
class="sbb-teaser__lead"
level="2"
role="heading"
visual-level="5"
>
<slot name="title">
</slot>
</sbb-title>
<span class="sbb-teaser__description">
<slot>
</slot>
</span>
</span>
</span>
</a>
`;
/* end snapshot sbb-teaser renders after with title level set - ShadowDOM */

snapshots["sbb-teaser renders below with projected content - DOM"] =
`<sbb-teaser
alignment="below"
aria-label="SBB teaser"
data-slot-names="chip image title unnamed"
dir="ltr"
href="https://github.com/lyne-design-system/lyne-components"
role="link"
tabindex="0"
>
<img
alt="400x300"
slot="image"
src="https://cdn.img.sbb.ch/content/dam/internet/lyne/Billetkontrolle.jpg"
>
<span slot="chip">
Chip
</span>
<span slot="title">
TITLE
</span>
description
</sbb-teaser>
`;
/* end snapshot sbb-teaser renders below with projected content - DOM */

snapshots["sbb-teaser renders below with projected content - ShadowDOM"] =
`<a
class="sbb-teaser"
href="https://github.com/lyne-design-system/lyne-components"
role="presentation"
tabindex="-1"
>
<span class="sbb-teaser__container">
<span class="sbb-teaser__image-wrapper">
<slot name="image">
</slot>
</span>
<span class="sbb-teaser__text">
<sbb-chip
class="sbb-teaser__chip"
color="charcoal"
size="xxs"
>
<slot name="chip">
</slot>
</sbb-chip>
<sbb-title
aria-level="5"
class="sbb-teaser__lead"
level="5"
role="heading"
visual-level="5"
>
<slot name="title">
</slot>
</sbb-title>
<span class="sbb-teaser__description">
<slot>
</slot>
</span>
</span>
</span>
</a>
`;
/* end snapshot sbb-teaser renders below with projected content - ShadowDOM */

snapshots["sbb-teaser renders static - DOM"] =
`<sbb-teaser
alignment="after-centered"
dir="ltr"
>
</sbb-teaser>
`;
/* end snapshot sbb-teaser renders static - DOM */

snapshots["sbb-teaser renders static - ShadowDOM"] =
`<span class="sbb-teaser">
<span class="sbb-teaser__container">
<span class="sbb-teaser__image-wrapper">
<slot name="image">
</slot>
</span>
<span class="sbb-teaser__text">
<sbb-chip
class="sbb-teaser__chip"
color="charcoal"
size="xxs"
>
<slot name="chip">
</slot>
</sbb-chip>
<sbb-title
aria-level="5"
class="sbb-teaser__lead"
level="5"
role="heading"
visual-level="5"
>
<slot name="title">
</slot>
</sbb-title>
<span class="sbb-teaser__description">
<slot>
</slot>
</span>
</span>
</span>
</span>
`;
/* end snapshot sbb-teaser renders static - ShadowDOM */

65 changes: 47 additions & 18 deletions src/components/teaser/readme.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,48 @@
The `sbb-teaser` is a component which can display an image with a caption, and it behaves like a link on user interaction.

Simple teaser example:

```html
<sbb-teaser
href="https://www.sbb.ch"
title-level="2"
title-content="Title"
chip-content="Chip label"
>
<img slot="image" src="..." alt="400x300" />
A brief description.
</sbb-teaser>
```

## Slots

The component displays the `image`, the `title` and the `description` in the self-named slots.
The default slot is reserved for the description. The component displays the `image` and the `title` with the self-named slots.
It's also possible to display a [sbb-chip](/docs/components-sbb-chip--docs) using the `chip` slot.

```html
<sbb-teaser href="https://www.sbb.ch">
<sbb-teaser href="https://www.sbb.ch" title-level="2">
<img slot="image" src="..." alt="400x300" />
<span slot="title"> Title </span>
<span slot="description"> A brief description. </span>
<span slot="chip">Chip label</span>
<span slot="title">Title</span>
A brief description.
</sbb-teaser>
```

The title level can be set by the consumer using the `titleLevel` property.
## Style

Using the `alignment` property, it is possible to change the text position respect to the image.
Possible values are `after-centered` (default), `after` and `below`.

```html
<sbb-teaser href="https://www.sbb.ch" aligment="below"> ... </sbb-teaser>
```

By default, the image dimensions are set using the width and the aspect ratio.
Default values are `300px` and `4/3`. Consumers can change these values on their slotted image element.

## Accessibility

It's important to set the `accessibilityLabel` property, which describes the `sbb-teaser` for screen-reader users.
It's important to set the `aria-label` on the `<sbb-teaser>`, which describes the `sbb-teaser` for screen-reader users.

The description text is wrapped into an `<p>` element to guarantee the semantic meaning.

Expand All @@ -26,18 +52,21 @@ Avoid slotting block elements (e.g. `<div>`) as this violates semantic rules and

## Properties

| Name | Attribute | Privacy | Type | Default | Description |
| ------------ | ------------- | ------- | ---------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `isStacked` | `is-stacked` | public | `boolean` | | Teaser variant - when this is true the text-content will be under the image otherwise it will be displayed next to the image. |
| `titleLevel` | `title-level` | public | `TitleLevel` | `'5'` | Heading level of the sbb-title element (e.g. h1-h6). |
| `href` | `href` | public | `string \| undefined` | | The href value you want to link to. |
| `target` | `target` | public | `LinkTargetType \| string \| undefined \| undefined` | | Where to display the linked URL. |
| `rel` | `rel` | public | `string \| undefined \| undefined` | | The relationship of the linked URL as space-separated link types. |
| Name | Attribute | Privacy | Type | Default | Description |
| -------------- | --------------- | ------- | ---------------------------------------------------- | ------------------ | ------------------------------------------------------------------------- |
| `alignment` | `alignment` | public | `'after-centered' \| 'after' \| 'below'` | `'after-centered'` | Teaser variant - define the position and the alignment of the text block. |
| `titleLevel` | `title-level` | public | `TitleLevel` | `'5'` | Heading level of the sbb-title element (e.g. h1-h6). |
| `titleContent` | `title-content` | public | `string \| undefined` | | Content of title. |
| `chipContent` | `chip-content` | public | `string \| undefined` | | Content of chip. |
| `href` | `href` | public | `string \| undefined` | | The href value you want to link to. |
| `target` | `target` | public | `LinkTargetType \| string \| undefined \| undefined` | | Where to display the linked URL. |
| `rel` | `rel` | public | `string \| undefined \| undefined` | | The relationship of the linked URL as space-separated link types. |

## Slots

| Name | Description |
| ------------- | ----------------------------------- |
| `image` | Slot used to render the image |
| `title` | Slot used to render the title |
| `description` | Slot used to render the description |
| Name | Description |
| ------- | ----------------------------------------------- |
| `image` | Slot used to render the image. |
| `chip` | Slot used to render the sbb-chip label. |
| `title` | Slot used to render the title. |
| | Use the unnamed slot to render the description. |
36 changes: 29 additions & 7 deletions src/components/teaser/teaser.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
import { expect, fixture } from '@open-wc/testing';
import { assert, expect, fixture } from '@open-wc/testing';
import { html } from 'lit/static-html.js';

import { waitForLitRender } from '../core/testing';
import { EventSpy, waitForLitRender } from '../core/testing';

import type { SbbTeaserElement } from './teaser';
import '.';
import { SbbTeaserElement } from './teaser';

describe('sbb-teaser', () => {
let element: SbbTeaserElement;

it('should receive focus', async () => {
element = await fixture(html`<sbb-teaser href="link" id="focus-id">Hero content</sbb-teaser>`);
beforeEach(async () => {
element = await fixture(html`<sbb-teaser id="focus-id" href="#">Content</sbb-teaser>`);
await waitForLitRender(element);
});

it('should render', async () => {
assert.instanceOf(element, SbbTeaserElement);
});

it('should receive focus', async () => {
element.focus();
await waitForLitRender(element);

expect(document.activeElement.id).to.be.equal('focus-id');
});

it('dispatches event on click', async () => {
const clickSpy = new EventSpy('click');

element.click();
expect(clickSpy.count).to.be.equal(1);
});

it('should dispatch event on click if is-static', async () => {
element.setAttribute('is-static', 'true');

const clickSpy = new EventSpy('click');
await waitForLitRender(element);

element.click();
expect(clickSpy.count).to.be.equal(1);
});
});
Loading

0 comments on commit ba5f86c

Please sign in to comment.