Skip to content

Commit

Permalink
feat: ✨ sd-media-teaser – add component (#725)
Browse files Browse the repository at this point in the history
Co-authored-by: Kohler, Samuel <[email protected]>
  • Loading branch information
saemik94 and saemik94 authored Feb 9, 2024
1 parent 71bfdf4 commit 974a951
Show file tree
Hide file tree
Showing 3 changed files with 423 additions and 0 deletions.
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>
`;
}
};
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;
});
});
Loading

0 comments on commit 974a951

Please sign in to comment.