From 0de40ae69bae31c14d6dc4a71e657cfe918fa9ca Mon Sep 17 00:00:00 2001 From: "boris.netsov" Date: Fri, 27 Dec 2024 14:59:46 +0200 Subject: [PATCH] feat(pie-thumbnail): DSW-2580 add basic thumbnail functionality format(pie-thumbnail): DSW-2580 lint test(pie-thumbnail): DSW-2580 add visual tests test(pie-thumbnail): DSW-2580 update visual tests refactor(pie-thumbnail): DSW-2580 address comments refactor(pie-thumbnail): DSW-2580 remove placeholder image from storybook chore(pie-thumbnail): DSW-2580 update changelog refactor(pie-thumbnail): DSW-2580 add default src and alt props to visual test refactor(pie-thumbnail): DSW-2580 update based on comments feat(pie-thumbnail): DSW-2580 add basic thumbnail functionality refactor(pie-thumbnail): DSW-2580 address comments refactor(pie-thumbnail): DSW-2580 remove placeholder image from storybook fix(pie-thumbnail): DSW-2580 fix percy test fix(pie-thumbnail): DSW-2580 fix percy test refactor(pie-thumbnail): DSW-2580 update based on comments format(pie-thumbnail): DSW-2580 address comments feat(pie-thumbnail): DSW-2580 add basic thumbnail functionality test(pie-thumbnail): DSW-2580 add visual tests test(pie-thumbnail): DSW-2580 update visual tests refactor(pie-thumbnail): DSW-2580 address comments refactor(pie-thumbnail): DSW-2580 remove placeholder image from storybook feat(pie-thumbnail): DSW-2580 add basic thumbnail functionality test(pie-thumbnail): DSW-2580 add visual tests test(pie-thumbnail): DSW-2580 update visual tests refactor(pie-thumbnail): DSW-2580 address comments refactor(pie-thumbnail): DSW-2580 remove placeholder image from storybook --- .changeset/wicked-windows-admire.md | 6 ++ .../stories/pie-thumbnail.stories.ts | 60 ++++++++++++--- .../testing/pie-thumbnail.test.stories.ts | 75 +++++++++++++++---- packages/components/pie-thumbnail/src/defs.ts | 22 +++++- .../components/pie-thumbnail/src/index.ts | 37 ++++++++- .../pie-thumbnail/src/thumbnail.scss | 26 ++++++- .../test/visual/pie-thumbnail.spec.ts | 17 +++-- 7 files changed, 200 insertions(+), 43 deletions(-) create mode 100644 .changeset/wicked-windows-admire.md diff --git a/.changeset/wicked-windows-admire.md b/.changeset/wicked-windows-admire.md new file mode 100644 index 0000000000..876e6d23e1 --- /dev/null +++ b/.changeset/wicked-windows-admire.md @@ -0,0 +1,6 @@ +--- +"@justeattakeaway/pie-thumbnail": minor +"pie-storybook": minor +--- + +[Added] - basic functionality of thumbnail component diff --git a/apps/pie-storybook/stories/pie-thumbnail.stories.ts b/apps/pie-storybook/stories/pie-thumbnail.stories.ts index 8fb5c123c0..2a1f731c38 100644 --- a/apps/pie-storybook/stories/pie-thumbnail.stories.ts +++ b/apps/pie-storybook/stories/pie-thumbnail.stories.ts @@ -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; -const defaultArgs: ThumbnailProps = {}; +const defaultArgs: ThumbnailProps = { + ...defaultProps, + src: 'https://www.pie.design/assets/img/jet-logo-narrow.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` - -`; +const Template: TemplateFunction = ({ + variant, + src, + alt, +}) => html` + + `; + +const createThumbnailStory = createStory(Template, defaultArgs); + +export const Default = createThumbnailStory({}, {}); -export const Default = createStory(Template, defaultArgs)(); +export const Outline = createThumbnailStory({ + variant: 'outline', +}, {}); diff --git a/apps/pie-storybook/stories/testing/pie-thumbnail.test.stories.ts b/apps/pie-storybook/stories/testing/pie-thumbnail.test.stories.ts index 119355b47a..013c3ef3bc 100644 --- a/apps/pie-storybook/stories/testing/pie-thumbnail.test.stories.ts +++ b/apps/pie-storybook/stories/testing/pie-thumbnail.test.stories.ts @@ -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; -const defaultArgs: ThumbnailProps = {}; +const defaultArgs: ThumbnailProps = { + ...defaultProps, + src: 'https://www.pie.design/assets/img/jet-logo-narrow.svg', + alt: 'JET logo', +}; const thumbnailStoryMeta: ThumbnailStoryMeta = { title: 'Thumbnail', component: 'pie-thumbnail', - argTypes: {}, - args: defaultArgs, - 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` - -`; +const Template: TemplateFunction = ({ + variant, + src, + alt, +}) => html` + + `; + +// Define the prop options for the matrix +const sharedPropOptions = { + src: ['https://www.pie.design/assets/img/jet-logo-narrow.svg'], + alt: ['JET logo'], +}; + +const defaultPropOptions = { + ...sharedPropOptions, + variant: ['default'], +}; + +const outlinePropOptions = { + ...sharedPropOptions, + variant: ['outline'], +}; -export const Default = createStory(Template, defaultArgs)(); +export const DefaultPropVariations = createVariantStory(Template, defaultPropOptions); +export const OutlinePropVariations = createVariantStory(Template, outlinePropOptions); diff --git a/packages/components/pie-thumbnail/src/defs.ts b/packages/components/pie-thumbnail/src/defs.ts index d3f4b4bd27..5507825649 100644 --- a/packages/components/pie-thumbnail/src/defs.ts +++ b/packages/components/pie-thumbnail/src/defs.ts @@ -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; + +export const defaultProps: DefaultProps = { + variant: 'default', + src: '', + alt: '', +}; diff --git a/packages/components/pie-thumbnail/src/index.ts b/packages/components/pie-thumbnail/src/index.ts index 30918c4c60..0194fc5069 100644 --- a/packages/components/pie-thumbnail/src/index.ts +++ b/packages/components/pie-thumbnail/src/index.ts @@ -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'; @@ -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`

Hello world!

`; + const { + variant, + src, + alt, + } = this; + + const wrapperClasses = { + 'c-thumbnail': true, + [`c-thumbnail--${variant}`]: true, + }; + + return html` +
+ ${alt} +
+ `; } // Renders a `CSSResult` generated from SCSS by Vite diff --git a/packages/components/pie-thumbnail/src/thumbnail.scss b/packages/components/pie-thumbnail/src/thumbnail.scss index 6ffaedad64..5447e51f48 100644 --- a/packages/components/pie-thumbnail/src/thumbnail.scss +++ b/packages/components/pie-thumbnail/src/thumbnail.scss @@ -1 +1,25 @@ -@use '@justeattakeaway/pie-css/scss' as p; +.c-thumbnail { + --thumbnail-size: var(--dt-spacing-g); + --thumbnail-border-radius: var(--dt-radius-rounded-b); + --thumbnail-bg-color: var(--dt-color-container-default); + --thumbnail-border-color: transparent; + + box-sizing: border-box; + overflow: hidden; + width: var(--thumbnail-size); + height: var(--thumbnail-size); + border-radius: var(--thumbnail-border-radius); + border: 1px solid var(--thumbnail-border-color); + background-color: var(--thumbnail-bg-color); + + &.c-thumbnail--outline { + --thumbnail-border-color: var(--dt-color-border-default); + } + + .c-thumbnail-img { + width: 100%; + height: 100%; + object-fit: contain; + display: block; + } +} diff --git a/packages/components/pie-thumbnail/test/visual/pie-thumbnail.spec.ts b/packages/components/pie-thumbnail/test/visual/pie-thumbnail.spec.ts index eed897d37a..ef7934335b 100644 --- a/packages/components/pie-thumbnail/test/visual/pie-thumbnail.spec.ts +++ b/packages/components/pie-thumbnail/test/visual/pie-thumbnail.spec.ts @@ -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); +}));