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(pie-thumbnail): DSW-2580 add basic thumbnail functionality #2138

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
6 changes: 6 additions & 0 deletions .changeset/wicked-windows-admire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@justeattakeaway/pie-thumbnail": minor
"pie-storybook": minor
---

added basic functionality of thumbnail component
60 changes: 49 additions & 11 deletions apps/pie-storybook/stories/pie-thumbnail.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,71 @@ import { html } from 'lit';
import { type Meta } from '@storybook/web-components';

import '@justeattakeaway/pie-thumbnail';
import { type ThumbnailProps } from '@justeattakeaway/pie-thumbnail';
import { type ThumbnailProps, defaultProps, variants } from '@justeattakeaway/pie-thumbnail';

import { createStory } from '../utilities';
import { createStory, type TemplateFunction } from '../utilities';

type ThumbnailStoryMeta = Meta<ThumbnailProps>;

const defaultArgs: ThumbnailProps = {};
const defaultArgs: ThumbnailProps = {
...defaultProps,
src: 'https://www.takeaway.com/consumer-web/images/takeaway-brand.61e55e0b.svg',
alt: 'JET logo',
};

const thumbnailStoryMeta: ThumbnailStoryMeta = {
title: 'Thumbnail',
component: 'pie-thumbnail',
argTypes: {},
argTypes: {
variant: {
description: 'Set the variant of the thumbnail.',
control: 'select',
options: variants,
defaultValue: {
summary: defaultArgs.variant,
},
},
src: {
description: 'Set the src attribute for the underlying image tag.',
control: 'text',
defaultValue: {
summary: defaultArgs.src,
},
},
alt: {
description: 'Set the alt attribute for the underlying image tag.',
control: 'text',
defaultValue: {
summary: defaultArgs.alt,
},
},
},
args: defaultArgs,
parameters: {
design: {
type: 'figma',
url: '',
url: 'https://www.figma.com/design/pPSC73rPin4csb8DiK1CRr/branch/z8B7RUnz2Oq8cplqN38E9j/%E2%9C%A8-%5BCore%5D-Web-Components-%5BPIE-3%5D?node-id=17054-19120&node-type=instance&m=dev',
},
},
};

export default thumbnailStoryMeta;

// TODO: remove the eslint-disable rule when props are added
// eslint-disable-next-line no-empty-pattern
const Template = ({}: ThumbnailProps) => html`
<pie-thumbnail></pie-thumbnail>
`;
const Template: TemplateFunction<ThumbnailProps> = ({
variant,
src,
alt,
}) => html`
<pie-thumbnail
variant="${variant}"
src="${src}"
alt="${alt}">
</pie-thumbnail>`;

const createThumbnailStory = createStory<ThumbnailProps>(Template, defaultArgs);

export const Default = createThumbnailStory({}, {});

export const Default = createStory<ThumbnailProps>(Template, defaultArgs)();
export const Outline = createThumbnailStory({
variant: 'outline',
}, {});
75 changes: 59 additions & 16 deletions apps/pie-storybook/stories/testing/pie-thumbnail.test.stories.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,77 @@
import { html } from 'lit';
import { type Meta } from '@storybook/web-components';

import '@justeattakeaway/pie-thumbnail';
import { type ThumbnailProps } from '@justeattakeaway/pie-thumbnail';
import { type ThumbnailProps, defaultProps, variants } from '@justeattakeaway/pie-thumbnail';

import { createStory } from '../../utilities';
import { type Meta } from '@storybook/web-components';
import { createVariantStory, type TemplateFunction } from '../../utilities';

type ThumbnailStoryMeta = Meta<ThumbnailProps>;

const defaultArgs: ThumbnailProps = {};
Copy link
Member

@raoufswe raoufswe Jan 7, 2025

Choose a reason for hiding this comment

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

i think we need to revert this line and assign the default values from the component itself

it will be something like

const defaultArgs: ThumbnailProps = { ...defaultProps, };

and defaultProps is imported from '@justeattakeaway/pie-thumbnail'

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The defaults for storybook are

const defaultArgs: ThumbnailProps = {
    ...defaultProps,
    src: 'https://www.takeaway.com/consumer-web/images/takeaway-brand.61e55e0b.svg',
    alt: 'JET logo',
};

do you think we should use the same for tests? (Component defaults for src and alt are now empty strings)

Copy link
Member

Choose a reason for hiding this comment

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

Yes we can use the same for tests

const defaultArgs: ThumbnailProps = {
...defaultProps,
src: 'https://www.takeaway.com/consumer-web/images/takeaway-brand.61e55e0b.svg',
alt: 'JET logo',
};

