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-2582 add size prop #2180

Merged
merged 17 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/slow-items-perform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@justeattakeaway/pie-thumbnail": minor
"pie-storybook": minor
---

[Added] - the size prop
27 changes: 21 additions & 6 deletions apps/pie-storybook/stories/pie-thumbnail.stories.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { html } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import { type Meta } from '@storybook/web-components';

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

import { createStory, type TemplateFunction } from '../utilities';
Expand Down Expand Up @@ -32,6 +37,14 @@ const thumbnailStoryMeta: ThumbnailStoryMeta = {
summary: defaultProps.variant,
},
},
size: {
description: 'Set the size of the thumbnail.',
control: 'select',
options: sizes,
defaultValue: {
summary: defaultArgs.size,
},
},
src: {
description: 'Set the src attribute for the underlying image tag.',
control: 'text',
Expand Down Expand Up @@ -69,7 +82,7 @@ const thumbnailStoryMeta: ThumbnailStoryMeta = {
},
},
placeholder: {
description: 'If an image is unavailable, the placeholder prop can be used to ensure there is always something visible to users.',
description: 'If an image fails to load, the placeholder prop can be used to ensure there is always something visible to users.',
control: 'object',
defaultValue: {
summary: defaultProps.placeholder,
Expand All @@ -89,6 +102,7 @@ export default thumbnailStoryMeta;

const Template: TemplateFunction<ThumbnailProps> = ({
variant,
size,
src,
alt,
disabled,
Expand All @@ -97,12 +111,13 @@ const Template: TemplateFunction<ThumbnailProps> = ({
placeholder,
}) => html`
<pie-thumbnail
variant="${variant}"
src="${src}"
alt="${alt}"
variant="${ifDefined(variant)}"
size="${ifDefined(size)}"
src="${ifDefined(src)}"
alt="${ifDefined(alt)}"
backgroundColor="${ifDefined(backgroundColor)}"
?disabled="${disabled}"
?hasPadding="${hasPadding}"
backgroundColor="${backgroundColor}"
.placeholder="${placeholder}"
</pie-thumbnail>`;

Expand Down
40 changes: 28 additions & 12 deletions apps/pie-storybook/stories/testing/pie-thumbnail.test.stories.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { html } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';

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

import { type Meta } from '@storybook/web-components';
Expand Down Expand Up @@ -32,6 +37,14 @@ const thumbnailStoryMeta: ThumbnailStoryMeta = {
summary: defaultProps.variant,
},
},
size: {
description: 'Set the size of the thumbnail.',
control: 'select',
options: sizes,
defaultValue: {
summary: defaultArgs.size,
},
},
src: {
description: 'Set the src attribute for the underlying image tag.',
control: 'text',
Expand Down Expand Up @@ -69,7 +82,7 @@ const thumbnailStoryMeta: ThumbnailStoryMeta = {
},
},
placeholder: {
description: 'If an image is unavailable, the placeholder prop can be used to ensure there is always something visible to users.',
description: 'If an image fails to load, the placeholder prop can be used to ensure there is always something visible to users.',
control: 'object',
defaultValue: {
summary: defaultProps.placeholder,
Expand All @@ -83,6 +96,7 @@ export default thumbnailStoryMeta;

const Template: TemplateFunction<ThumbnailProps> = ({
variant,
size,
src,
alt,
disabled,
Expand All @@ -91,38 +105,40 @@ const Template: TemplateFunction<ThumbnailProps> = ({
placeholder,
}) => html`
<pie-thumbnail
variant="${variant}"
src="${src}"
alt="${alt}"
variant="${ifDefined(variant)}"
size="${ifDefined(size)}"
src="${ifDefined(src)}"
alt="${ifDefined(alt)}"
backgroundColor="${ifDefined(backgroundColor)}"
?disabled="${disabled}"
?hasPadding="${hasPadding}"
backgroundColor="${backgroundColor}"
.placeholder="${placeholder}">
</pie-thumbnail>`;

// Define the prop options for the matrix
const sharedPropOptions: Partial<Record<keyof ThumbnailProps, unknown[]>> = {
const sharedPropOptions = {
src: [defaultArgs.src],
alt: [defaultArgs.alt],
size: sizes,
disabled: [true, false],
hasPadding: [true, false],
backgroundColor: [defaultArgs.backgroundColor],
placeholder: [defaultArgs.placeholder],
};

const defaultPropOptions: Partial<Record<keyof ThumbnailProps, unknown[]>> = {
const defaultPropOptions = {
...sharedPropOptions,
variant: ['default'],
};

const outlinePropOptions: Partial<Record<keyof ThumbnailProps, unknown[]>> = {
const outlinePropOptions = {
...sharedPropOptions,
variant: ['outline'],
};

const backgroundPropOptions: Partial<Record<keyof ThumbnailProps, unknown[]>> = {
backgroundColor: backgroundColors,
variant: variants,
const backgroundPropOptions = {
backgroundColor: [...backgroundColors],
variant: [...variants],
src: ['https://www.pie.design/assets/img/404_narrow.png'],
};

Expand Down
37 changes: 36 additions & 1 deletion packages/components/pie-thumbnail/src/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,60 @@ export const backgroundColorClassNames: Record<typeof backgroundColors[number],
'inverse-alternative': 'c-thumbnail--backgroundInverseAlternative',
};

const SIZE_INCREMENT_BY = 8;
const SIZE_MIN = 24;
const SIZE_MAX = 128;

export const sizes = Object.freeze(Array.from(
raoufswe marked this conversation as resolved.
Show resolved Hide resolved
{ length: (SIZE_MAX - SIZE_MIN) / SIZE_INCREMENT_BY + 1 },
(_, i) => SIZE_MIN + i * SIZE_INCREMENT_BY,
)) as readonly number[];

type PlaceholderProps = {
src?: string;
alt?: string;
}

export interface ThumbnailProps {
/**
* What style variant the thumbnail should be such as default or outline.
*/
variant?: typeof variants[number];
/**
* Specify the size as a number between 24 and 128 (inclusive) and a multiple of 8.
*/
size?: typeof sizes[number];
/**
* The src attribute for the underlying image tag.
*/
src?: string;
/**
* The alt attribute for the underlying image tag.
*/
alt?: string;
/**
* When true, the disabled styles are applied.
*/
disabled?: boolean;
/**
* When true, an extra spacing around the thumbnail container is applied.
*/
hasPadding?: boolean;
/**
* What background color the thumbnail should be.
*/
backgroundColor?: typeof backgroundColors[number];
/**
* What placeholder should be used when the image fails to load.
*/
placeholder?: PlaceholderProps;
}

export type DefaultProps = ComponentDefaultProps<ThumbnailProps, 'variant' | 'src' | 'alt' | 'disabled' | 'hasPadding' | 'backgroundColor' | 'placeholder'>;
export type DefaultProps = ComponentDefaultProps<ThumbnailProps>;

export const defaultProps: DefaultProps = {
variant: 'default',
size: 48,
src: '',
alt: '',
disabled: false,
Expand Down
29 changes: 26 additions & 3 deletions packages/components/pie-thumbnail/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
variants,
backgroundColors,
backgroundColorClassNames,
sizes,
} from './defs';
import styles from './thumbnail.scss?inline';

Expand All @@ -28,6 +29,10 @@ export class PieThumbnail extends LitElement implements ThumbnailProps {
@validPropertyValues(componentSelector, variants, defaultProps.variant)
public variant = defaultProps.variant;

@property({ type: Number })
@validPropertyValues(componentSelector, sizes, defaultProps.size)
public size = defaultProps.size;

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

Expand All @@ -50,6 +55,21 @@ export class PieThumbnail extends LitElement implements ThumbnailProps {
@query('img')
private img!: HTMLImageElement;

private _generateSizeStyles (): string {
const { size } = this;
let borderRadius = '--dt-radius-rounded-c';
if (size <= 40) {
borderRadius = '--dt-radius-rounded-a';
} else if (size <= 56) {
borderRadius = '--dt-radius-rounded-b';
}

return `
--thumbnail-size: ${size}px;
--thumbnail-border-radius: var(${borderRadius});
`;
}

/**
* Handles image load errors by replacing the src and alt props
* with the placeholder props.
Expand Down Expand Up @@ -83,7 +103,6 @@ export class PieThumbnail extends LitElement implements ThumbnailProps {
disabled,
hasPadding,
backgroundColor,
_handleImageError,
} = this;

const wrapperClasses = {
Expand All @@ -94,14 +113,18 @@ export class PieThumbnail extends LitElement implements ThumbnailProps {
'c-thumbnail--padding': hasPadding,
};

const sizeStyles = this._generateSizeStyles();

return html`
<div data-test-id="pie-thumbnail" class="${classMap(wrapperClasses)}">
<div data-test-id="pie-thumbnail"
class="${classMap(wrapperClasses)}"
style="${sizeStyles}">
<img
data-test-id="pie-thumbnail-img"
src="${src}"
class="c-thumbnail-img"
alt="${alt}"
@error="${_handleImageError}"
@error="${this._handleImageError}"
/>
</div>
`;
Expand Down
9 changes: 5 additions & 4 deletions packages/components/pie-thumbnail/src/thumbnail.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
.c-thumbnail {
--thumbnail-size: var(--dt-spacing-g);
--thumbnail-size: 48px;
--thumbnail-border-radius: var(--dt-radius-rounded-b);
--thumbnail-bg-color: var(--dt-color-container-default);
--thumbnail-border-color: transparent;
--thumbnail-padding: calc(var(--dt-spacing-a) / 2);

display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
overflow: hidden;
width: var(--thumbnail-size);
Expand Down Expand Up @@ -47,8 +50,6 @@

.c-thumbnail-img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
height: auto;
}
}
Loading