@repobit/dex-system-design 0.24.9 → 0.24.11
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/CHANGELOG.md +16 -0
- package/package.json +4 -4
- package/src/components/announcement-banner/announcement-banner.css.js +73 -0
- package/src/components/announcement-banner/announcement-banner.js +56 -0
- package/src/components/announcement-banner/announcement-banner.stories.js +190 -0
- package/src/components/paragraph/paragraph.js +22 -1
- package/src/components/picture/picture.js +35 -10
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.24.11](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.24.10...@repobit/dex-system-design@0.24.11) (2026-09-09)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **DEX-1014:** announcement banner component
|
|
11
|
+
* **DEX-1014:** announcement banner component
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [0.24.10](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.24.9...@repobit/dex-system-design@0.24.10) (2026-09-08)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @repobit/dex-system-design
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
## [0.24.9](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.24.8...@repobit/dex-system-design@0.24.9) (2026-09-08)
|
|
7
23
|
|
|
8
24
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@repobit/dex-system-design",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.11",
|
|
4
4
|
"description": "Design system based on Web Components.",
|
|
5
5
|
"author": "Iordache Matei Cezar <miordache@bitdefender.com>",
|
|
6
6
|
"homepage": "https://github.com/bitdefender/dex-core#readme",
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
"url": "https://github.com/bitdefender/dex-core/issues"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@repobit/dex-store": "1.6.
|
|
78
|
-
"@repobit/dex-store-elements": "2.0.
|
|
77
|
+
"@repobit/dex-store": "1.6.27",
|
|
78
|
+
"@repobit/dex-store-elements": "2.0.32",
|
|
79
79
|
"lit": "^3.3.2"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"volta": {
|
|
93
93
|
"node": "24.14.0"
|
|
94
94
|
},
|
|
95
|
-
"gitHead": "
|
|
95
|
+
"gitHead": "1090fb8b6f3075a6fbfc7a2d055c3d00bfe05a55"
|
|
96
96
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
|
|
3
|
+
export default css`
|
|
4
|
+
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
font-family: "Roboto", "roboto-normal-400-fallback", helvetica, ubuntu, roboto, noto, sans-serif;
|
|
7
|
+
max-width: 1290px;
|
|
8
|
+
margin: 0 auto;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.bd-announcementbanner-container {
|
|
12
|
+
background: linear-gradient(87.6deg, var(--color-blue-500) 0%, var(--color-blue-950) 100%);
|
|
13
|
+
border-radius: var(--radius-2xl);
|
|
14
|
+
padding: var(--spacing-48);
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-wrap: wrap;
|
|
18
|
+
align-items: center;
|
|
19
|
+
// justify-content: space-between;
|
|
20
|
+
gap: var(--spacing-96);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.bd-announcementbanner-title {
|
|
24
|
+
display: block;
|
|
25
|
+
margin: 0;
|
|
26
|
+
color: var(--color-neutral-0, #fff);
|
|
27
|
+
line-height: var(--typography-lineHeight-tight, 1.15);
|
|
28
|
+
flex: 1 1 320px;
|
|
29
|
+
max-width: 560px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.bd-announcementbanner-side {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
align-items: flex-start;
|
|
36
|
+
gap: var(--spacing-16);
|
|
37
|
+
flex: 1 1 280px;
|
|
38
|
+
max-width: 360px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.bd-announcementbanner-icon {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
color: var(--color-neutral-0, #fff);
|
|
45
|
+
margin-bottom: var(--spacing-4);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.bd-announcementbanner-icon ::slotted(*) {
|
|
49
|
+
display: block;
|
|
50
|
+
max-width: 160px;
|
|
51
|
+
width: 100%;
|
|
52
|
+
height: auto;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.bd-announcementbanner-description {
|
|
56
|
+
margin: 0;
|
|
57
|
+
color: rgba(255, 255, 255, 0.65);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@media (max-width: 699px) {
|
|
61
|
+
.bd-announcementbanner-container {
|
|
62
|
+
padding: var(--spacing-28) var(--spacing-24);
|
|
63
|
+
flex-direction: column;
|
|
64
|
+
align-items: flex-start;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.bd-announcementbanner-title,
|
|
68
|
+
.bd-announcementbanner-side {
|
|
69
|
+
max-width: none;
|
|
70
|
+
flex-basis: auto;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { LitElement, html, nothing } from "lit";
|
|
2
|
+
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
+
import "../heading/heading.js";
|
|
4
|
+
import "../paragraph/paragraph.js";
|
|
5
|
+
import announcementBannerCSS from "./announcement-banner.css.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Simple two-column banner on a blue gradient — a title on the left, an
|
|
9
|
+
* icon + description on the right. No buttons; for
|
|
10
|
+
* partnership/announcement callouts (e.g. "Bitdefender joined the Global
|
|
11
|
+
* Anti-Scam Alliance"), not calls to action. See bd-cta-banner for the
|
|
12
|
+
* centred, button-driven variant.
|
|
13
|
+
*
|
|
14
|
+
* <bd-announcement-banner
|
|
15
|
+
* title="Bitdefender joined the Global Anti-Scam Alliance as a Foundation Member"
|
|
16
|
+
= * description="Global Anti-Scam Alliance (GASA) unites organisations, experts, and law enforcement to protect consumers worldwide from scams."
|
|
17
|
+
* >
|
|
18
|
+
* <bd-gasa-icon slot="icon" width="140" height="40" color="#fff"></bd-gasa-icon>
|
|
19
|
+
* </bd-announcement-banner>
|
|
20
|
+
*/
|
|
21
|
+
class BdAnnouncementBanner extends LitElement {
|
|
22
|
+
static properties = {
|
|
23
|
+
title : { type: String },
|
|
24
|
+
description: { type: String }
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
static styles = [tokens, announcementBannerCSS];
|
|
28
|
+
|
|
29
|
+
constructor() {
|
|
30
|
+
super();
|
|
31
|
+
this.title = "";
|
|
32
|
+
this.description = "";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
render() {
|
|
36
|
+
return html`
|
|
37
|
+
<div class="bd-announcementbanner-container">
|
|
38
|
+
<bd-h as="h2" fontWeight="400" class="bd-announcementbanner-title">
|
|
39
|
+
<slot name="title">${this.title}</slot>
|
|
40
|
+
</bd-h>
|
|
41
|
+
|
|
42
|
+
<div class="bd-announcementbanner-side">
|
|
43
|
+
<div class="bd-announcementbanner-icon">
|
|
44
|
+
<slot name="icon"></slot>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
${this.description
|
|
48
|
+
? html`<bd-p kind="large" color="var(--color-neutral-0)" class="bd-announcementbanner-description"><slot name="description">${this.description}</slot></bd-p>`
|
|
49
|
+
: nothing}
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
`;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
customElements.define("bd-announcement-banner", BdAnnouncementBanner);
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import "../picture/picture.js";
|
|
3
|
+
import "./announcement-banner.js";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title : "Components/AnnouncementBanner",
|
|
8
|
+
component : "bd-announcement-banner",
|
|
9
|
+
tags : ["autodocs"],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "padded",
|
|
12
|
+
docs : {
|
|
13
|
+
description: {
|
|
14
|
+
component: `
|
|
15
|
+
**AnnouncementBanner** este un banner simplu, cu 2 coloane, pe fundal albastru
|
|
16
|
+
gradient — titlu mare în stânga, iar în dreapta o iconiță/logo + caption +
|
|
17
|
+
descriere. Nu are butoane — e gândit pentru anunțuri de tip parteneriat sau
|
|
18
|
+
apartenență la o organizație, nu pentru CTA-uri.
|
|
19
|
+
|
|
20
|
+
Pentru varianta centrată, cu butoane, vezi \`bd-cta-banner\`.
|
|
21
|
+
|
|
22
|
+
### Usage
|
|
23
|
+
\`\`\`html
|
|
24
|
+
<bd-announcement-banner
|
|
25
|
+
title="Bitdefender joined the Global Anti-Scam Alliance as a Foundation Member"
|
|
26
|
+
caption="Global Anti-Scam Alliance"
|
|
27
|
+
description="Global Anti-Scam Alliance (GASA) unites organisations, experts, and law enforcement to protect consumers worldwide from scams."
|
|
28
|
+
>
|
|
29
|
+
<bd-picture
|
|
30
|
+
slot="icon"
|
|
31
|
+
.sources=\${sources}
|
|
32
|
+
.fallbackSrc=\${fallbackSrc}
|
|
33
|
+
alt="Global Anti-Scam Alliance logo"
|
|
34
|
+
></bd-picture>
|
|
35
|
+
</bd-announcement-banner>
|
|
36
|
+
\`\`\`
|
|
37
|
+
|
|
38
|
+
### Attributes
|
|
39
|
+
| Attribute | Type | Default | Description |
|
|
40
|
+
|------------------|--------|----------|------------------------------------------------------------|
|
|
41
|
+
| \`title\` | String | \`""\` | Titlul mare, afișat în coloana stângă (sau slot-ul \`title\`) |
|
|
42
|
+
| \`caption\` | String | \`""\` | Eticheta scurtă de deasupra descrierii, coloana dreaptă (opțional) |
|
|
43
|
+
| \`description\` | String | \`""\` | Textul descriptiv din coloana dreaptă (sau slot-ul \`description\`) |
|
|
44
|
+
|
|
45
|
+
### Slots
|
|
46
|
+
| Slot | Description |
|
|
47
|
+
|-----------------|--------------------------------------------------------------------|
|
|
48
|
+
| \`icon\` | Iconița/logo-ul din coloana dreaptă (ex: \`bd-picture\`) |
|
|
49
|
+
| \`title\` | Suprascrie atributul \`title\` dacă are conținut |
|
|
50
|
+
| \`caption\` | Suprascrie atributul \`caption\` dacă are conținut |
|
|
51
|
+
| \`description\` | Suprascrie atributul \`description\` dacă are conținut |
|
|
52
|
+
`
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
argTypes: {
|
|
57
|
+
title : { control: "text", table: { category: "Content" } },
|
|
58
|
+
caption : { control: "text", table: { category: "Content" } },
|
|
59
|
+
description: { control: "text", table: { category: "Content" } }
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const gasaSources = [
|
|
64
|
+
{
|
|
65
|
+
type : "image/webp",
|
|
66
|
+
srcset: "https://main--www-websites--bitdefender.aem.page/en-us/consumer/media_1a19736be4554469877718d743401be3086dbb640.png?width=2000&format=webply&optimize=medium",
|
|
67
|
+
media : "(min-width: 600px)"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type : "image/webp",
|
|
71
|
+
srcset: "https://main--www-websites--bitdefender.aem.page/en-us/consumer/media_1a19736be4554469877718d743401be3086dbb640.png?width=750&format=webply&optimize=medium"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
type : "image/png",
|
|
75
|
+
srcset: "https://main--www-websites--bitdefender.aem.page/en-us/consumer/media_1a19736be4554469877718d743401be3086dbb640.png?width=2000&format=png&optimize=medium",
|
|
76
|
+
media : "(min-width: 600px)"
|
|
77
|
+
}
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
const gasaFallback = "https://main--www-websites--bitdefender.aem.page/en-us/consumer/media_1a19736be4554469877718d743401be3086dbb640.png?width=750&format=png&optimize=medium";
|
|
81
|
+
|
|
82
|
+
const gasaPicture = () => html`
|
|
83
|
+
<bd-picture
|
|
84
|
+
slot="icon"
|
|
85
|
+
.sources=${gasaSources}
|
|
86
|
+
.fallbackSrc=${gasaFallback}
|
|
87
|
+
alt="Global Anti-Scam Alliance logo"
|
|
88
|
+
.width=${393}
|
|
89
|
+
.height=${144}
|
|
90
|
+
fit="contain"
|
|
91
|
+
loading="lazy"
|
|
92
|
+
referrer-policy="no-referrer"
|
|
93
|
+
></bd-picture>
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
export const Default = {
|
|
97
|
+
name: "1. Default",
|
|
98
|
+
args: {
|
|
99
|
+
title : "Bitdefender joined the Global Anti-Scam Alliance as a Foundation Member",
|
|
100
|
+
caption : "Global Anti-Scam Alliance",
|
|
101
|
+
description: "Global Anti-Scam Alliance (GASA) unites organisations, experts, and law enforcement to protect consumers worldwide from scams."
|
|
102
|
+
},
|
|
103
|
+
render: (args) => html`
|
|
104
|
+
<bd-announcement-banner
|
|
105
|
+
title=${args.title}
|
|
106
|
+
caption=${args.caption}
|
|
107
|
+
description=${args.description}
|
|
108
|
+
>
|
|
109
|
+
${gasaPicture()}
|
|
110
|
+
</bd-announcement-banner>
|
|
111
|
+
`,
|
|
112
|
+
parameters: {
|
|
113
|
+
docs: {
|
|
114
|
+
description: {
|
|
115
|
+
story: "Varianta completă: titlu, caption, descriere și iconiță."
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const NoCaption = {
|
|
122
|
+
name: "2. Fără caption",
|
|
123
|
+
args: {
|
|
124
|
+
title : "Bitdefender named a Leader in the 2026 Endpoint Protection report",
|
|
125
|
+
caption : "",
|
|
126
|
+
description: "Recognised for detection accuracy, low false-positive rate, and minimal performance impact across three consecutive evaluation cycles."
|
|
127
|
+
},
|
|
128
|
+
render: (args) => html`
|
|
129
|
+
<bd-announcement-banner
|
|
130
|
+
title=${args.title}
|
|
131
|
+
caption=${args.caption}
|
|
132
|
+
description=${args.description}
|
|
133
|
+
>
|
|
134
|
+
${gasaPicture()}
|
|
135
|
+
</bd-announcement-banner>
|
|
136
|
+
`,
|
|
137
|
+
parameters: {
|
|
138
|
+
docs: {
|
|
139
|
+
description: {
|
|
140
|
+
story: "Fără caption — util când titlul e suficient de descriptiv."
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export const TitleOnly = {
|
|
147
|
+
name: "3. Doar titlu",
|
|
148
|
+
args: {
|
|
149
|
+
title : "Bitdefender now supports macOS Tahoe on day one",
|
|
150
|
+
caption : "",
|
|
151
|
+
description: ""
|
|
152
|
+
},
|
|
153
|
+
render: (args) => html`
|
|
154
|
+
<bd-announcement-banner title=${args.title}>
|
|
155
|
+
${gasaPicture()}
|
|
156
|
+
</bd-announcement-banner>
|
|
157
|
+
`,
|
|
158
|
+
parameters: {
|
|
159
|
+
docs: {
|
|
160
|
+
description: {
|
|
161
|
+
story: "Minimal — doar titlu și iconiță, fără caption sau descriere."
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export const Playground = {
|
|
168
|
+
name: "Playground",
|
|
169
|
+
args: {
|
|
170
|
+
title : "Bitdefender joined the Global Anti-Scam Alliance as a Foundation Member",
|
|
171
|
+
caption : "Global Anti-Scam Alliance",
|
|
172
|
+
description: "Global Anti-Scam Alliance (GASA) unites organisations, experts, and law enforcement to protect consumers worldwide from scams."
|
|
173
|
+
},
|
|
174
|
+
render: (args) => html`
|
|
175
|
+
<bd-announcement-banner
|
|
176
|
+
title=${args.title}
|
|
177
|
+
caption=${args.caption}
|
|
178
|
+
description=${args.description}
|
|
179
|
+
>
|
|
180
|
+
${gasaPicture()}
|
|
181
|
+
</bd-announcement-banner>
|
|
182
|
+
`,
|
|
183
|
+
parameters: {
|
|
184
|
+
docs: {
|
|
185
|
+
description: {
|
|
186
|
+
story: "Interactiv — modifică `title`, `caption` și `description` din Controls."
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
@@ -9,7 +9,8 @@ export class BdP extends LitElement {
|
|
|
9
9
|
paddingBottom: { type: String },
|
|
10
10
|
paddingTop : { type: String },
|
|
11
11
|
fontFamily : { type: String, attribute: "font-family" },
|
|
12
|
-
fontWeight : { type: String, attribute: "font-weight" }
|
|
12
|
+
fontWeight : { type: String, attribute: "font-weight" },
|
|
13
|
+
color : { type: String }
|
|
13
14
|
};
|
|
14
15
|
|
|
15
16
|
constructor() {
|
|
@@ -20,6 +21,7 @@ export class BdP extends LitElement {
|
|
|
20
21
|
this.paddingTop = "";
|
|
21
22
|
this.fontFamily = "";
|
|
22
23
|
this.fontWeight = "";
|
|
24
|
+
this.color = "";
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
_getKindClass() {
|
|
@@ -35,6 +37,22 @@ export class BdP extends LitElement {
|
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
// Same validation as bd-h's _getValidColor — only accepts CSS token
|
|
41
|
+
// references or real colour syntax, so a typo or stray text never lands
|
|
42
|
+
// in the inline style attribute as literal (and potentially unsafe) CSS.
|
|
43
|
+
_getValidColor(color) {
|
|
44
|
+
if (!color) return "";
|
|
45
|
+
if (
|
|
46
|
+
color.startsWith("var(") ||
|
|
47
|
+
color.startsWith("#") ||
|
|
48
|
+
color.startsWith("rgb") ||
|
|
49
|
+
color.startsWith("hsl")
|
|
50
|
+
) {
|
|
51
|
+
return color;
|
|
52
|
+
}
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
|
|
38
56
|
render() {
|
|
39
57
|
const styles = [];
|
|
40
58
|
if (this.padding) styles.push(`padding: ${this.padding};`);
|
|
@@ -43,6 +61,9 @@ export class BdP extends LitElement {
|
|
|
43
61
|
if (this.fontFamily) styles.push(`font-family: ${this.fontFamily};`);
|
|
44
62
|
if (this.fontWeight) styles.push(`font-weight: ${this.fontWeight};`);
|
|
45
63
|
|
|
64
|
+
const validColor = this._getValidColor(this.color);
|
|
65
|
+
if (validColor) styles.push(`color: ${validColor};`);
|
|
66
|
+
|
|
46
67
|
const kindClass = this._getKindClass();
|
|
47
68
|
|
|
48
69
|
return html`
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { LitElement, html } from "lit";
|
|
1
|
+
import { LitElement, html, nothing } from "lit";
|
|
2
2
|
import { tokens } from "../../tokens/tokens.js";
|
|
3
3
|
import pictureCSS from "./picture.css.js";
|
|
4
4
|
|
|
5
5
|
export class BdPicture extends LitElement {
|
|
6
6
|
static properties = {
|
|
7
|
-
sources
|
|
8
|
-
alt
|
|
9
|
-
fallbackSrc: { type: String },
|
|
10
|
-
width
|
|
11
|
-
height
|
|
12
|
-
loading
|
|
13
|
-
fit
|
|
14
|
-
radius
|
|
7
|
+
sources : { type: Array },
|
|
8
|
+
alt : { type: String },
|
|
9
|
+
fallbackSrc : { type: String },
|
|
10
|
+
width : { type: Number },
|
|
11
|
+
height : { type: Number },
|
|
12
|
+
loading : { type: String },
|
|
13
|
+
fit : { type: String },
|
|
14
|
+
radius : { type: String },
|
|
15
|
+
referrerPolicy: { type: String, attribute: "referrer-policy" },
|
|
16
|
+
_loaded : { state: true }
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
constructor() {
|
|
@@ -24,6 +26,25 @@ export class BdPicture extends LitElement {
|
|
|
24
26
|
this.loading = "lazy";
|
|
25
27
|
this.fit = "cover";
|
|
26
28
|
this.radius = "none";
|
|
29
|
+
this.referrerPolicy = "";
|
|
30
|
+
this._loaded = false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_onImgLoad() {
|
|
34
|
+
this._loaded = true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
_onImgError() {
|
|
38
|
+
this._loaded = true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
updated(changedProperties) {
|
|
42
|
+
super.updated(changedProperties);
|
|
43
|
+
if (this._loaded) return;
|
|
44
|
+
const img = this.renderRoot?.querySelector("img");
|
|
45
|
+
if (img && img.complete && img.naturalWidth > 0) {
|
|
46
|
+
this._loaded = true;
|
|
47
|
+
}
|
|
27
48
|
}
|
|
28
49
|
|
|
29
50
|
render() {
|
|
@@ -34,7 +55,7 @@ export class BdPicture extends LitElement {
|
|
|
34
55
|
].filter(Boolean).join(' ');
|
|
35
56
|
|
|
36
57
|
return html`
|
|
37
|
-
<picture class="${classes}">
|
|
58
|
+
<picture class="${classes}" ?loaded=${this._loaded}>
|
|
38
59
|
${this.sources.map(source => html`
|
|
39
60
|
<source
|
|
40
61
|
type="${source.type}"
|
|
@@ -49,6 +70,10 @@ export class BdPicture extends LitElement {
|
|
|
49
70
|
src="${this.fallbackSrc}"
|
|
50
71
|
width="${this.width}"
|
|
51
72
|
height="${this.height}"
|
|
73
|
+
referrerpolicy="${this.referrerPolicy || nothing}"
|
|
74
|
+
?loaded=${this._loaded}
|
|
75
|
+
@load=${this._onImgLoad}
|
|
76
|
+
@error=${this._onImgError}
|
|
52
77
|
>
|
|
53
78
|
</picture>
|
|
54
79
|
`;
|