-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ✨ sd-media-teaser – add component (#725)
Co-authored-by: Kohler, Samuel <[email protected]>
- Loading branch information
Showing
3 changed files
with
423 additions
and
0 deletions.
There are no files selected for viewing
251 changes: 251 additions & 0 deletions
251
packages/components/src/components/teaser-media/teaser-media.stories.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,251 @@ | ||
import '../../solid-components'; | ||
import { html } from 'lit'; | ||
import { storybookDefaults, storybookHelpers, storybookTemplate } from '../../../scripts/storybook/helper'; | ||
|
||
const { argTypes, parameters } = storybookDefaults('sd-teaser-media'); | ||
const { overrideArgs } = storybookHelpers('sd-teaser-media'); | ||
const { generateTemplate } = storybookTemplate('sd-teaser-media'); | ||
|
||
export default { | ||
title: 'Components/sd-teaser-media', | ||
component: 'sd-teaser-media', | ||
args: overrideArgs([ | ||
{ | ||
type: 'slot', | ||
name: 'default', | ||
value: `<div class="slot slot--border slot--text h-12">Main slot</div>` | ||
}, | ||
{ | ||
type: 'slot', | ||
name: 'media', | ||
value: `<div slot="media" class="slot slot--border slot--text h-[384px]">Media slot</div>` | ||
}, | ||
{ | ||
type: 'slot', | ||
name: 'meta', | ||
value: `<div slot="meta" class="slot slot--border slot--text h-12">Meta slot</div>` | ||
} | ||
]), | ||
argTypes, | ||
parameters | ||
}; | ||
|
||
/** | ||
* This shows sd-teaser-media in its default state. | ||
*/ | ||
|
||
export const Default = { | ||
render: (args: any) => { | ||
return generateTemplate({ args }); | ||
} | ||
}; | ||
|
||
/** | ||
* Teaser-Media in all possible `variant`. | ||
*/ | ||
|
||
export const Variant = { | ||
name: 'Variant', | ||
parameters: { controls: { exclude: ['variant'] } }, | ||
render: (args: any) => { | ||
return generateTemplate({ | ||
axis: { | ||
y: { type: 'attribute', name: 'variant' } | ||
}, | ||
args, | ||
constants: [ | ||
{ | ||
type: 'template', | ||
name: 'style', | ||
value: '<div style="margin-bottom: 40px; width: 600px">%TEMPLATE%</div>' | ||
}, | ||
{ | ||
type: 'slot', | ||
name: 'media', | ||
value: | ||
'<img slot="media" class="aspect-video object-cover" src="./placeholders/generic.jpg" alt="A skyline of a city by night"/>' | ||
} | ||
] | ||
}); | ||
} | ||
}; | ||
|
||
/** | ||
* Use the 'default', 'media', 'meta', 'expandable' and 'headline' slots to add content to the teaser. Please make sure to use semantically correct headline tags for the `headline` slot to provide accessible content. | ||
*/ | ||
export const Slots = { | ||
parameters: { | ||
controls: { exclude: ['default', 'media', 'meta', 'headline', 'expandable'] } | ||
}, | ||
render: (args: any) => { | ||
return html` | ||
${['default', 'media', 'meta', 'headline', 'expandable'].map(slot => { | ||
let value = `<div slot='${slot}' class="slot slot--border slot--background h-16"></div>`; | ||
if (slot === 'default') { | ||
value = `<div class="slot slot--border slot--background h-16"></div>`; | ||
} else if (slot === 'media') { | ||
value = `<div slot='${slot}' class="slot slot--border slot--background h-[577px]"></div>`; | ||
} else if (slot === 'expandable') { | ||
value = `<div slot='${slot}' class="slot--border slot--background h-16 box-border flex flex-col items-center justify-center rounded-md"></div>`; | ||
} | ||
return generateTemplate({ | ||
axis: { | ||
x: { | ||
type: 'slot', | ||
name: slot, | ||
title: 'slot=..', | ||
values: [ | ||
{ | ||
value: value, | ||
title: slot | ||
} | ||
] | ||
} | ||
}, | ||
args, | ||
constants: [ | ||
{ | ||
type: 'slot', | ||
name: 'media', | ||
value: `<img slot='media' src='./placeholders/collaboration.jpg' alt='Test'/>` | ||
}, | ||
{ | ||
type: 'slot', | ||
name: 'meta', | ||
value: `<slot slot='meta'>Teaser's Meta information</slot>` | ||
}, | ||
{ | ||
type: 'slot', | ||
name: 'default', | ||
value: `<slot>Teaser's Main content</slot>` | ||
}, | ||
{ | ||
type: 'slot', | ||
name: 'headline', | ||
value: `<slot slot='headline'>Teaser's Headline</slot>` | ||
}, | ||
{ | ||
type: 'slot', | ||
name: 'expandable', | ||
value: `<slot slot='expandable'>Teaser's Expandable content</slot>` | ||
}, | ||
{ | ||
type: 'template', | ||
name: 'style', | ||
value: '<div style="margin-bottom: 40px; width: 782px;">%TEMPLATE%</div>' | ||
} | ||
] | ||
}); | ||
})} | ||
`; | ||
} | ||
}; | ||
|
||
export const Parts = { | ||
parameters: { | ||
controls: { exclude: ['base', 'media', 'content', 'meta', 'headline', 'main', 'expandable', 'variant'] } | ||
}, | ||
render: (args: any) => { | ||
return generateTemplate({ | ||
axis: { | ||
y: { | ||
type: 'template', | ||
name: 'sd-teaser-media::part(...){outline: solid 2px red}', | ||
values: ['base', 'media', 'content', 'meta', 'headline', 'main', 'expandable'].map(part => { | ||
return { | ||
title: part, | ||
value: `<style>#part-${part} sd-teaser-media::part(${part}){outline: solid 2px red}</style><div id="part-${part}">%TEMPLATE%</div>` | ||
}; | ||
}) | ||
} | ||
}, | ||
args, | ||
constants: [ | ||
{ | ||
type: 'template', | ||
name: 'style', | ||
value: '<div style="margin-bottom: 40px; width: 500px">%TEMPLATE%</div>' | ||
}, | ||
{ | ||
type: 'attribute', | ||
name: 'variant', | ||
value: 'white' | ||
}, | ||
{ | ||
type: 'slot', | ||
name: 'expandable', | ||
value: `<div slot="expandable" class="slot--border slot--text box-border flex flex-col items-center justify-center rounded-md"><p>Expandable slot</p></div>` | ||
} | ||
] | ||
}); | ||
} | ||
}; | ||
|
||
export const Samples = { | ||
name: 'Samples: Teaser-Media', | ||
parameters: { | ||
controls: { | ||
disable: true | ||
}, | ||
backgrounds: { | ||
default: 'white' | ||
} | ||
}, | ||
render: () => { | ||
return html` | ||
<style> | ||
#teaserWithContentPlaceholder::part(media) { | ||
flex-grow: 1; | ||
} | ||
</style> | ||
<div class="flex flex-wrap gap-8"> | ||
<sd-teaser-media variant="gradient-dark" class="min-w-[435px] max-w-4xl"> | ||
<div slot="media" class="relative"> | ||
<img class="aspect-video object-cover" src="./placeholders/architecture.jpg" alt="A skyline of a city" /> | ||
</div> | ||
<div slot="meta" class="meta-info"> | ||
<span class="meta-info-item">01.12.2013</span> | ||
<span class="meta-info-item">| Author name</span> | ||
</div> | ||
<h3 slot="headline">Not expandable teaser-media</h3> | ||
<div class="flex flex-col gap-4"> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> | ||
<div class="flex-none"> | ||
<sd-button href="#" target="_blank" variant="primary" inverted>Link</sd-button> | ||
</div> | ||
</div> | ||
</sd-teaser-media> | ||
<sd-teaser-media variant="gradient-white" class="min-w-[435px] max-w-4xl"> | ||
<div slot="media" class="relative"> | ||
<img class="aspect-video object-cover" src="./placeholders/architecture.jpg" alt="A skyline of a city" /> | ||
</div> | ||
<div slot="meta" class="meta-info"> | ||
<span class="meta-info-item">01.12.2013</span> | ||
<span class="meta-info-item">| Author name</span> | ||
</div> | ||
<h3 slot="headline">Expandable teaser-media</h3> | ||
<div slot="expandable"> | ||
<p> | ||
Expandable: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut | ||
labore et dolore magna aliqua. | ||
</p> | ||
</div> | ||
<div class="flex flex-col gap-4"> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et | ||
dolore magna aliqua. | ||
</p> | ||
<div class="flex-none"> | ||
<sd-button href="#" target="_blank" variant="primary">Link</sd-button> | ||
</div> | ||
<div class="flex-none text-sm"> | ||
<p>@Copyright Lorem ipsum</p> | ||
</div> | ||
</div> | ||
</sd-teaser-media> | ||
</div> | ||
`; | ||
} | ||
}; |
43 changes: 43 additions & 0 deletions
43
packages/components/src/components/teaser-media/teaser-media.test.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,43 @@ | ||
import { expect, fixture, html } from '@open-wc/testing'; | ||
import type SdTeaserMedia from './teaser-media'; | ||
|
||
describe('<sd-teaser-media>', () => { | ||
it('renders default values correctly', async () => { | ||
const el = await fixture<SdTeaserMedia>(html`<sd-teaser-media></sd-teaser-media>`); | ||
|
||
expect(el.variant).to.equal('white'); | ||
}); | ||
|
||
it('renders assigned values correctly', async () => { | ||
const el = await fixture<SdTeaserMedia>(html`<sd-teaser-media variant="neutral-100"></sd-teaser-media>`); | ||
|
||
expect(el.variant).to.equal('neutral-100'); | ||
}); | ||
|
||
it('renders slots correctly', async () => { | ||
const el = await fixture<SdTeaserMedia>(html` | ||
<sd-teaser-media> | ||
<div slot="media">Media</div> | ||
<div slot="meta">Meta</div> | ||
<div slot="headline">Headline</div> | ||
<div slot="main">Main</div> | ||
<div slot="expandable">Expandable</div> | ||
</sd-teaser-media> | ||
`); | ||
|
||
expect(el.shadowRoot!.querySelector<HTMLElement>('[part~="media"]')).to.exist; | ||
expect(el.shadowRoot!.querySelector<HTMLElement>('[part~="meta"]')).to.exist; | ||
expect(el.shadowRoot!.querySelector<HTMLElement>('[part~="headline"]')).to.exist; | ||
expect(el.shadowRoot!.querySelector<HTMLElement>('[part~="main"]')).to.exist; | ||
expect(el.shadowRoot!.querySelector<HTMLElement>('[part~="expandable"]')).to.exist; | ||
}); | ||
|
||
it('hides slots correctly', async () => { | ||
const el = await fixture<SdTeaserMedia>(html` <sd-teaser-media> </sd-teaser-media> `); | ||
|
||
expect(el.shadowRoot!.querySelector<HTMLElement>('[part~="media"]')?.classList.contains('hidden')).to.be.true; | ||
expect(el.shadowRoot!.querySelector<HTMLElement>('[part~="meta"]')?.classList.contains('hidden')).to.be.true; | ||
expect(el.shadowRoot!.querySelector<HTMLElement>('[part~="main"]')?.classList.contains('hidden')).to.be.true; | ||
expect(el.shadowRoot!.querySelector<HTMLElement>('[part~="expandable"]')?.classList.contains('hidden')).to.be.true; | ||
}); | ||
}); |
Oops, something went wrong.