@justeattakeaway/pie-thumbnail 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +84 -4
- package/declaration.d.ts +5 -0
- package/dist/index.d.ts +32 -4
- package/dist/index.js +96 -55
- package/dist/react.d.ts +32 -4
- package/dist/react.js +8 -7
- package/package.json +1 -3
- package/src/default-placeholder.svg +1 -0
- package/src/defs.ts +13 -1
- package/src/index.ts +61 -11
- package/src/thumbnail.scss +22 -4
package/custom-elements.json
CHANGED
|
@@ -36,6 +36,14 @@
|
|
|
36
36
|
},
|
|
37
37
|
"default": "{\n default: 'c-thumbnail--backgroundDefault',\n subtle: 'c-thumbnail--backgroundSubtle',\n strong: 'c-thumbnail--backgroundStrong',\n dark: 'c-thumbnail--backgroundDark',\n inverse: 'c-thumbnail--backgroundInverse',\n 'inverse-alternative': 'c-thumbnail--backgroundInverseAlternative',\n}"
|
|
38
38
|
},
|
|
39
|
+
{
|
|
40
|
+
"kind": "variable",
|
|
41
|
+
"name": "aspectRatios",
|
|
42
|
+
"type": {
|
|
43
|
+
"text": "['1by1', '4by3', '16by9']"
|
|
44
|
+
},
|
|
45
|
+
"default": "['1by1', '4by3', '16by9']"
|
|
46
|
+
},
|
|
39
47
|
{
|
|
40
48
|
"kind": "variable",
|
|
41
49
|
"name": "sizes",
|
|
@@ -47,7 +55,7 @@
|
|
|
47
55
|
"type": {
|
|
48
56
|
"text": "DefaultProps"
|
|
49
57
|
},
|
|
50
|
-
"default": "{\n variant: 'default',\n size: 48,\n src: '',\n alt: '',\n disabled: false,\n hasPadding: false,\n backgroundColor: 'default',\n placeholder: {\n src: '',\n alt: '',\n },\n}"
|
|
58
|
+
"default": "{\n variant: 'default',\n size: 48,\n src: '',\n alt: '',\n disabled: false,\n hasPadding: false,\n hideDefaultPlaceholder: false,\n backgroundColor: 'default',\n aspectRatio: '1by1',\n placeholder: {\n src: '',\n alt: '',\n },\n}"
|
|
51
59
|
}
|
|
52
60
|
],
|
|
53
61
|
"exports": [
|
|
@@ -75,6 +83,14 @@
|
|
|
75
83
|
"module": "src/defs.js"
|
|
76
84
|
}
|
|
77
85
|
},
|
|
86
|
+
{
|
|
87
|
+
"kind": "js",
|
|
88
|
+
"name": "aspectRatios",
|
|
89
|
+
"declaration": {
|
|
90
|
+
"name": "aspectRatios",
|
|
91
|
+
"module": "src/defs.js"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
78
94
|
{
|
|
79
95
|
"kind": "js",
|
|
80
96
|
"name": "sizes",
|
|
@@ -114,6 +130,12 @@
|
|
|
114
130
|
"privacy": "public",
|
|
115
131
|
"attribute": "size"
|
|
116
132
|
},
|
|
133
|
+
{
|
|
134
|
+
"kind": "field",
|
|
135
|
+
"name": "aspectRatio",
|
|
136
|
+
"privacy": "public",
|
|
137
|
+
"attribute": "aspectRatio"
|
|
138
|
+
},
|
|
117
139
|
{
|
|
118
140
|
"kind": "field",
|
|
119
141
|
"name": "src",
|
|
@@ -138,6 +160,12 @@
|
|
|
138
160
|
"privacy": "public",
|
|
139
161
|
"attribute": "hasPadding"
|
|
140
162
|
},
|
|
163
|
+
{
|
|
164
|
+
"kind": "field",
|
|
165
|
+
"name": "hideDefaultPlaceholder",
|
|
166
|
+
"privacy": "public",
|
|
167
|
+
"attribute": "hideDefaultPlaceholder"
|
|
168
|
+
},
|
|
141
169
|
{
|
|
142
170
|
"kind": "field",
|
|
143
171
|
"name": "backgroundColor",
|
|
@@ -161,6 +189,44 @@
|
|
|
161
189
|
},
|
|
162
190
|
"privacy": "private"
|
|
163
191
|
},
|
|
192
|
+
{
|
|
193
|
+
"kind": "field",
|
|
194
|
+
"name": "_hasError",
|
|
195
|
+
"type": {
|
|
196
|
+
"text": "boolean"
|
|
197
|
+
},
|
|
198
|
+
"privacy": "private",
|
|
199
|
+
"default": "false"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"kind": "field",
|
|
203
|
+
"name": "_isDefaultPlaceholderVisible",
|
|
204
|
+
"type": {
|
|
205
|
+
"text": "boolean"
|
|
206
|
+
},
|
|
207
|
+
"privacy": "private",
|
|
208
|
+
"description": "Determines if the default placeholder should be displayed.",
|
|
209
|
+
"readonly": true
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"kind": "field",
|
|
213
|
+
"name": "_controlledSrc",
|
|
214
|
+
"type": {
|
|
215
|
+
"text": "string"
|
|
216
|
+
},
|
|
217
|
+
"privacy": "private",
|
|
218
|
+
"description": "Returns the appropriate image props based on the following order:\n1. If there is no error, return the provided image props.\n2. If there is an error and a custom placeholder is provided, return the placeholder props.\n3. If there is an error and no custom placeholder is provided, return the component default placeholder.\n4. Otherwise, fall back to the provided src (resulting in a broken image).",
|
|
219
|
+
"readonly": true
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"kind": "field",
|
|
223
|
+
"name": "_controlledAlt",
|
|
224
|
+
"type": {
|
|
225
|
+
"text": "string"
|
|
226
|
+
},
|
|
227
|
+
"privacy": "private",
|
|
228
|
+
"readonly": true
|
|
229
|
+
},
|
|
164
230
|
{
|
|
165
231
|
"kind": "method",
|
|
166
232
|
"name": "_generateSizeStyles",
|
|
@@ -169,19 +235,25 @@
|
|
|
169
235
|
"type": {
|
|
170
236
|
"text": "string"
|
|
171
237
|
}
|
|
172
|
-
}
|
|
238
|
+
},
|
|
239
|
+
"description": "Assigns CSS variables based on the size prop."
|
|
173
240
|
},
|
|
174
241
|
{
|
|
175
242
|
"kind": "method",
|
|
176
243
|
"name": "_handleImageError",
|
|
177
244
|
"privacy": "private",
|
|
178
|
-
"
|
|
245
|
+
"return": {
|
|
246
|
+
"type": {
|
|
247
|
+
"text": "void"
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
"description": "Handles the image error event."
|
|
179
251
|
},
|
|
180
252
|
{
|
|
181
253
|
"kind": "method",
|
|
182
254
|
"name": "_checkImageError",
|
|
183
255
|
"privacy": "private",
|
|
184
|
-
"description": "
|
|
256
|
+
"description": "Checks the image load status and triggers error handling if needed.\nThis is needed as the `onerror` event is not triggered in SSR."
|
|
185
257
|
}
|
|
186
258
|
],
|
|
187
259
|
"attributes": [
|
|
@@ -193,6 +265,10 @@
|
|
|
193
265
|
"name": "size",
|
|
194
266
|
"fieldName": "size"
|
|
195
267
|
},
|
|
268
|
+
{
|
|
269
|
+
"name": "aspectRatio",
|
|
270
|
+
"fieldName": "aspectRatio"
|
|
271
|
+
},
|
|
196
272
|
{
|
|
197
273
|
"name": "src",
|
|
198
274
|
"fieldName": "src"
|
|
@@ -209,6 +285,10 @@
|
|
|
209
285
|
"name": "hasPadding",
|
|
210
286
|
"fieldName": "hasPadding"
|
|
211
287
|
},
|
|
288
|
+
{
|
|
289
|
+
"name": "hideDefaultPlaceholder",
|
|
290
|
+
"fieldName": "hideDefaultPlaceholder"
|
|
291
|
+
},
|
|
212
292
|
{
|
|
213
293
|
"name": "backgroundColor",
|
|
214
294
|
"fieldName": "backgroundColor"
|
package/declaration.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import type { CSSResult } from 'lit';
|
|
|
3
3
|
import type { LitElement } from 'lit';
|
|
4
4
|
import type { TemplateResult } from 'lit-html';
|
|
5
5
|
|
|
6
|
+
export declare const aspectRatios: readonly ["1by1", "4by3", "16by9"];
|
|
7
|
+
|
|
6
8
|
export declare const backgroundColorClassNames: Record<typeof backgroundColors[number], string>;
|
|
7
9
|
|
|
8
10
|
export declare const backgroundColors: readonly ["default", "subtle", "strong", "dark", "inverse", "inverse-alternative"];
|
|
@@ -17,21 +19,39 @@ export declare const defaultProps: DefaultProps;
|
|
|
17
19
|
export declare class PieThumbnail extends LitElement implements ThumbnailProps {
|
|
18
20
|
variant: "default" | "outline";
|
|
19
21
|
size: number;
|
|
22
|
+
aspectRatio: "1by1" | "4by3" | "16by9";
|
|
20
23
|
src: string;
|
|
21
24
|
alt: string;
|
|
22
25
|
disabled: boolean;
|
|
23
26
|
hasPadding: boolean;
|
|
27
|
+
hideDefaultPlaceholder: boolean;
|
|
24
28
|
backgroundColor: "default" | "subtle" | "strong" | "dark" | "inverse" | "inverse-alternative";
|
|
25
29
|
placeholder: ThumbnailProps['placeholder'];
|
|
26
30
|
private img;
|
|
31
|
+
private _hasError;
|
|
32
|
+
/**
|
|
33
|
+
* Determines if the default placeholder should be displayed.
|
|
34
|
+
*/
|
|
35
|
+
private get _isDefaultPlaceholderVisible();
|
|
36
|
+
/**
|
|
37
|
+
* Returns the appropriate image props based on the following order:
|
|
38
|
+
* 1. If there is no error, return the provided image props.
|
|
39
|
+
* 2. If there is an error and a custom placeholder is provided, return the placeholder props.
|
|
40
|
+
* 3. If there is an error and no custom placeholder is provided, return the component default placeholder.
|
|
41
|
+
* 4. Otherwise, fall back to the provided src (resulting in a broken image).
|
|
42
|
+
*/
|
|
43
|
+
private get _controlledSrc();
|
|
44
|
+
private get _controlledAlt();
|
|
45
|
+
/**
|
|
46
|
+
* Assigns CSS variables based on the size prop.
|
|
47
|
+
*/
|
|
27
48
|
private _generateSizeStyles;
|
|
28
49
|
/**
|
|
29
|
-
* Handles
|
|
30
|
-
* with the placeholder props.
|
|
50
|
+
* Handles the image error event.
|
|
31
51
|
*/
|
|
32
52
|
private _handleImageError;
|
|
33
53
|
/**
|
|
34
|
-
*
|
|
54
|
+
* Checks the image load status and triggers error handling if needed.
|
|
35
55
|
* This is needed as the `onerror` event is not triggered in SSR.
|
|
36
56
|
*/
|
|
37
57
|
private _checkImageError;
|
|
@@ -77,9 +97,17 @@ export declare interface ThumbnailProps {
|
|
|
77
97
|
*/
|
|
78
98
|
backgroundColor?: typeof backgroundColors[number];
|
|
79
99
|
/**
|
|
80
|
-
*
|
|
100
|
+
* When true, hides the component default placeholder on image load failure.
|
|
101
|
+
*/
|
|
102
|
+
hideDefaultPlaceholder?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Overrides the component default placeholder with a custom one on image load failure.
|
|
81
105
|
*/
|
|
82
106
|
placeholder?: PlaceholderProps;
|
|
107
|
+
/**
|
|
108
|
+
* Sets the aspect-ratio of the thumbnail image.
|
|
109
|
+
*/
|
|
110
|
+
aspectRatio?: typeof aspectRatios[number];
|
|
83
111
|
}
|
|
84
112
|
|
|
85
113
|
export declare const variants: readonly ["default", "outline"];
|
package/dist/index.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { LitElement as
|
|
2
|
-
import { validPropertyValues as
|
|
3
|
-
import { classMap as
|
|
4
|
-
import { property as
|
|
5
|
-
const
|
|
1
|
+
import { LitElement as k, html as _, unsafeCSS as E } from "lit";
|
|
2
|
+
import { validPropertyValues as h, defineCustomElement as S } from "@justeattakeaway/pie-webc-core";
|
|
3
|
+
import { classMap as P } from "lit/directives/class-map.js";
|
|
4
|
+
import { property as l, query as z, state as C } from "lit/decorators.js";
|
|
5
|
+
const I = [
|
|
6
6
|
"default",
|
|
7
7
|
"outline"
|
|
8
|
-
],
|
|
8
|
+
], D = [
|
|
9
9
|
"default",
|
|
10
10
|
"subtle",
|
|
11
11
|
"strong",
|
|
12
12
|
"dark",
|
|
13
13
|
"inverse",
|
|
14
14
|
"inverse-alternative"
|
|
15
|
-
],
|
|
15
|
+
], x = {
|
|
16
16
|
default: "c-thumbnail--backgroundDefault",
|
|
17
17
|
subtle: "c-thumbnail--backgroundSubtle",
|
|
18
18
|
strong: "c-thumbnail--backgroundStrong",
|
|
19
19
|
dark: "c-thumbnail--backgroundDark",
|
|
20
20
|
inverse: "c-thumbnail--backgroundInverse",
|
|
21
21
|
"inverse-alternative": "c-thumbnail--backgroundInverseAlternative"
|
|
22
|
-
}, m = 8, g = 24,
|
|
23
|
-
{ length: (
|
|
24
|
-
(
|
|
22
|
+
}, $ = ["1by1", "4by3", "16by9"], m = 8, g = 24, w = 128, R = Object.freeze(Array.from(
|
|
23
|
+
{ length: (w - g) / m + 1 },
|
|
24
|
+
(u, t) => g + t * m
|
|
25
25
|
)), e = {
|
|
26
26
|
variant: "default",
|
|
27
27
|
size: 48,
|
|
@@ -29,39 +29,65 @@ const C = [
|
|
|
29
29
|
alt: "",
|
|
30
30
|
disabled: !1,
|
|
31
31
|
hasPadding: !1,
|
|
32
|
+
hideDefaultPlaceholder: !1,
|
|
32
33
|
backgroundColor: "default",
|
|
34
|
+
aspectRatio: "1by1",
|
|
33
35
|
placeholder: {
|
|
34
36
|
src: "",
|
|
35
37
|
alt: ""
|
|
36
38
|
}
|
|
37
|
-
},
|
|
38
|
-
var
|
|
39
|
-
for (var n = void 0,
|
|
40
|
-
(
|
|
41
|
-
return n &&
|
|
39
|
+
}, j = ".c-thumbnail{--thumbnail-size: 48px;--thumbnail-border-radius: var(--dt-radius-rounded-b);--thumbnail-bg-color: var(--dt-color-container-default);--thumbnail-padding: calc(var(--dt-spacing-a) / 2);--thumbnail-default-placeholder-padding: var(--dt-spacing-b);--thumbnail-img-border-radius: unset;--thumbnail-img-object-fit: cover;display:flex;justify-content:center;align-items:center;box-sizing:border-box;overflow:hidden;width:var(--thumbnail-size);height:var(--thumbnail-size);border-radius:var(--thumbnail-border-radius);background-color:var(--thumbnail-bg-color)}.c-thumbnail.c-thumbnail--outline{border:1px solid var(--dt-color-border-default)}.c-thumbnail.c-thumbnail--disabled{opacity:.5}.c-thumbnail.c-thumbnail--backgroundSubtle{--thumbnail-bg-color: var(--dt-color-container-subtle)}.c-thumbnail.c-thumbnail--backgroundStrong{--thumbnail-bg-color: var(--dt-color-container-strong)}.c-thumbnail.c-thumbnail--backgroundDark{--thumbnail-bg-color: var(--dt-color-container-dark)}.c-thumbnail.c-thumbnail--backgroundInverse{--thumbnail-bg-color: var(--dt-color-container-inverse)}.c-thumbnail.c-thumbnail--backgroundInverseAlternative{--thumbnail-bg-color: var(--dt-color-container-inverse-alternative)}.c-thumbnail.c-thumbnail--padding{--thumbnail-img-border-radius: calc(var(--thumbnail-border-radius) - var(--thumbnail-padding));padding:var(--thumbnail-padding)}.c-thumbnail.c-thumbnail--4by3{height:calc(var(--thumbnail-size) * 3 / 4)}.c-thumbnail.c-thumbnail--16by9{height:calc(var(--thumbnail-size) * 9 / 16)}.c-thumbnail .c-thumbnail-img{width:100%;height:100%;border-radius:var(--thumbnail-img-border-radius);object-fit:var(--thumbnail-img-object-fit)}.c-thumbnail.c-thumbnail--defaultPlaceholder{--thumbnail-bg-color: var(--dt-color-container-default);--thumbnail-img-object-fit: fill;padding:var(--thumbnail-default-placeholder-padding)}", A = "data:image/svg+xml,%3csvg%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2032%2032'%3e%3cpath%20d='M31.9%2015.493c-.103-.254-1.496-2.753-4.081-5.887a.507.507%200%200%201-.12-.267%2048.166%2048.166%200%200%200-.777-5.436.881.881%200%200%200-.282-.468.925.925%200%200%200-.51-.22l-2.678-.324a.595.595%200%200%200-.07%200%20.575.575%200%200%200-.402.161.543.543%200%200%200-.166.39v.905a.034.034%200%200%201-.01.024.036.036%200%200%201-.037.007A2.43%202.43%200%200%200%2015.992%200c-.472%200-.935.138-1.327.395C5.387%205.956.282%2015.005.085%2015.493a.87.87%200%200%200%20.25%201.064.929.929%200%200%200%20.355.175l2.672.5a.917.917%200%200%201%20.454.28.872.872%200%200%201%20.213.479c.023.457.528%2010.69%201.163%2013.344a.89.89%200%200%200%20.327.48c.161.12.358.185.561.185h.02c1.56-.038%202.986-.063%204.528-.084h.13a.303.303%200%200%200%20.21-.086.288.288%200%200%200%20.087-.206c-.062-.893-.197-2.936-.306-5.093%200-.054-.007-.121-.01-.176a.558.558%200%200%200-.272-.442%202.847%202.847%200%200%201-.992-.96%202.745%202.745%200%200%201-.41-1.3c-.142-3.59-.211-7.736-.008-10.982a.515.515%200%200%201%20.165-.365.547.547%200%200%201%20.76.015c.098.1.152.234.149.373v.04c-.132%202.163-.142%204.721-.095%207.244a.61.61%200%200%200%20.195.435.648.648%200%200%200%20.902-.015.61.61%200%200%200%20.179-.442c-.049-2.54-.036-5.114.099-7.285a.515.515%200%200%201%20.165-.365.547.547%200%200%201%20.76.015c.098.1.152.234.15.373v.04c-.133%202.152-.143%204.695-.097%207.204a.608.608%200%200%200%20.194.436.648.648%200%200%200%20.902-.014.61.61%200%200%200%20.18-.44c-.047-2.53-.035-5.094.1-7.25a.515.515%200%200%201%20.165-.366.546.546%200%200%201%20.76.016c.099.1.152.234.15.372v.041c-.194%203.154-.131%207.148%200%2010.651a.26.26%200%200%201%200%20.033v.087c0%20.454-.114.902-.332%201.304a2.827%202.827%200%200%201-.919%201.004.54.54%200%200%200-.237.406s-.066.539.179%203.145c.113%201.138.201%201.927.241%202.283a.273.273%200%200%200%20.095.172c.052.044.12.068.188.068h4.054l1.516.012c.07%200%20.137-.024.19-.069a.273.273%200%200%200%20.094-.173c.35-3.124.434-4.879.434-4.879a.307.307%200%200%200-.084-.201.323.323%200%200%200-.2-.099l-1.842-.246a.636.636%200%200%201-.331-.143.606.606%200%200%201-.195-.296.832.832%200%200%201-.024-.276c.747-10.41%204.281-13.92%204.281-13.92a1.05%201.05%200%200%201%20.172-.144.576.576%200%200%201%20.859.245.968.968%200%200%201%20.045.25c.306%203.273.157%208.842-.032%2013.187a316.08%20316.08%200%200%201-.353%206.582c0%20.057.023.112.064.152.042.04.098.063.157.063%201.002.017%201.984.036%203.037.062h.021c.203%200%20.4-.065.561-.185a.893.893%200%200%200%20.328-.48c.635-2.654%201.134-12.887%201.16-13.344a.877.877%200%200%201%20.215-.479.92.92%200%200%201%20.453-.28l2.672-.5a.92.92%200%200%200%20.5-.316.875.875%200%200%200%20.193-.548.883.883%200%200%200-.1-.368Z'%20fill='%23EFEDEA'/%3e%3c/svg%3e";
|
|
40
|
+
var B = Object.defineProperty, i = (u, t, r, o) => {
|
|
41
|
+
for (var n = void 0, c = u.length - 1, d; c >= 0; c--)
|
|
42
|
+
(d = u[c]) && (n = d(t, r, n) || n);
|
|
43
|
+
return n && B(t, r, n), n;
|
|
42
44
|
};
|
|
43
|
-
const
|
|
45
|
+
const s = "pie-thumbnail", b = class b extends k {
|
|
44
46
|
constructor() {
|
|
45
|
-
super(...arguments), this.variant = e.variant, this.size = e.size, this.src = e.src, this.alt = e.alt, this.disabled = e.disabled, this.hasPadding = e.hasPadding, this.backgroundColor = e.backgroundColor, this.placeholder = e.placeholder;
|
|
47
|
+
super(...arguments), this.variant = e.variant, this.size = e.size, this.aspectRatio = e.aspectRatio, this.src = e.src, this.alt = e.alt, this.disabled = e.disabled, this.hasPadding = e.hasPadding, this.hideDefaultPlaceholder = e.hideDefaultPlaceholder, this.backgroundColor = e.backgroundColor, this.placeholder = e.placeholder, this._hasError = !1;
|
|
46
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Determines if the default placeholder should be displayed.
|
|
51
|
+
*/
|
|
52
|
+
get _isDefaultPlaceholderVisible() {
|
|
53
|
+
const { _hasError: t, placeholder: r, hideDefaultPlaceholder: o } = this;
|
|
54
|
+
return t && !(r != null && r.src) && !o;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Returns the appropriate image props based on the following order:
|
|
58
|
+
* 1. If there is no error, return the provided image props.
|
|
59
|
+
* 2. If there is an error and a custom placeholder is provided, return the placeholder props.
|
|
60
|
+
* 3. If there is an error and no custom placeholder is provided, return the component default placeholder.
|
|
61
|
+
* 4. Otherwise, fall back to the provided src (resulting in a broken image).
|
|
62
|
+
*/
|
|
63
|
+
get _controlledSrc() {
|
|
64
|
+
var t;
|
|
65
|
+
return this._hasError ? (t = this.placeholder) != null && t.src ? this.placeholder.src : this.hideDefaultPlaceholder ? this.src : A : this.src;
|
|
66
|
+
}
|
|
67
|
+
get _controlledAlt() {
|
|
68
|
+
var t;
|
|
69
|
+
return this._hasError ? (t = this.placeholder) != null && t.src ? this.placeholder.alt ?? "" : this.hideDefaultPlaceholder ? this.alt : "" : this.alt;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Assigns CSS variables based on the size prop.
|
|
73
|
+
*/
|
|
47
74
|
_generateSizeStyles() {
|
|
48
75
|
const { size: t } = this;
|
|
49
|
-
let r = "--dt-radius-rounded-c";
|
|
50
|
-
return t <= 40 ? r = "--dt-radius-rounded-a" : t <= 56 && (r = "--dt-radius-rounded-b"), `
|
|
76
|
+
let r = "--dt-radius-rounded-c", o = "--dt-spacing-d";
|
|
77
|
+
return t <= 40 ? (r = "--dt-radius-rounded-a", o = "--dt-spacing-a") : t <= 56 && (r = "--dt-radius-rounded-b", o = "--dt-spacing-b"), `
|
|
51
78
|
--thumbnail-size: ${t}px;
|
|
52
79
|
--thumbnail-border-radius: var(${r});
|
|
80
|
+
--thumbnail-default-placeholder-padding: var(${o});
|
|
53
81
|
`;
|
|
54
82
|
}
|
|
55
83
|
/**
|
|
56
|
-
* Handles
|
|
57
|
-
* with the placeholder props.
|
|
84
|
+
* Handles the image error event.
|
|
58
85
|
*/
|
|
59
86
|
_handleImageError() {
|
|
60
|
-
|
|
61
|
-
(t = this.placeholder) != null && t.src && this.setAttribute("src", this.placeholder.src), (r = this.placeholder) != null && r.alt && this.setAttribute("alt", this.placeholder.alt);
|
|
87
|
+
this._hasError = !0;
|
|
62
88
|
}
|
|
63
89
|
/**
|
|
64
|
-
*
|
|
90
|
+
* Checks the image load status and triggers error handling if needed.
|
|
65
91
|
* This is needed as the `onerror` event is not triggered in SSR.
|
|
66
92
|
*/
|
|
67
93
|
_checkImageError() {
|
|
@@ -76,71 +102,86 @@ const d = "pie-thumbnail", h = class h extends f {
|
|
|
76
102
|
render() {
|
|
77
103
|
const {
|
|
78
104
|
variant: t,
|
|
79
|
-
|
|
80
|
-
|
|
105
|
+
_controlledSrc: r,
|
|
106
|
+
_controlledAlt: o,
|
|
81
107
|
disabled: n,
|
|
82
|
-
hasPadding:
|
|
83
|
-
|
|
84
|
-
|
|
108
|
+
hasPadding: c,
|
|
109
|
+
_isDefaultPlaceholderVisible: d,
|
|
110
|
+
backgroundColor: p,
|
|
111
|
+
aspectRatio: v
|
|
112
|
+
} = this, f = {
|
|
85
113
|
"c-thumbnail": !0,
|
|
86
114
|
[`c-thumbnail--${t}`]: !0,
|
|
87
|
-
[
|
|
115
|
+
[`c-thumbnail--${v}`]: !0,
|
|
116
|
+
[x[p]]: !0,
|
|
88
117
|
"c-thumbnail--disabled": n,
|
|
89
|
-
"c-thumbnail--padding":
|
|
90
|
-
|
|
91
|
-
|
|
118
|
+
"c-thumbnail--padding": c,
|
|
119
|
+
"c-thumbnail--defaultPlaceholder": d
|
|
120
|
+
}, y = this._generateSizeStyles();
|
|
121
|
+
return _`
|
|
92
122
|
<div data-test-id="pie-thumbnail"
|
|
93
|
-
class="${
|
|
94
|
-
style="${
|
|
123
|
+
class="${P(f)}"
|
|
124
|
+
style="${y}">
|
|
95
125
|
<img
|
|
96
126
|
data-test-id="pie-thumbnail-img"
|
|
97
127
|
src="${r}"
|
|
128
|
+
alt="${o}"
|
|
98
129
|
class="c-thumbnail-img"
|
|
99
|
-
alt="${u}"
|
|
100
130
|
@error="${this._handleImageError}"
|
|
101
131
|
/>
|
|
102
132
|
</div>
|
|
103
133
|
`;
|
|
104
134
|
}
|
|
105
135
|
};
|
|
106
|
-
|
|
107
|
-
let a =
|
|
136
|
+
b.styles = E(j);
|
|
137
|
+
let a = b;
|
|
108
138
|
i([
|
|
109
|
-
|
|
110
|
-
|
|
139
|
+
l({ type: String }),
|
|
140
|
+
h(s, I, e.variant)
|
|
111
141
|
], a.prototype, "variant");
|
|
112
142
|
i([
|
|
113
|
-
|
|
114
|
-
|
|
143
|
+
l({ type: Number }),
|
|
144
|
+
h(s, R, e.size)
|
|
115
145
|
], a.prototype, "size");
|
|
116
146
|
i([
|
|
117
|
-
|
|
147
|
+
l({ type: String }),
|
|
148
|
+
h(s, $, e.aspectRatio)
|
|
149
|
+
], a.prototype, "aspectRatio");
|
|
150
|
+
i([
|
|
151
|
+
l({ type: String })
|
|
118
152
|
], a.prototype, "src");
|
|
119
153
|
i([
|
|
120
|
-
|
|
154
|
+
l({ type: String })
|
|
121
155
|
], a.prototype, "alt");
|
|
122
156
|
i([
|
|
123
|
-
|
|
157
|
+
l({ type: Boolean })
|
|
124
158
|
], a.prototype, "disabled");
|
|
125
159
|
i([
|
|
126
|
-
|
|
160
|
+
l({ type: Boolean })
|
|
127
161
|
], a.prototype, "hasPadding");
|
|
128
162
|
i([
|
|
129
|
-
|
|
130
|
-
|
|
163
|
+
l({ type: Boolean })
|
|
164
|
+
], a.prototype, "hideDefaultPlaceholder");
|
|
165
|
+
i([
|
|
166
|
+
l({ type: String }),
|
|
167
|
+
h(s, D, e.backgroundColor)
|
|
131
168
|
], a.prototype, "backgroundColor");
|
|
132
169
|
i([
|
|
133
|
-
|
|
170
|
+
l({ type: Object })
|
|
134
171
|
], a.prototype, "placeholder");
|
|
135
172
|
i([
|
|
136
|
-
|
|
173
|
+
z("img")
|
|
137
174
|
], a.prototype, "img");
|
|
138
|
-
|
|
175
|
+
i([
|
|
176
|
+
C()
|
|
177
|
+
], a.prototype, "_hasError");
|
|
178
|
+
S(s, a);
|
|
139
179
|
export {
|
|
140
180
|
a as PieThumbnail,
|
|
141
|
-
|
|
142
|
-
|
|
181
|
+
$ as aspectRatios,
|
|
182
|
+
x as backgroundColorClassNames,
|
|
183
|
+
D as backgroundColors,
|
|
143
184
|
e as defaultProps,
|
|
144
|
-
|
|
145
|
-
|
|
185
|
+
R as sizes,
|
|
186
|
+
I as variants
|
|
146
187
|
};
|
package/dist/react.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import type { LitElement } from 'lit';
|
|
|
4
4
|
import * as React_2 from 'react';
|
|
5
5
|
import type { TemplateResult } from 'lit-html';
|
|
6
6
|
|
|
7
|
+
export declare const aspectRatios: readonly ["1by1", "4by3", "16by9"];
|
|
8
|
+
|
|
7
9
|
export declare const backgroundColorClassNames: Record<typeof backgroundColors[number], string>;
|
|
8
10
|
|
|
9
11
|
export declare const backgroundColors: readonly ["default", "subtle", "strong", "dark", "inverse", "inverse-alternative"];
|
|
@@ -20,21 +22,39 @@ export declare const PieThumbnail: React_2.ForwardRefExoticComponent<ThumbnailPr
|
|
|
20
22
|
declare class PieThumbnail_2 extends LitElement implements ThumbnailProps {
|
|
21
23
|
variant: "default" | "outline";
|
|
22
24
|
size: number;
|
|
25
|
+
aspectRatio: "1by1" | "4by3" | "16by9";
|
|
23
26
|
src: string;
|
|
24
27
|
alt: string;
|
|
25
28
|
disabled: boolean;
|
|
26
29
|
hasPadding: boolean;
|
|
30
|
+
hideDefaultPlaceholder: boolean;
|
|
27
31
|
backgroundColor: "default" | "subtle" | "strong" | "dark" | "inverse" | "inverse-alternative";
|
|
28
32
|
placeholder: ThumbnailProps['placeholder'];
|
|
29
33
|
private img;
|
|
34
|
+
private _hasError;
|
|
35
|
+
/**
|
|
36
|
+
* Determines if the default placeholder should be displayed.
|
|
37
|
+
*/
|
|
38
|
+
private get _isDefaultPlaceholderVisible();
|
|
39
|
+
/**
|
|
40
|
+
* Returns the appropriate image props based on the following order:
|
|
41
|
+
* 1. If there is no error, return the provided image props.
|
|
42
|
+
* 2. If there is an error and a custom placeholder is provided, return the placeholder props.
|
|
43
|
+
* 3. If there is an error and no custom placeholder is provided, return the component default placeholder.
|
|
44
|
+
* 4. Otherwise, fall back to the provided src (resulting in a broken image).
|
|
45
|
+
*/
|
|
46
|
+
private get _controlledSrc();
|
|
47
|
+
private get _controlledAlt();
|
|
48
|
+
/**
|
|
49
|
+
* Assigns CSS variables based on the size prop.
|
|
50
|
+
*/
|
|
30
51
|
private _generateSizeStyles;
|
|
31
52
|
/**
|
|
32
|
-
* Handles
|
|
33
|
-
* with the placeholder props.
|
|
53
|
+
* Handles the image error event.
|
|
34
54
|
*/
|
|
35
55
|
private _handleImageError;
|
|
36
56
|
/**
|
|
37
|
-
*
|
|
57
|
+
* Checks the image load status and triggers error handling if needed.
|
|
38
58
|
* This is needed as the `onerror` event is not triggered in SSR.
|
|
39
59
|
*/
|
|
40
60
|
private _checkImageError;
|
|
@@ -82,9 +102,17 @@ export declare interface ThumbnailProps {
|
|
|
82
102
|
*/
|
|
83
103
|
backgroundColor?: typeof backgroundColors[number];
|
|
84
104
|
/**
|
|
85
|
-
*
|
|
105
|
+
* When true, hides the component default placeholder on image load failure.
|
|
106
|
+
*/
|
|
107
|
+
hideDefaultPlaceholder?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Overrides the component default placeholder with a custom one on image load failure.
|
|
86
110
|
*/
|
|
87
111
|
placeholder?: PlaceholderProps;
|
|
112
|
+
/**
|
|
113
|
+
* Sets the aspect-ratio of the thumbnail image.
|
|
114
|
+
*/
|
|
115
|
+
aspectRatio?: typeof aspectRatios[number];
|
|
88
116
|
}
|
|
89
117
|
|
|
90
118
|
export declare const variants: readonly ["default", "outline"];
|
package/dist/react.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import * as a from "react";
|
|
2
2
|
import { createComponent as e } from "@lit/react";
|
|
3
3
|
import { PieThumbnail as o } from "./index.js";
|
|
4
|
-
import {
|
|
5
|
-
const
|
|
4
|
+
import { aspectRatios as l, backgroundColorClassNames as p, backgroundColors as c, defaultProps as u, sizes as b, variants as h } from "./index.js";
|
|
5
|
+
const t = e({
|
|
6
6
|
displayName: "PieThumbnail",
|
|
7
7
|
elementClass: o,
|
|
8
8
|
react: a,
|
|
9
9
|
tagName: "pie-thumbnail",
|
|
10
10
|
events: {}
|
|
11
|
-
}),
|
|
11
|
+
}), s = t;
|
|
12
12
|
export {
|
|
13
|
-
|
|
14
|
-
l as
|
|
15
|
-
p as
|
|
13
|
+
s as PieThumbnail,
|
|
14
|
+
l as aspectRatios,
|
|
15
|
+
p as backgroundColorClassNames,
|
|
16
|
+
c as backgroundColors,
|
|
16
17
|
u as defaultProps,
|
|
17
18
|
b as sizes,
|
|
18
|
-
|
|
19
|
+
h as variants
|
|
19
20
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-thumbnail",
|
|
3
3
|
"description": "PIE Design System Thumbnail built using Web Components",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -24,8 +24,6 @@
|
|
|
24
24
|
"lint:style": "run -T stylelint ./src/**/*.{css,scss}",
|
|
25
25
|
"lint:style:fix": "yarn lint:style --fix",
|
|
26
26
|
"watch": "run -T vite build --watch",
|
|
27
|
-
"test": "echo \"Error: no test specified\" && exit 0",
|
|
28
|
-
"test:ci": "yarn test",
|
|
29
27
|
"test:browsers": "npx playwright test -c ./playwright-lit.config.ts",
|
|
30
28
|
"test:browsers:ci": "yarn test:browsers",
|
|
31
29
|
"test:visual": "run -T cross-env-shell PERCY_TOKEN=${PERCY_TOKEN_PIE_THUMBNAIL} percy exec --allowed-hostname cloudfront.net -- npx playwright test -c ./playwright-lit-visual.config.ts",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M31.9 15.493c-.103-.254-1.496-2.753-4.081-5.887a.507.507 0 0 1-.12-.267 48.166 48.166 0 0 0-.777-5.436.881.881 0 0 0-.282-.468.925.925 0 0 0-.51-.22l-2.678-.324a.595.595 0 0 0-.07 0 .575.575 0 0 0-.402.161.543.543 0 0 0-.166.39v.905a.034.034 0 0 1-.01.024.036.036 0 0 1-.037.007A2.43 2.43 0 0 0 15.992 0c-.472 0-.935.138-1.327.395C5.387 5.956.282 15.005.085 15.493a.87.87 0 0 0 .25 1.064.929.929 0 0 0 .355.175l2.672.5a.917.917 0 0 1 .454.28.872.872 0 0 1 .213.479c.023.457.528 10.69 1.163 13.344a.89.89 0 0 0 .327.48c.161.12.358.185.561.185h.02c1.56-.038 2.986-.063 4.528-.084h.13a.303.303 0 0 0 .21-.086.288.288 0 0 0 .087-.206c-.062-.893-.197-2.936-.306-5.093 0-.054-.007-.121-.01-.176a.558.558 0 0 0-.272-.442 2.847 2.847 0 0 1-.992-.96 2.745 2.745 0 0 1-.41-1.3c-.142-3.59-.211-7.736-.008-10.982a.515.515 0 0 1 .165-.365.547.547 0 0 1 .76.015c.098.1.152.234.149.373v.04c-.132 2.163-.142 4.721-.095 7.244a.61.61 0 0 0 .195.435.648.648 0 0 0 .902-.015.61.61 0 0 0 .179-.442c-.049-2.54-.036-5.114.099-7.285a.515.515 0 0 1 .165-.365.547.547 0 0 1 .76.015c.098.1.152.234.15.373v.04c-.133 2.152-.143 4.695-.097 7.204a.608.608 0 0 0 .194.436.648.648 0 0 0 .902-.014.61.61 0 0 0 .18-.44c-.047-2.53-.035-5.094.1-7.25a.515.515 0 0 1 .165-.366.546.546 0 0 1 .76.016c.099.1.152.234.15.372v.041c-.194 3.154-.131 7.148 0 10.651a.26.26 0 0 1 0 .033v.087c0 .454-.114.902-.332 1.304a2.827 2.827 0 0 1-.919 1.004.54.54 0 0 0-.237.406s-.066.539.179 3.145c.113 1.138.201 1.927.241 2.283a.273.273 0 0 0 .095.172c.052.044.12.068.188.068h4.054l1.516.012c.07 0 .137-.024.19-.069a.273.273 0 0 0 .094-.173c.35-3.124.434-4.879.434-4.879a.307.307 0 0 0-.084-.201.323.323 0 0 0-.2-.099l-1.842-.246a.636.636 0 0 1-.331-.143.606.606 0 0 1-.195-.296.832.832 0 0 1-.024-.276c.747-10.41 4.281-13.92 4.281-13.92a1.05 1.05 0 0 1 .172-.144.576.576 0 0 1 .859.245.968.968 0 0 1 .045.25c.306 3.273.157 8.842-.032 13.187a316.08 316.08 0 0 1-.353 6.582c0 .057.023.112.064.152.042.04.098.063.157.063 1.002.017 1.984.036 3.037.062h.021c.203 0 .4-.065.561-.185a.893.893 0 0 0 .328-.48c.635-2.654 1.134-12.887 1.16-13.344a.877.877 0 0 1 .215-.479.92.92 0 0 1 .453-.28l2.672-.5a.92.92 0 0 0 .5-.316.875.875 0 0 0 .193-.548.883.883 0 0 0-.1-.368Z" fill="#EFEDEA"/></svg>
|
package/src/defs.ts
CHANGED
|
@@ -17,6 +17,8 @@ export const backgroundColorClassNames: Record<typeof backgroundColors[number],
|
|
|
17
17
|
'inverse-alternative': 'c-thumbnail--backgroundInverseAlternative',
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
export const aspectRatios = ['1by1', '4by3', '16by9'] as const;
|
|
21
|
+
|
|
20
22
|
const SIZE_INCREMENT_BY = 8;
|
|
21
23
|
const SIZE_MIN = 24;
|
|
22
24
|
const SIZE_MAX = 128;
|
|
@@ -61,9 +63,17 @@ export interface ThumbnailProps {
|
|
|
61
63
|
*/
|
|
62
64
|
backgroundColor?: typeof backgroundColors[number];
|
|
63
65
|
/**
|
|
64
|
-
*
|
|
66
|
+
* When true, hides the component default placeholder on image load failure.
|
|
67
|
+
*/
|
|
68
|
+
hideDefaultPlaceholder?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Overrides the component default placeholder with a custom one on image load failure.
|
|
65
71
|
*/
|
|
66
72
|
placeholder?: PlaceholderProps;
|
|
73
|
+
/**
|
|
74
|
+
* Sets the aspect-ratio of the thumbnail image.
|
|
75
|
+
*/
|
|
76
|
+
aspectRatio?: typeof aspectRatios[number];
|
|
67
77
|
}
|
|
68
78
|
|
|
69
79
|
export type DefaultProps = ComponentDefaultProps<ThumbnailProps>;
|
|
@@ -75,7 +85,9 @@ export const defaultProps: DefaultProps = {
|
|
|
75
85
|
alt: '',
|
|
76
86
|
disabled: false,
|
|
77
87
|
hasPadding: false,
|
|
88
|
+
hideDefaultPlaceholder: false,
|
|
78
89
|
backgroundColor: 'default',
|
|
90
|
+
aspectRatio: '1by1',
|
|
79
91
|
placeholder: {
|
|
80
92
|
src: '',
|
|
81
93
|
alt: '',
|
package/src/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from 'lit';
|
|
6
6
|
import { defineCustomElement, validPropertyValues } from '@justeattakeaway/pie-webc-core';
|
|
7
7
|
import { classMap } from 'lit/directives/class-map.js';
|
|
8
|
-
import { property, query } from 'lit/decorators.js';
|
|
8
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
9
9
|
import {
|
|
10
10
|
type ThumbnailProps,
|
|
11
11
|
defaultProps,
|
|
@@ -13,8 +13,10 @@ import {
|
|
|
13
13
|
backgroundColors,
|
|
14
14
|
backgroundColorClassNames,
|
|
15
15
|
sizes,
|
|
16
|
+
aspectRatios,
|
|
16
17
|
} from './defs';
|
|
17
18
|
import styles from './thumbnail.scss?inline';
|
|
19
|
+
import defaultPlaceholder from './default-placeholder.svg?inline';
|
|
18
20
|
|
|
19
21
|
// Valid values available to consumers
|
|
20
22
|
export * from './defs';
|
|
@@ -33,6 +35,10 @@ export class PieThumbnail extends LitElement implements ThumbnailProps {
|
|
|
33
35
|
@validPropertyValues(componentSelector, sizes, defaultProps.size)
|
|
34
36
|
public size = defaultProps.size;
|
|
35
37
|
|
|
38
|
+
@property({ type: String })
|
|
39
|
+
@validPropertyValues(componentSelector, aspectRatios, defaultProps.aspectRatio)
|
|
40
|
+
public aspectRatio = defaultProps.aspectRatio;
|
|
41
|
+
|
|
36
42
|
@property({ type: String })
|
|
37
43
|
public src = defaultProps.src;
|
|
38
44
|
|
|
@@ -45,6 +51,9 @@ export class PieThumbnail extends LitElement implements ThumbnailProps {
|
|
|
45
51
|
@property({ type: Boolean })
|
|
46
52
|
public hasPadding = defaultProps.hasPadding;
|
|
47
53
|
|
|
54
|
+
@property({ type: Boolean })
|
|
55
|
+
public hideDefaultPlaceholder = defaultProps.hideDefaultPlaceholder;
|
|
56
|
+
|
|
48
57
|
@property({ type: String })
|
|
49
58
|
@validPropertyValues(componentSelector, backgroundColors, defaultProps.backgroundColor)
|
|
50
59
|
public backgroundColor = defaultProps.backgroundColor;
|
|
@@ -55,32 +64,69 @@ export class PieThumbnail extends LitElement implements ThumbnailProps {
|
|
|
55
64
|
@query('img')
|
|
56
65
|
private img!: HTMLImageElement;
|
|
57
66
|
|
|
67
|
+
@state()
|
|
68
|
+
private _hasError = false;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Determines if the default placeholder should be displayed.
|
|
72
|
+
*/
|
|
73
|
+
private get _isDefaultPlaceholderVisible (): boolean {
|
|
74
|
+
const { _hasError, placeholder, hideDefaultPlaceholder } = this;
|
|
75
|
+
return _hasError && !placeholder?.src && !hideDefaultPlaceholder;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Returns the appropriate image props based on the following order:
|
|
80
|
+
* 1. If there is no error, return the provided image props.
|
|
81
|
+
* 2. If there is an error and a custom placeholder is provided, return the placeholder props.
|
|
82
|
+
* 3. If there is an error and no custom placeholder is provided, return the component default placeholder.
|
|
83
|
+
* 4. Otherwise, fall back to the provided src (resulting in a broken image).
|
|
84
|
+
*/
|
|
85
|
+
private get _controlledSrc (): string {
|
|
86
|
+
if (!this._hasError) return this.src;
|
|
87
|
+
if (this.placeholder?.src) return this.placeholder.src;
|
|
88
|
+
if (!this.hideDefaultPlaceholder) return defaultPlaceholder;
|
|
89
|
+
return this.src;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private get _controlledAlt (): string {
|
|
93
|
+
if (!this._hasError) return this.alt;
|
|
94
|
+
if (this.placeholder?.src) return this.placeholder.alt ?? '';
|
|
95
|
+
if (!this.hideDefaultPlaceholder) return '';
|
|
96
|
+
return this.alt;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Assigns CSS variables based on the size prop.
|
|
101
|
+
*/
|
|
58
102
|
private _generateSizeStyles (): string {
|
|
59
103
|
const { size } = this;
|
|
60
104
|
let borderRadius = '--dt-radius-rounded-c';
|
|
105
|
+
let defaultPlaceholderPadding = '--dt-spacing-d';
|
|
61
106
|
if (size <= 40) {
|
|
62
107
|
borderRadius = '--dt-radius-rounded-a';
|
|
108
|
+
defaultPlaceholderPadding = '--dt-spacing-a';
|
|
63
109
|
} else if (size <= 56) {
|
|
64
110
|
borderRadius = '--dt-radius-rounded-b';
|
|
111
|
+
defaultPlaceholderPadding = '--dt-spacing-b';
|
|
65
112
|
}
|
|
66
113
|
|
|
67
114
|
return `
|
|
68
115
|
--thumbnail-size: ${size}px;
|
|
69
116
|
--thumbnail-border-radius: var(${borderRadius});
|
|
117
|
+
--thumbnail-default-placeholder-padding: var(${defaultPlaceholderPadding});
|
|
70
118
|
`;
|
|
71
119
|
}
|
|
72
120
|
|
|
73
121
|
/**
|
|
74
|
-
* Handles
|
|
75
|
-
* with the placeholder props.
|
|
122
|
+
* Handles the image error event.
|
|
76
123
|
*/
|
|
77
|
-
private _handleImageError () {
|
|
78
|
-
|
|
79
|
-
if (this.placeholder?.alt) this.setAttribute('alt', this.placeholder.alt);
|
|
124
|
+
private _handleImageError (): void {
|
|
125
|
+
this._hasError = true;
|
|
80
126
|
}
|
|
81
127
|
|
|
82
128
|
/**
|
|
83
|
-
*
|
|
129
|
+
* Checks the image load status and triggers error handling if needed.
|
|
84
130
|
* This is needed as the `onerror` event is not triggered in SSR.
|
|
85
131
|
*/
|
|
86
132
|
private _checkImageError () {
|
|
@@ -98,19 +144,23 @@ export class PieThumbnail extends LitElement implements ThumbnailProps {
|
|
|
98
144
|
render () {
|
|
99
145
|
const {
|
|
100
146
|
variant,
|
|
101
|
-
|
|
102
|
-
|
|
147
|
+
_controlledSrc,
|
|
148
|
+
_controlledAlt,
|
|
103
149
|
disabled,
|
|
104
150
|
hasPadding,
|
|
151
|
+
_isDefaultPlaceholderVisible,
|
|
105
152
|
backgroundColor,
|
|
153
|
+
aspectRatio,
|
|
106
154
|
} = this;
|
|
107
155
|
|
|
108
156
|
const wrapperClasses = {
|
|
109
157
|
'c-thumbnail': true,
|
|
110
158
|
[`c-thumbnail--${variant}`]: true,
|
|
159
|
+
[`c-thumbnail--${aspectRatio}`]: true,
|
|
111
160
|
[backgroundColorClassNames[backgroundColor]]: true,
|
|
112
161
|
'c-thumbnail--disabled': disabled,
|
|
113
162
|
'c-thumbnail--padding': hasPadding,
|
|
163
|
+
'c-thumbnail--defaultPlaceholder': _isDefaultPlaceholderVisible,
|
|
114
164
|
};
|
|
115
165
|
|
|
116
166
|
const sizeStyles = this._generateSizeStyles();
|
|
@@ -121,9 +171,9 @@ export class PieThumbnail extends LitElement implements ThumbnailProps {
|
|
|
121
171
|
style="${sizeStyles}">
|
|
122
172
|
<img
|
|
123
173
|
data-test-id="pie-thumbnail-img"
|
|
124
|
-
src="${
|
|
174
|
+
src="${_controlledSrc}"
|
|
175
|
+
alt="${_controlledAlt}"
|
|
125
176
|
class="c-thumbnail-img"
|
|
126
|
-
alt="${alt}"
|
|
127
177
|
@error="${this._handleImageError}"
|
|
128
178
|
/>
|
|
129
179
|
</div>
|
package/src/thumbnail.scss
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
--thumbnail-size: 48px;
|
|
3
3
|
--thumbnail-border-radius: var(--dt-radius-rounded-b);
|
|
4
4
|
--thumbnail-bg-color: var(--dt-color-container-default);
|
|
5
|
-
--thumbnail-border-color: transparent;
|
|
6
5
|
--thumbnail-padding: calc(var(--dt-spacing-a) / 2);
|
|
6
|
+
--thumbnail-default-placeholder-padding: var(--dt-spacing-b);
|
|
7
|
+
--thumbnail-img-border-radius: unset;
|
|
8
|
+
--thumbnail-img-object-fit: cover;
|
|
7
9
|
|
|
8
10
|
display: flex;
|
|
9
11
|
justify-content: center;
|
|
@@ -13,11 +15,10 @@
|
|
|
13
15
|
width: var(--thumbnail-size);
|
|
14
16
|
height: var(--thumbnail-size);
|
|
15
17
|
border-radius: var(--thumbnail-border-radius);
|
|
16
|
-
border: 1px solid var(--thumbnail-border-color);
|
|
17
18
|
background-color: var(--thumbnail-bg-color);
|
|
18
19
|
|
|
19
20
|
&.c-thumbnail--outline {
|
|
20
|
-
|
|
21
|
+
border: 1px solid var(--dt-color-border-default);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
&.c-thumbnail--disabled {
|
|
@@ -45,11 +46,28 @@
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
&.c-thumbnail--padding {
|
|
49
|
+
--thumbnail-img-border-radius: calc(var(--thumbnail-border-radius) - var(--thumbnail-padding));
|
|
48
50
|
padding: var(--thumbnail-padding);
|
|
49
51
|
}
|
|
50
52
|
|
|
53
|
+
&.c-thumbnail--4by3 {
|
|
54
|
+
height: calc(var(--thumbnail-size) * 3 / 4)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&.c-thumbnail--16by9 {
|
|
58
|
+
height: calc(var(--thumbnail-size) * 9 / 16)
|
|
59
|
+
}
|
|
60
|
+
|
|
51
61
|
.c-thumbnail-img {
|
|
52
62
|
width: 100%;
|
|
53
|
-
height:
|
|
63
|
+
height: 100%;
|
|
64
|
+
border-radius: var(--thumbnail-img-border-radius);
|
|
65
|
+
object-fit: var(--thumbnail-img-object-fit);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&.c-thumbnail--defaultPlaceholder {
|
|
69
|
+
--thumbnail-bg-color: var(--dt-color-container-default);
|
|
70
|
+
--thumbnail-img-object-fit: fill;
|
|
71
|
+
padding: var(--thumbnail-default-placeholder-padding);
|
|
54
72
|
}
|
|
55
73
|
}
|