const thumbnailStoryMeta: ThumbnailStoryMeta = {
title: 'Thumbnail',
component: 'pie-thumbnail',
argTypes: {},
args: defaultArgs,
raoufswe marked this conversation as resolved.
Show resolved Hide resolved
parameters: {
design: {
type: 'figma',
url: '',
argTypes: {
variant: {
description: 'Set the variant of the thumbnail.',
control: 'select',
options: variants,
defaultValue: {
summary: defaultArgs.variant,
},
},
src: {
description: 'Set the src attribute for the underlying image tag.',
control: 'text',
defaultValue: {
summary: defaultArgs.src,
},
},
alt: {
description: 'Set the alt attribute for the underlying image tag.',
control: 'text',
defaultValue: {
summary: defaultArgs.alt,
},
},
},
args: defaultArgs,
};

export default thumbnailStoryMeta;

// TODO: remove the eslint-disable rule when props are added
// eslint-disable-next-line no-empty-pattern
const Template = ({}: ThumbnailProps) => html`
<pie-thumbnail></pie-thumbnail>
`;
const Template: TemplateFunction<ThumbnailProps> = ({
variant,
src,
alt,
}) => html`
<pie-thumbnail
variant="${variant}"
src="${src}"
alt="${alt}">
</pie-thumbnail>`;

// Define the prop options for the matrix
const sharedPropOptions = {
src: ['https://www.takeaway.com/consumer-web/images/takeaway-brand.61e55e0b.svg'],
alt: ['JET logo'],
};

const defaultPropOptions = {
...sharedPropOptions,
variant: ['default'],
};

const outlinePropOptions = {
...sharedPropOptions,
variant: ['outline'],
};

export const Default = createStory<ThumbnailProps>(Template, defaultArgs)();
export const DefaultPropVariations = createVariantStory<ThumbnailProps>(Template, defaultPropOptions);
export const OutlinePropVariations = createVariantStory<ThumbnailProps>(Template, outlinePropOptions);
22 changes: 19 additions & 3 deletions packages/components/pie-thumbnail/src/defs.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
// TODO - please remove the eslint disable comment below when you add props to this interface
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ThumbnailProps {}
import type { ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';

export const variants = [
'default', 'outline',
] as const;

export interface ThumbnailProps {
variant?: typeof variants[number];
src?: string;
alt?: string;
}

export type DefaultProps = ComponentDefaultProps<ThumbnailProps, 'variant' | 'src' | 'alt'>;

export const defaultProps: DefaultProps = {
variant: 'default',
src: '',
alt: '',
};
37 changes: 33 additions & 4 deletions packages/components/pie-thumbnail/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { LitElement, html, unsafeCSS } from 'lit';
import {
LitElement, html, unsafeCSS,
} from 'lit';

import { defineCustomElement } from '@justeattakeaway/pie-webc-core';
import { defineCustomElement, validPropertyValues } from '@justeattakeaway/pie-webc-core';
import { classMap } from 'lit/directives/class-map.js';
import { property } from 'lit/decorators.js';
import { type ThumbnailProps, defaultProps, variants } from './defs';
import styles from './thumbnail.scss?inline';
import { type ThumbnailProps } from './defs';

// Valid values available to consumers
export * from './defs';
Expand All @@ -13,8 +17,33 @@ const componentSelector = 'pie-thumbnail';
* @tagname pie-thumbnail
*/
export class PieThumbnail extends LitElement implements ThumbnailProps {
@property({ type: String })
@validPropertyValues(componentSelector, variants, defaultProps.variant)
public variant = defaultProps.variant;

@property({ type: String })
public src = defaultProps.src;

@property({ type: String })
public alt = defaultProps.alt;

render () {
return html`<h1 data-test-id="pie-thumbnail">Hello world!</h1>`;
const {
variant,
src,
alt,
} = this;

const wrapperClasses = {
'c-thumbnail': true,
[`c-thumbnail--${variant}`]: true,
};

return html`
<div data-test-id="pie-thumbnail" class="${classMap(wrapperClasses)}">
<img data-test-id="pie-thumbnail-img" src="${src}" class="c-thumbnail-img" alt="${alt}">
</div>
`;
}

// Renders a `CSSResult` generated from SCSS by Vite
Expand Down
27 changes: 27 additions & 0 deletions packages/components/pie-thumbnail/src/thumbnail.scss
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
@use '@justeattakeaway/pie-css/scss' as p;

// Base thumbnail styles
.c-thumbnail {
--thumbnail-size-small: var(--dt-spacing-g);
--thumbnail-border-radius-small: var(--dt-radius-rounded-b);
--thumbnail-bg-color: var(--dt-color-container-default);
--thumbnail-border-outline: 1px solid var(--dt-color-border-default);

&.c-thumbnail--outline {
--thumbnail-border: var(--thumbnail-border-outline);
}

box-sizing: border-box;
width: var(--thumbnail-size-small);
height: var(--thumbnail-size-small);
border-radius: var(--thumbnail-border-radius-small);
border: var(--thumbnail-border);
background-color: var(--thumbnail-bg-color);
}

.c-thumbnail-img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
border-radius: var(--thumbnail-border-radius-small);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { test } from '@playwright/test';
import percySnapshot from '@percy/playwright';
import { percyWidths } from '@justeattakeaway/pie-webc-testing/src/percy/breakpoints.ts';
import { BasePage } from '@justeattakeaway/pie-webc-testing/src/helpers/page-object/base-page.ts';
import { variants } from '../../src/defs.ts';

test.describe('PieThumbnail - Visual tests`', () => {
test('should display the PieThumbnail component successfully', async ({ page }) => {
const basePage = new BasePage(page, 'thumbnail--default');
variants.forEach((variant) => test(`should render all prop variations for Variant: ${variant}`, async ({ page }) => {
const basePage = new BasePage(page, `thumbnail--${variant}-prop-variations`);

basePage.load();
await page.waitForTimeout(2500);
basePage.load();

await percySnapshot(page, 'PieThumbnail - Visual Test');
});
});
await page.waitForTimeout(5000);

await percySnapshot(page, `PIE Thumbnail - Variant: ${variant}`, percyWidths);
}));
Loading