@repobit/dex-system-design 0.23.63 → 0.23.65
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 +15 -0
- package/package.json +4 -4
- package/src/components/cards/card.css.js +40 -26
- package/src/components/cards/card.js +101 -15
- package/src/components/cards/card.stories.js +146 -28
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
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.23.65](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.23.64...@repobit/dex-system-design@0.23.65) (2026-07-03)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **DEX-1014:** css adjustments for cards component
|
|
11
|
+
* **DEX-1014:** css adjustments for cards component
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [0.23.64](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.23.63...@repobit/dex-system-design@0.23.64) (2026-07-03)
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* **DEX-1014:** css adjustments for cards component
|
|
19
|
+
|
|
20
|
+
|
|
6
21
|
## [0.23.63](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.23.62...@repobit/dex-system-design@0.23.63) (2026-07-02)
|
|
7
22
|
|
|
8
23
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@repobit/dex-system-design",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.65",
|
|
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",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"url": "https://github.com/bitdefender/dex-core/issues"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@repobit/dex-store": "1.3.
|
|
74
|
-
"@repobit/dex-store-elements": "1.4.
|
|
73
|
+
"@repobit/dex-store": "1.3.61",
|
|
74
|
+
"@repobit/dex-store-elements": "1.4.53",
|
|
75
75
|
"lit": "^3.3.2"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
@@ -88,5 +88,5 @@
|
|
|
88
88
|
"volta": {
|
|
89
89
|
"node": "24.14.0"
|
|
90
90
|
},
|
|
91
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "798ae4c67c57d8932da4962aea6c451315865638"
|
|
92
92
|
}
|
|
@@ -8,12 +8,16 @@ export default css`
|
|
|
8
8
|
padding-top: var(--spacing-64);
|
|
9
9
|
padding-bottom: var(--spacing-64);
|
|
10
10
|
max-width: 1290px;
|
|
11
|
+
margin: 0 auto;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
::slotted([slot="icon"]) {
|
|
14
|
-
width:
|
|
15
|
-
height:
|
|
16
|
-
|
|
15
|
+
max-width: 120px !important;
|
|
16
|
+
max-height: 120px !important;
|
|
17
|
+
width: auto !important;
|
|
18
|
+
height: auto !important;
|
|
19
|
+
object-fit: contain !important;
|
|
20
|
+
display: block !important;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
.bd-section-title-s {
|
|
@@ -33,11 +37,7 @@ export default css`
|
|
|
33
37
|
justify-content: center;
|
|
34
38
|
position: relative;
|
|
35
39
|
width: 100%;
|
|
36
|
-
margin: var(--spacing-0) auto;
|
|
37
|
-
overflow: hidden;
|
|
38
40
|
flex-direction: column;
|
|
39
|
-
padding-left: var(--spacing-14);
|
|
40
|
-
padding-right: var(--spacing-14);
|
|
41
41
|
max-width: 1400px;
|
|
42
42
|
margin: 0 auto;
|
|
43
43
|
}
|
|
@@ -65,7 +65,6 @@ export default css`
|
|
|
65
65
|
scroll-snap-type: x mandatory;
|
|
66
66
|
display: grid;
|
|
67
67
|
gap: 1.5rem;
|
|
68
|
-
grid-template-columns: repeat(4, 1fr);
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
.bd-light-carousel-track-s::-webkit-scrollbar {
|
|
@@ -73,13 +72,12 @@ export default css`
|
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
.bd-light-box-s {
|
|
76
|
-
flex: var(--spacing-0) var(--spacing-0) auto;
|
|
77
75
|
background: var(--background-card-grey);
|
|
78
76
|
border-radius: var(--spacing-20);
|
|
79
77
|
padding: var(--spacing-32);
|
|
80
78
|
display: flex;
|
|
81
79
|
flex-direction: column;
|
|
82
|
-
align-items: start;
|
|
80
|
+
align-items: flex-start;
|
|
83
81
|
justify-content: flex-start;
|
|
84
82
|
text-align: start;
|
|
85
83
|
transition: transform 0.2s ease-in-out;
|
|
@@ -133,30 +131,32 @@ export default css`
|
|
|
133
131
|
text-align: center !important;
|
|
134
132
|
}
|
|
135
133
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
.bd-light-icon-s {
|
|
135
|
+
max-width: 120px;
|
|
136
|
+
max-height: 120px;
|
|
137
|
+
width: auto;
|
|
138
|
+
height: auto;
|
|
139
|
+
object-fit: contain;
|
|
140
|
+
display: block;
|
|
141
|
+
}
|
|
142
142
|
|
|
143
143
|
.bd-light-box-no-content .bd-light-icon-s {
|
|
144
144
|
margin: 0 !important;
|
|
145
|
-
bottom: 0;
|
|
146
145
|
}
|
|
147
146
|
|
|
148
147
|
.bd-light-box-header-s {
|
|
149
148
|
display: flex;
|
|
150
149
|
flex-direction: column;
|
|
151
150
|
align-items: flex-start;
|
|
151
|
+
justify-content: flex-start;
|
|
152
152
|
gap: var(--spacing-8);
|
|
153
153
|
padding-bottom: var(--spacing-8);
|
|
154
|
-
left: -5px;
|
|
155
154
|
position: relative;
|
|
156
155
|
}
|
|
157
156
|
|
|
158
157
|
.bd-light-box-no-content .bd-light-box-header-s {
|
|
159
158
|
align-items: center !important;
|
|
159
|
+
justify-content: center !important;
|
|
160
160
|
margin: 0 !important;
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -167,8 +167,9 @@ export default css`
|
|
|
167
167
|
|
|
168
168
|
.bd-light-title-badge-wrapper-s {
|
|
169
169
|
display: flex;
|
|
170
|
-
align-items:
|
|
170
|
+
align-items: flex-start;
|
|
171
171
|
gap: var(--spacing-4, 4px);
|
|
172
|
+
overflow: hidden;
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
.bd-light-title-no-content {
|
|
@@ -177,9 +178,26 @@ export default css`
|
|
|
177
178
|
justify-content: center;
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
.bd-card-content-wrapper {
|
|
182
|
+
flex: 1;
|
|
183
|
+
display: flex;
|
|
184
|
+
flex-direction: column;
|
|
185
|
+
width: 100%;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.bd-card-cta-wrapper {
|
|
189
|
+
margin-top: var(--spacing-16);
|
|
190
|
+
padding-top: var(--spacing-8);
|
|
191
|
+
display: flex;
|
|
192
|
+
align-items: flex-start;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.bd-card-cta-wrapper:empty {
|
|
196
|
+
display: none;
|
|
197
|
+
}
|
|
198
|
+
|
|
180
199
|
@media (max-width: 1024px) {
|
|
181
200
|
.bd-light-box-s {
|
|
182
|
-
width: 380px;
|
|
183
201
|
padding: 1.5em;
|
|
184
202
|
}
|
|
185
203
|
|
|
@@ -192,7 +210,7 @@ export default css`
|
|
|
192
210
|
}
|
|
193
211
|
|
|
194
212
|
.bd-light-carousel-track-s {
|
|
195
|
-
grid-template-columns: repeat(2, 1fr);
|
|
213
|
+
grid-template-columns: repeat(2, 1fr) !important;
|
|
196
214
|
}
|
|
197
215
|
}
|
|
198
216
|
|
|
@@ -230,15 +248,11 @@ export default css`
|
|
|
230
248
|
.bd-light-box-s p {
|
|
231
249
|
font-size: 0.9em;
|
|
232
250
|
}
|
|
233
|
-
|
|
234
|
-
.bd-light-icon-s {
|
|
235
|
-
bottom: var(--spacing-10);
|
|
236
|
-
}
|
|
237
251
|
}
|
|
238
252
|
|
|
239
253
|
@media (max-width: 600px) {
|
|
240
254
|
.bd-light-carousel-track-s {
|
|
241
|
-
grid-template-columns: 1fr;
|
|
255
|
+
grid-template-columns: 1fr !important;
|
|
242
256
|
}
|
|
243
257
|
}
|
|
244
258
|
`;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LitElement, html } from "lit";
|
|
2
2
|
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
+
import "../button/button.js";
|
|
3
4
|
import "../heading/heading.js";
|
|
4
5
|
import carouselCSS from "./card.css.js";
|
|
5
6
|
|
|
@@ -25,20 +26,68 @@ class Card extends LitElement {
|
|
|
25
26
|
if (!items.length) return;
|
|
26
27
|
|
|
27
28
|
items.forEach(item => {
|
|
28
|
-
const box
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
const box = item.renderRoot?.querySelector(".bd-light-box-s");
|
|
30
|
+
const iconW = item.renderRoot?.querySelector(".bd-light-box-header-s");
|
|
31
|
+
const titleW = item.renderRoot?.querySelector(".bd-light-title-badge-wrapper-s");
|
|
32
|
+
const contentW = item.renderRoot?.querySelector(".bd-card-content-wrapper");
|
|
33
|
+
|
|
34
|
+
if (box) { box.style.height = "auto"; box.style.minHeight = "0"; box.style.width = "auto"; }
|
|
35
|
+
if (iconW) { iconW.style.height = "auto"; }
|
|
36
|
+
if (titleW) { titleW.style.height = "auto"; }
|
|
37
|
+
if (contentW) { contentW.style.height = "auto"; }
|
|
33
38
|
});
|
|
34
39
|
|
|
35
40
|
requestAnimationFrame(() => {
|
|
41
|
+
let maxIcon = 0;
|
|
42
|
+
items.forEach(item => {
|
|
43
|
+
const el = item.renderRoot?.querySelector(".bd-light-box-header-s");
|
|
44
|
+
if (!el) return;
|
|
45
|
+
const h = el.getBoundingClientRect().height;
|
|
46
|
+
if (h > maxIcon) maxIcon = h;
|
|
47
|
+
});
|
|
48
|
+
if (maxIcon > 0) {
|
|
49
|
+
items.forEach(item => {
|
|
50
|
+
const el = item.renderRoot?.querySelector(".bd-light-box-header-s");
|
|
51
|
+
if (el) el.style.height = `${maxIcon}px`;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let maxTitle = 0;
|
|
56
|
+
items.forEach(item => {
|
|
57
|
+
const el = item.renderRoot?.querySelector(".bd-light-title-badge-wrapper-s");
|
|
58
|
+
if (!el) return;
|
|
59
|
+
const h = el.getBoundingClientRect().height;
|
|
60
|
+
if (h > maxTitle) maxTitle = h;
|
|
61
|
+
});
|
|
62
|
+
if (maxTitle > 0) {
|
|
63
|
+
items.forEach(item => {
|
|
64
|
+
const el = item.renderRoot?.querySelector(".bd-light-title-badge-wrapper-s");
|
|
65
|
+
if (el) el.style.height = `${maxTitle}px`;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let maxContent = 0;
|
|
70
|
+
items.forEach(item => {
|
|
71
|
+
const el = item.renderRoot?.querySelector(".bd-card-content-wrapper");
|
|
72
|
+
if (!el) return;
|
|
73
|
+
const h = el.getBoundingClientRect().height;
|
|
74
|
+
if (h > maxContent) maxContent = h;
|
|
75
|
+
});
|
|
76
|
+
if (maxContent > 0) {
|
|
77
|
+
items.forEach(item => {
|
|
78
|
+
const el = item.renderRoot?.querySelector(".bd-card-content-wrapper");
|
|
79
|
+
if (el) el.style.height = `${maxContent}px`;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let maxW = 0;
|
|
36
84
|
let maxH = 0;
|
|
37
85
|
items.forEach(item => {
|
|
38
86
|
const box = item.renderRoot?.querySelector(".bd-light-box-s");
|
|
39
87
|
if (!box) return;
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
88
|
+
const rect = box.getBoundingClientRect();
|
|
89
|
+
if (rect.height > maxH) maxH = rect.height;
|
|
90
|
+
if (rect.width > maxW) maxW = rect.width;
|
|
42
91
|
});
|
|
43
92
|
|
|
44
93
|
if (maxH > 0) {
|
|
@@ -50,6 +99,16 @@ class Card extends LitElement {
|
|
|
50
99
|
}
|
|
51
100
|
});
|
|
52
101
|
}
|
|
102
|
+
|
|
103
|
+
if (maxW > 0) {
|
|
104
|
+
items.forEach(item => {
|
|
105
|
+
const box = item.renderRoot?.querySelector(".bd-light-box-s");
|
|
106
|
+
if (box) {
|
|
107
|
+
box.style.width = `${maxW}px`;
|
|
108
|
+
box.style.minWidth = `${maxW}px`;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
53
112
|
});
|
|
54
113
|
}
|
|
55
114
|
|
|
@@ -76,6 +135,8 @@ class Card extends LitElement {
|
|
|
76
135
|
}
|
|
77
136
|
|
|
78
137
|
render() {
|
|
138
|
+
const itemCount = this.querySelectorAll("bd-card-item").length;
|
|
139
|
+
|
|
79
140
|
return html`
|
|
80
141
|
<section class="bd-light-carousel-s">
|
|
81
142
|
${this.title
|
|
@@ -85,7 +146,10 @@ class Card extends LitElement {
|
|
|
85
146
|
</div>
|
|
86
147
|
`
|
|
87
148
|
: null}
|
|
88
|
-
<div
|
|
149
|
+
<div
|
|
150
|
+
class="bd-light-carousel-track-s"
|
|
151
|
+
style="grid-template-columns: repeat(${itemCount}, 1fr);"
|
|
152
|
+
>
|
|
89
153
|
<slot @slotchange=${() => this._equalizeHeights()}></slot>
|
|
90
154
|
</div>
|
|
91
155
|
</section>
|
|
@@ -111,15 +175,22 @@ class CardItem extends LitElement {
|
|
|
111
175
|
const iconEl = this.querySelector("[slot='icon']");
|
|
112
176
|
|
|
113
177
|
if (iconEl) {
|
|
114
|
-
|
|
178
|
+
const clone = iconEl.cloneNode(true);
|
|
179
|
+
clone.style.maxWidth = "120px";
|
|
180
|
+
clone.style.maxHeight = "120px";
|
|
181
|
+
clone.style.width = "auto";
|
|
182
|
+
clone.style.height = "auto";
|
|
183
|
+
clone.style.objectFit = "contain";
|
|
184
|
+
clone.style.display = "block";
|
|
185
|
+
return clone;
|
|
115
186
|
}
|
|
116
187
|
|
|
117
188
|
if (this.icon) {
|
|
118
189
|
return html`<img
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
190
|
+
src="${this.icon}"
|
|
191
|
+
alt="icon"
|
|
192
|
+
class="bd-light-icon-s"
|
|
193
|
+
/>`;
|
|
123
194
|
}
|
|
124
195
|
|
|
125
196
|
return "";
|
|
@@ -128,7 +199,8 @@ class CardItem extends LitElement {
|
|
|
128
199
|
_hasContent() {
|
|
129
200
|
const slottedNodes = [...this.childNodes].filter((node) => {
|
|
130
201
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
131
|
-
|
|
202
|
+
const slot = node.getAttribute("slot");
|
|
203
|
+
return slot !== "icon" && slot !== "cta";
|
|
132
204
|
}
|
|
133
205
|
return node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== "";
|
|
134
206
|
});
|
|
@@ -142,9 +214,13 @@ class CardItem extends LitElement {
|
|
|
142
214
|
|
|
143
215
|
return html`
|
|
144
216
|
<div class="bd-light-box-s ${isCentered ? "bd-light-box-center" : ""} ${!hasContent ? "bd-light-box-no-content" : ""}">
|
|
217
|
+
|
|
218
|
+
<!-- Icon -->
|
|
145
219
|
<div class="bd-light-box-header-s ${isCentered ? "bd-light-box-header-center" : ""}">
|
|
146
220
|
${this._renderIcon()}
|
|
147
221
|
</div>
|
|
222
|
+
|
|
223
|
+
<!-- Titlu -->
|
|
148
224
|
${this.title
|
|
149
225
|
? html`
|
|
150
226
|
<div class="bd-light-title-badge-wrapper-s ${!hasContent ? "bd-light-title-no-content" : ""}">
|
|
@@ -152,7 +228,17 @@ class CardItem extends LitElement {
|
|
|
152
228
|
</div>
|
|
153
229
|
`
|
|
154
230
|
: ""}
|
|
155
|
-
|
|
231
|
+
|
|
232
|
+
<!-- Content -->
|
|
233
|
+
<div class="bd-card-content-wrapper">
|
|
234
|
+
<slot></slot>
|
|
235
|
+
</div>
|
|
236
|
+
|
|
237
|
+
<!-- CTA Button -->
|
|
238
|
+
<div class="bd-card-cta-wrapper">
|
|
239
|
+
<slot name="cta"></slot>
|
|
240
|
+
</div>
|
|
241
|
+
|
|
156
242
|
</div>
|
|
157
243
|
`;
|
|
158
244
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
|
+
import '../button/button.js';
|
|
2
3
|
import '../heading/heading.js';
|
|
3
4
|
import '../icons/analysis-icon.js';
|
|
4
|
-
import '../icons/arrow-down-icon.js';
|
|
5
5
|
import '../icons/arrow-up-icon.js';
|
|
6
|
-
import '../icons/close-icon.js';
|
|
7
6
|
import '../icons/family-icon.js';
|
|
8
7
|
import '../icons/globe-icon.js';
|
|
9
8
|
import '../icons/individual-icon.js';
|
|
@@ -20,25 +19,33 @@ export default {
|
|
|
20
19
|
component: `
|
|
21
20
|
**Card** and **CardItem** are Lit components for a static card grid layout.
|
|
22
21
|
|
|
23
|
-
- \`<bd-card-section>\` — a section wrapper with an optional title and a
|
|
24
|
-
- \`<bd-card-item>\` — individual card with optional icon, title, alignment, and
|
|
22
|
+
- \`<bd-card-section>\` — a section wrapper with an optional title and a grid track
|
|
23
|
+
- \`<bd-card-item>\` — individual card with optional icon, title, alignment, slotted content, and CTA button
|
|
25
24
|
|
|
26
25
|
### Usage
|
|
27
26
|
\`\`\`html
|
|
28
27
|
<bd-card-section title="Why Bitdefender">
|
|
29
|
-
<bd-card-item title="AI
|
|
28
|
+
<bd-card-item title="AI Protection" align="center">
|
|
30
29
|
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
31
30
|
<bd-p>Powered by machine learning.</bd-p>
|
|
32
|
-
|
|
31
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
33
32
|
</bd-card-item>
|
|
34
33
|
</bd-card-section>
|
|
35
34
|
\`\`\`
|
|
36
35
|
|
|
37
|
-
### CardItem
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
### CardItem Slots
|
|
37
|
+
| Slot | Descriere |
|
|
38
|
+
|---|---|
|
|
39
|
+
| \`icon\` | Iconiță sau imagine (max 120x120px automat) |
|
|
40
|
+
| default | Conținut text — \`bd-p\`, liste, etc. |
|
|
41
|
+
| \`cta\` | Buton CTA jos stânga — \`bd-button-link\` sau \`bd-button\` |
|
|
42
|
+
|
|
43
|
+
### CardItem Props
|
|
44
|
+
| Prop | Valori | Default |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| \`title\` | String | \`''\` |
|
|
47
|
+
| \`align\` | \`start\`, \`center\` | \`start\` |
|
|
48
|
+
| \`icon\` | String (path) | \`''\` |
|
|
42
49
|
`
|
|
43
50
|
}
|
|
44
51
|
}
|
|
@@ -46,25 +53,23 @@ export default {
|
|
|
46
53
|
argTypes: {
|
|
47
54
|
sectionTitle: {
|
|
48
55
|
control : 'text',
|
|
49
|
-
description: 'Optional title for the card section
|
|
56
|
+
description: 'Optional title for the card section',
|
|
50
57
|
table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'CardSection' }
|
|
51
58
|
},
|
|
52
59
|
itemTitle: {
|
|
53
60
|
control : 'text',
|
|
54
|
-
description: 'Title of the card item
|
|
61
|
+
description: 'Title of the card item',
|
|
55
62
|
table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'CardItem' }
|
|
56
63
|
},
|
|
57
64
|
align: {
|
|
58
65
|
control : { type: 'select' },
|
|
59
66
|
options : ['start', 'center'],
|
|
60
|
-
description: 'Alignment of card content.
|
|
67
|
+
description: 'Alignment of card content.',
|
|
61
68
|
table : { type: { summary: "'start' | 'center'" }, defaultValue: { summary: 'start' }, category: 'CardItem' }
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
71
|
};
|
|
65
72
|
|
|
66
|
-
// ─── Stories ───────────────────────────────────────────────────────────────
|
|
67
|
-
|
|
68
73
|
export const Default = {
|
|
69
74
|
name : 'Default (4 items)',
|
|
70
75
|
render: () => html`
|
|
@@ -87,7 +92,65 @@ export const Default = {
|
|
|
87
92
|
</bd-card-item>
|
|
88
93
|
</bd-card-section>
|
|
89
94
|
`,
|
|
90
|
-
parameters: { docs: { description: { story: 'Four card items with icons, titles, and
|
|
95
|
+
parameters: { docs: { description: { story: 'Four card items with icons, titles, and content.' } } }
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const WithCTA = {
|
|
99
|
+
name : 'With CTA Button',
|
|
100
|
+
render: () => html`
|
|
101
|
+
<bd-card-section title="Why Bitdefender">
|
|
102
|
+
<bd-card-item title="AI Protection">
|
|
103
|
+
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
104
|
+
<bd-p>Powered by machine learning and behavioral analysis to stop threats before they reach you.</bd-p>
|
|
105
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
106
|
+
</bd-card-item>
|
|
107
|
+
<bd-card-item title="Multi-layer Security">
|
|
108
|
+
<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
|
|
109
|
+
<bd-p>Multiple independent protection layers stop any attack.</bd-p>
|
|
110
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
111
|
+
</bd-card-item>
|
|
112
|
+
<bd-card-item title="VPN Included">
|
|
113
|
+
<bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
|
|
114
|
+
<bd-p>Unlimited encrypted VPN traffic for all your devices, anywhere.</bd-p>
|
|
115
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
116
|
+
</bd-card-item>
|
|
117
|
+
<bd-card-item title="Parental Controls">
|
|
118
|
+
<bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
|
|
119
|
+
<bd-p>Advanced controls to protect your children online.</bd-p>
|
|
120
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
121
|
+
</bd-card-item>
|
|
122
|
+
</bd-card-section>
|
|
123
|
+
`,
|
|
124
|
+
parameters: { docs: { description: { story: 'Cards with CTA button in the bottom-left via `slot="cta"`.' } } }
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export const WithCTAUnevenContent = {
|
|
128
|
+
name : 'With CTA — Uneven Content (alignment test)',
|
|
129
|
+
render: () => html`
|
|
130
|
+
<bd-card-section title="Features">
|
|
131
|
+
<bd-card-item title="AI Protection">
|
|
132
|
+
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
133
|
+
<bd-p>Powered by machine learning and behavioral analysis to stop threats before they reach you. Our AI engine learns from billions of threat signals every day.</bd-p>
|
|
134
|
+
<bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
|
|
135
|
+
</bd-card-item>
|
|
136
|
+
<bd-card-item title="Multi-layer Security — Advanced Protection Suite">
|
|
137
|
+
<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
|
|
138
|
+
<bd-p>Stop any attack.</bd-p>
|
|
139
|
+
<bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
|
|
140
|
+
</bd-card-item>
|
|
141
|
+
<bd-card-item title="VPN">
|
|
142
|
+
<bd-machine-learning-icon slot="icon" width="32" height="32" color="#006DFF"></bd-machine-learning-icon>
|
|
143
|
+
<bd-p>Unlimited encrypted VPN traffic for all your devices, anywhere in the world, at any time.</bd-p>
|
|
144
|
+
<bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
|
|
145
|
+
</bd-card-item>
|
|
146
|
+
<bd-card-item title="Parental Controls">
|
|
147
|
+
<bd-analysis-icon slot="icon" width="32" height="32" color="#006DFF"></bd-analysis-icon>
|
|
148
|
+
<bd-p>Advanced controls to protect your children online and monitor their activity.</bd-p>
|
|
149
|
+
<bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
|
|
150
|
+
</bd-card-item>
|
|
151
|
+
</bd-card-section>
|
|
152
|
+
`,
|
|
153
|
+
parameters: { docs: { description: { story: 'Cards with uneven title and content lengths — tests row alignment equalization. CTA buttons should always align at the same vertical position.' } } }
|
|
91
154
|
};
|
|
92
155
|
|
|
93
156
|
export const NoSectionTitle = {
|
|
@@ -112,7 +175,7 @@ export const NoSectionTitle = {
|
|
|
112
175
|
</bd-card-item>
|
|
113
176
|
</bd-card-section>
|
|
114
177
|
`,
|
|
115
|
-
parameters: { docs: { description: { story: 'Section without
|
|
178
|
+
parameters: { docs: { description: { story: 'Section without title prop.' } } }
|
|
116
179
|
};
|
|
117
180
|
|
|
118
181
|
export const CenteredAlignment = {
|
|
@@ -137,7 +200,7 @@ export const CenteredAlignment = {
|
|
|
137
200
|
</bd-card-item>
|
|
138
201
|
</bd-card-section>
|
|
139
202
|
`,
|
|
140
|
-
parameters: { docs: { description: { story: '`align="center"` applied to all items
|
|
203
|
+
parameters: { docs: { description: { story: '`align="center"` applied to all items.' } } }
|
|
141
204
|
};
|
|
142
205
|
|
|
143
206
|
export const MixedAlignment = {
|
|
@@ -154,7 +217,7 @@ export const MixedAlignment = {
|
|
|
154
217
|
</bd-card-item>
|
|
155
218
|
</bd-card-section>
|
|
156
219
|
`,
|
|
157
|
-
parameters: { docs: { description: { story: 'Two items
|
|
220
|
+
parameters: { docs: { description: { story: 'Two items with different alignment values.' } } }
|
|
158
221
|
};
|
|
159
222
|
|
|
160
223
|
export const NoIcon = {
|
|
@@ -175,7 +238,7 @@ export const NoIcon = {
|
|
|
175
238
|
</bd-card-item>
|
|
176
239
|
</bd-card-section>
|
|
177
240
|
`,
|
|
178
|
-
parameters: { docs: { description: { story: 'Items without
|
|
241
|
+
parameters: { docs: { description: { story: 'Items without icon.' } } }
|
|
179
242
|
};
|
|
180
243
|
|
|
181
244
|
export const NoSlottedContent = {
|
|
@@ -196,11 +259,11 @@ export const NoSlottedContent = {
|
|
|
196
259
|
</bd-card-item>
|
|
197
260
|
</bd-card-section>
|
|
198
261
|
`,
|
|
199
|
-
parameters: { docs: { description: { story: 'Items with only
|
|
262
|
+
parameters: { docs: { description: { story: 'Items with only icon and title.' } } }
|
|
200
263
|
};
|
|
201
264
|
|
|
202
265
|
export const TitleOnly = {
|
|
203
|
-
name : 'Title Only
|
|
266
|
+
name : 'Title Only',
|
|
204
267
|
render: () => html`
|
|
205
268
|
<bd-card-section title="Features">
|
|
206
269
|
<bd-card-item title="AI Protection"></bd-card-item>
|
|
@@ -208,7 +271,7 @@ export const TitleOnly = {
|
|
|
208
271
|
<bd-card-item title="Parental Controls"></bd-card-item>
|
|
209
272
|
</bd-card-section>
|
|
210
273
|
`,
|
|
211
|
-
parameters: { docs: { description: { story: 'Minimal cards with only a title
|
|
274
|
+
parameters: { docs: { description: { story: 'Minimal cards with only a title.' } } }
|
|
212
275
|
};
|
|
213
276
|
|
|
214
277
|
export const RichContent = {
|
|
@@ -220,15 +283,16 @@ export const RichContent = {
|
|
|
220
283
|
<bd-p>Antivirus & Anti-malware</bd-p>
|
|
221
284
|
<bd-p>VPN (200+ servers)</bd-p>
|
|
222
285
|
<bd-p>Password Manager</bd-p>
|
|
286
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">See all features</bd-button-link>
|
|
223
287
|
</bd-card-item>
|
|
224
288
|
<bd-card-item title="Supported Platforms">
|
|
225
289
|
<bd-arrow-up-icon slot="icon" width="32" height="32" color="#006DFF"></bd-arrow-up-icon>
|
|
226
290
|
<bd-p>Windows, macOS, Android, iOS</bd-p>
|
|
227
|
-
<
|
|
291
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">View all platforms</bd-button-link>
|
|
228
292
|
</bd-card-item>
|
|
229
293
|
</bd-card-section>
|
|
230
294
|
`,
|
|
231
|
-
parameters: { docs: { description: { story: 'Rich
|
|
295
|
+
parameters: { docs: { description: { story: 'Rich content with multiple bd-p elements and CTA buttons.' } } }
|
|
232
296
|
};
|
|
233
297
|
|
|
234
298
|
export const SingleItem = {
|
|
@@ -238,12 +302,64 @@ export const SingleItem = {
|
|
|
238
302
|
<bd-card-item title="AI Protection">
|
|
239
303
|
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
240
304
|
<bd-p>Machine learning-powered protection.</bd-p>
|
|
305
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
241
306
|
</bd-card-item>
|
|
242
307
|
</bd-card-section>
|
|
243
308
|
`,
|
|
244
|
-
parameters: { docs: { description: { story: 'Edge case: only one card item
|
|
309
|
+
parameters: { docs: { description: { story: 'Edge case: only one card item.' } } }
|
|
310
|
+
};
|
|
311
|
+
export const WithImages = {
|
|
312
|
+
name : 'With Images (large + small)',
|
|
313
|
+
render: () => html`
|
|
314
|
+
<bd-card-section title="Our Products">
|
|
315
|
+
<bd-card-item title="Total Security">
|
|
316
|
+
<img slot="icon" src="/assets/tabs-img1.png" alt="Total Security" />
|
|
317
|
+
<bd-p>Complete protection for all your devices with advanced threat detection and real-time security updates.</bd-p>
|
|
318
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
319
|
+
</bd-card-item>
|
|
320
|
+
<bd-card-item title="Internet Security">
|
|
321
|
+
<img slot="icon" src="/assets/tabs-img2.png" alt="Internet Security" />
|
|
322
|
+
<bd-p>Stay safe online.</bd-p>
|
|
323
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
324
|
+
</bd-card-item>
|
|
325
|
+
<bd-card-item title="Antivirus Plus">
|
|
326
|
+
<img slot="icon" src="/assets/tabs-img3.png" alt="Antivirus Plus" />
|
|
327
|
+
<bd-p>Essential protection for your Windows PC with real-time antivirus and anti-phishing.</bd-p>
|
|
328
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
329
|
+
</bd-card-item>
|
|
330
|
+
</bd-card-section>
|
|
331
|
+
`,
|
|
332
|
+
parameters: { docs: { description: { story: 'Cards with large images via `slot="icon"` — max-width/max-height 120px applied automatically.' } } }
|
|
245
333
|
};
|
|
246
334
|
|
|
335
|
+
export const MixedIconsAndImages = {
|
|
336
|
+
name : 'Mixed — Icons and Images',
|
|
337
|
+
render: () => html`
|
|
338
|
+
<bd-card-section title="Mixed Media">
|
|
339
|
+
<bd-card-item title="AI Protection">
|
|
340
|
+
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
341
|
+
<bd-p>Powered by machine learning and behavioral analysis.</bd-p>
|
|
342
|
+
<bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
|
|
343
|
+
</bd-card-item>
|
|
344
|
+
<bd-card-item title="Total Security">
|
|
345
|
+
<img slot="icon" src="/assets/tabs-img1.png" alt="Total Security" />
|
|
346
|
+
<bd-p>Complete protection for all your devices.</bd-p>
|
|
347
|
+
<bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
|
|
348
|
+
</bd-card-item>
|
|
349
|
+
<bd-card-item title="VPN Included">
|
|
350
|
+
<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
|
|
351
|
+
<bd-p>Unlimited encrypted VPN traffic for all your devices, anywhere.</bd-p>
|
|
352
|
+
<bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
|
|
353
|
+
</bd-card-item>
|
|
354
|
+
<bd-card-item title="Internet Security">
|
|
355
|
+
<img slot="icon" src="/assets/tabs-img2.png" alt="Internet Security" />
|
|
356
|
+
<bd-p>Stay safe online with advanced threat detection.</bd-p>
|
|
357
|
+
<bd-button-link slot="cta" href="#" kind="danger" size="sm">Get started</bd-button-link>
|
|
358
|
+
</bd-card-item>
|
|
359
|
+
</bd-card-section>
|
|
360
|
+
`,
|
|
361
|
+
parameters: { docs: { description: { story: 'Mix of SVG icons and large images in the same grid — tests consistent icon row height equalization.' } } }
|
|
362
|
+
};
|
|
247
363
|
export const Playground = {
|
|
248
364
|
name: '🛝 Playground',
|
|
249
365
|
args: {
|
|
@@ -256,12 +372,14 @@ export const Playground = {
|
|
|
256
372
|
<bd-card-item title="${args.itemTitle}" align="${args.align}">
|
|
257
373
|
<bd-individual-icon slot="icon" width="32" height="32" color="#006DFF"></bd-individual-icon>
|
|
258
374
|
<bd-p>Powered by machine learning and behavioral analysis.</bd-p>
|
|
375
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
259
376
|
</bd-card-item>
|
|
260
377
|
<bd-card-item title="VPN Included" align="${args.align}">
|
|
261
378
|
<bd-globe-icon slot="icon" width="32" height="32" color="#006DFF"></bd-globe-icon>
|
|
262
379
|
<bd-p>Unlimited encrypted VPN traffic.</bd-p>
|
|
380
|
+
<bd-button-link slot="cta" href="#" kind="primary" size="sm">Learn more</bd-button-link>
|
|
263
381
|
</bd-card-item>
|
|
264
382
|
</bd-card-section>
|
|
265
383
|
`,
|
|
266
|
-
parameters: { docs: { description: { story: 'Interactive playground.
|
|
384
|
+
parameters: { docs: { description: { story: 'Interactive playground.' } } }
|
|
267
385
|
};
|