-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sbb-lead-container): initial implementation (#2672)
- Loading branch information
1 parent
35c7c21
commit bb1f3a8
Showing
13 changed files
with
471 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export async function loadAssetAsBase64(url: string): Promise<string> { | ||
return URL.createObjectURL(await fetch(url).then((r) => r.blob())); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './lead-container/lead-container.js'; |
51 changes: 51 additions & 0 deletions
51
src/components/lead-container/__snapshots__/lead-container.snapshot.spec.snap.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* @web/test-runner snapshot v1 */ | ||
export const snapshots = {}; | ||
|
||
snapshots["sbb-lead-container DOM"] = | ||
`<sbb-lead-container> | ||
<sbb-image | ||
aspect-ratio="16-9" | ||
border-radius="default" | ||
slot="image" | ||
> | ||
</sbb-image> | ||
</sbb-lead-container> | ||
`; | ||
/* end snapshot sbb-lead-container DOM */ | ||
|
||
snapshots["sbb-lead-container Shadow DOM"] = | ||
`<div class="sbb-lead-container"> | ||
<div class="sbb-lead-container-image"> | ||
<slot name="image"> | ||
</slot> | ||
</div> | ||
<div class="sbb-lead-container-content-wrapper"> | ||
<div class="sbb-lead-container-content"> | ||
<slot> | ||
</slot> | ||
</div> | ||
</div> | ||
</div> | ||
`; | ||
/* end snapshot sbb-lead-container Shadow DOM */ | ||
|
||
snapshots["sbb-lead-container A11y tree Chrome"] = | ||
`<p> | ||
{ | ||
"role": "WebArea", | ||
"name": "" | ||
} | ||
</p> | ||
`; | ||
/* end snapshot sbb-lead-container A11y tree Chrome */ | ||
|
||
snapshots["sbb-lead-container A11y tree Firefox"] = | ||
`<p> | ||
{ | ||
"role": "document", | ||
"name": "" | ||
} | ||
</p> | ||
`; | ||
/* end snapshot sbb-lead-container A11y tree Firefox */ | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
@use '../core/styles' as sbb; | ||
|
||
// Box-sizing rules contained in typography are not traversing Shadow DOM boundaries. We need to include box-sizing mixin in every component. | ||
@include sbb.box-sizing; | ||
|
||
:host { | ||
display: block; | ||
|
||
--sbb-lead-container-background-color: var(--sbb-color-white); | ||
--sbb-lead-container-image-ratio: 2 / 1; | ||
--sbb-lead-container-image-overlap: var(--sbb-spacing-fixed-24x); | ||
--sbb-lead-container-padding-block: var(--sbb-spacing-responsive-l); | ||
--sbb-lead-container-padding-inline: var(--sbb-layout-base-offset-responsive); | ||
--sbb-lead-container-border-radius: var(--sbb-border-radius-6x); | ||
--sbb-lead-container-image-border-radius: 0; | ||
|
||
@include sbb.mq($from: wide) { | ||
--sbb-lead-container-image-ratio: 21 / 9; | ||
} | ||
|
||
@include sbb.mq($from: ultra) { | ||
--sbb-lead-container-image-border-radius: var(--sbb-lead-container-border-radius); | ||
} | ||
} | ||
|
||
.sbb-lead-container { | ||
padding-block-end: var(--sbb-spacing-responsive-l); | ||
} | ||
|
||
::slotted(sbb-image[slot='image']) { | ||
--sbb-image-aspect-ratio: var(--sbb-lead-container-image-ratio); | ||
--sbb-image-border-radius: var(--sbb-lead-container-image-border-radius); | ||
} | ||
|
||
::slotted(:is(img[slot='image'], picture[slot='image'])) { | ||
display: block; | ||
width: 100%; | ||
object-fit: cover; | ||
aspect-ratio: var(--sbb-lead-container-image-ratio); | ||
border-radius: var(--sbb-lead-container-image-border-radius); | ||
} | ||
|
||
::slotted(:is(sbb-breadcrumb-group, sbb-block-link).sbb-lead-container-spacing) { | ||
margin-block-end: var(--sbb-spacing-fixed-4x); | ||
} | ||
|
||
::slotted(sbb-title.sbb-lead-container-spacing) { | ||
margin-block-start: 0; | ||
} | ||
|
||
::slotted(.sbb-lead-container-lead-text) { | ||
margin-block: 0 var(--sbb-spacing-responsive-s); | ||
} | ||
|
||
.sbb-lead-container-image { | ||
@include sbb.mq($from: ultra) { | ||
max-width: calc( | ||
var(--sbb-layout-base-page-max-width) + 2 * var(--sbb-layout-base-offset-responsive) | ||
); | ||
margin-inline: auto; | ||
} | ||
} | ||
|
||
.sbb-lead-container-content-wrapper { | ||
@include sbb.grid; | ||
|
||
// In case there is a global background color set, use full width with white color until large breakpoint | ||
background-color: var(--sbb-lead-container-background-color); | ||
|
||
@include sbb.mq($from: large) { | ||
background-color: transparent; | ||
} | ||
} | ||
|
||
.sbb-lead-container-content { | ||
z-index: 1; | ||
border-radius: var(--sbb-lead-container-border-radius); | ||
padding-block: var(--sbb-lead-container-padding-block); | ||
background-color: var(--sbb-lead-container-background-color); | ||
grid-column: 1 / -1; | ||
|
||
@include sbb.mq($from: medium) { | ||
grid-column: 2 / -2; | ||
} | ||
|
||
@include sbb.mq($from: large) { | ||
margin-block-start: calc(-1 * var(--sbb-lead-container-image-overlap)); | ||
padding-inline: var(--sbb-lead-container-padding-inline); | ||
|
||
// As the content should be aligned to the grid, we have to stretch the container by padding | ||
margin-inline: calc(-1 * var(--sbb-lead-container-padding-inline)); | ||
} | ||
|
||
@include sbb.mq($from: wide) { | ||
grid-column: 3 / -3; | ||
} | ||
|
||
@include sbb.mq($from: ultra) { | ||
grid-column: 4 / -4; | ||
} | ||
} |
133 changes: 133 additions & 0 deletions
133
src/components/lead-container/lead-container.snapshot.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
import { aTimeout, expect } from '@open-wc/testing'; | ||
import type { TemplateResult } from 'lit'; | ||
import { html } from 'lit/static-html.js'; | ||
|
||
import { | ||
describeViewports, | ||
fixture, | ||
isVisualRegressionRun, | ||
loadAssetAsBase64, | ||
testA11yTreeSnapshot, | ||
testVisualDiff, | ||
visualRegressionFixture, | ||
} from '../core/testing/private.js'; | ||
import { waitForCondition } from '../core/testing/wait-for-condition.js'; | ||
|
||
import type { SbbLeadContainerElement } from './lead-container.js'; | ||
|
||
import '../breadcrumb.js'; | ||
import '../image.js'; | ||
import '../link/block-link/block-link.js'; | ||
import '../title.js'; | ||
import './lead-container.js'; | ||
|
||
const leadImageUrl = import.meta.resolve('./assets/lucerne.png'); | ||
const leadImageBase64 = await loadAssetAsBase64(leadImageUrl); | ||
|
||
describe(`sbb-lead-container`, () => { | ||
if (!isVisualRegressionRun()) { | ||
let element: SbbLeadContainerElement; | ||
|
||
beforeEach(async () => { | ||
element = await fixture( | ||
html`<sbb-lead-container> | ||
<sbb-image slot="image"></sbb-image> | ||
</sbb-lead-container>`, | ||
); | ||
}); | ||
|
||
it('DOM', async () => { | ||
await expect(element).dom.to.be.equalSnapshot(); | ||
}); | ||
|
||
it('Shadow DOM', async () => { | ||
await expect(element).shadowDom.to.be.equalSnapshot(); | ||
}); | ||
|
||
testA11yTreeSnapshot(); | ||
} else { | ||
describe('visual-regression', () => { | ||
let root: HTMLElement; | ||
|
||
const wrapperStyles = { backgroundColor: `var(--sbb-color-milk)`, padding: '0' }; | ||
|
||
const leadContainerTemplate = (image: TemplateResult): TemplateResult => html` | ||
<sbb-lead-container> | ||
<style> | ||
p.other-content { | ||
margin-block-end: 0; | ||
} | ||
</style> | ||
${image} | ||
<sbb-breadcrumb-group class="sbb-lead-container-spacing"> | ||
<sbb-breadcrumb href="#" icon-name="house-small" id="breadcrumb-0"></sbb-breadcrumb> | ||
<sbb-breadcrumb href="#" id="breadcrumb-1">Level 1</sbb-breadcrumb> | ||
</sbb-breadcrumb-group> | ||
<sbb-block-link | ||
icon-placement="start" | ||
icon-name="chevron-small-left-small" | ||
size="xs" | ||
href="https://www.sbb.ch" | ||
class="sbb-lead-container-spacing" | ||
> | ||
Link | ||
</sbb-block-link> | ||
<sbb-title class="sbb-lead-container-spacing">Title</sbb-title> | ||
<p class="sbb-text-xl sbb-lead-container-lead-text"> | ||
Lead text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer enim elit, | ||
ultricies in tincidunt quis, mattis eu quam. Nulla sit amet lorem fermentum, molestie | ||
nunc ut, hendrerit risus. | ||
</p> | ||
<p class="sbb-text-m other-content"> | ||
Other content. Vestibulum rutrum elit et lacus sollicitudin, quis malesuada lorem | ||
vehicula. Suspendisse at augue quis tellus vulputate tempor. Vivamus urna velit, varius | ||
nec est ac, mollis efficitur lorem. Quisque non nisl eget massa interdum tempus. | ||
Praesent vel feugiat metus. | ||
</p> | ||
</sbb-lead-container> | ||
`; | ||
|
||
describeViewports(() => { | ||
describe('with sbb-image', () => { | ||
beforeEach(async function () { | ||
root = await visualRegressionFixture( | ||
leadContainerTemplate( | ||
html`<sbb-image | ||
slot="image" | ||
image-src=${leadImageUrl} | ||
alt="Station of Lucerne from outside" | ||
></sbb-image>`, | ||
), | ||
this, | ||
wrapperStyles, | ||
); | ||
await waitForCondition(() => | ||
root.querySelector('sbb-image')!.hasAttribute('data-loaded'), | ||
); | ||
await aTimeout(20); | ||
}); | ||
|
||
testVisualDiff(() => root); | ||
}); | ||
|
||
describe('with img tag', () => { | ||
beforeEach(async function () { | ||
root = await visualRegressionFixture( | ||
leadContainerTemplate( | ||
html`<img | ||
slot="image" | ||
src=${leadImageBase64} | ||
alt="Station of Lucerne from outside" | ||
/>`, | ||
), | ||
this, | ||
wrapperStyles, | ||
); | ||
}); | ||
|
||
testVisualDiff(() => root); | ||
}); | ||
}); | ||
}); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import type { Meta, StoryObj } from '@storybook/web-components'; | ||
import { html, type TemplateResult } from 'lit'; | ||
|
||
import '../breadcrumb.js'; | ||
import '../image.js'; | ||
import '../link/block-link/block-link.js'; | ||
import '../title.js'; | ||
import './lead-container.js'; | ||
|
||
import images from '../core/images.js'; | ||
|
||
import readme from './readme.md?raw'; | ||
|
||
const DefaultTemplate = (): TemplateResult => html` | ||
<sbb-lead-container> | ||
<style> | ||
p.other-content { | ||
margin-block-end: 0; | ||
} | ||
</style> | ||
<sbb-image | ||
slot="image" | ||
image-src=${images[6]} | ||
alt="Station of Lucerne from outside" | ||
></sbb-image> | ||
<sbb-breadcrumb-group class="sbb-lead-container-spacing"> | ||
<sbb-breadcrumb href="#" icon-name="house-small" id="breadcrumb-0"></sbb-breadcrumb> | ||
<sbb-breadcrumb href="#" id="breadcrumb-1">Level 1</sbb-breadcrumb> | ||
<sbb-breadcrumb href="#" id="breadcrumb-1">Level 2</sbb-breadcrumb> | ||
<sbb-breadcrumb href="#" id="breadcrumb-1">Level 3</sbb-breadcrumb> | ||
<sbb-breadcrumb href="#" id="breadcrumb-1">Level 4</sbb-breadcrumb> | ||
</sbb-breadcrumb-group> | ||
<sbb-block-link | ||
icon-placement="start" | ||
icon-name="chevron-small-left-small" | ||
size="xs" | ||
href="https://www.sbb.ch" | ||
class="sbb-lead-container-spacing" | ||
> | ||
Link | ||
</sbb-block-link> | ||
<sbb-title class="sbb-lead-container-spacing">Title</sbb-title> | ||
<p class="sbb-text-xl sbb-lead-container-lead-text"> | ||
Lead text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer enim elit, | ||
ultricies in tincidunt quis, mattis eu quam. Nulla sit amet lorem fermentum, molestie nunc ut, | ||
hendrerit risus. | ||
</p> | ||
<p class="sbb-text-m other-content"> | ||
Other content. Vestibulum rutrum elit et lacus sollicitudin, quis malesuada lorem vehicula. | ||
Suspendisse at augue quis tellus vulputate tempor. Vivamus urna velit, varius nec est ac, | ||
mollis efficitur lorem. Quisque non nisl eget massa interdum tempus. Praesent vel feugiat | ||
metus. | ||
</p> | ||
</sbb-lead-container> | ||
`; | ||
|
||
export const Default: StoryObj = { | ||
render: DefaultTemplate, | ||
}; | ||
|
||
const meta: Meta = { | ||
parameters: { | ||
docs: { | ||
extractComponentDescription: () => readme, | ||
}, | ||
layout: 'fullscreen', | ||
}, | ||
title: 'components/sbb-lead-container', | ||
}; | ||
|
||
export default meta; |
Oops, something went wrong.