@repobit/dex-system-design 0.23.113 → 0.23.115

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 CHANGED
@@ -3,6 +3,20 @@
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.115](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.23.114...@repobit/dex-system-design@0.23.115) (2026-08-07)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **DEX-1014:** video-player component
11
+
12
+
13
+ ## [0.23.114](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.23.113...@repobit/dex-system-design@0.23.114) (2026-08-07)
14
+
15
+ ### Bug Fixes
16
+
17
+ * **DEX-1014:** new version for features tab
18
+
19
+
6
20
  ## [0.23.113](https://github.com/bitdefender/dex-core/compare/@repobit/dex-system-design@0.23.112...@repobit/dex-system-design@0.23.113) (2026-08-06)
7
21
 
8
22
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@repobit/dex-system-design",
3
- "version": "0.23.113",
3
+ "version": "0.23.115",
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.11",
78
- "@repobit/dex-store-elements": "2.0.16",
77
+ "@repobit/dex-store": "1.6.13",
78
+ "@repobit/dex-store-elements": "2.0.18",
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": "c02545cd221c54bfa4abf96490f01786b7a54e8b"
95
+ "gitHead": "40caed2cbcd80d281839f6e39d2bb4acc47a0806"
96
96
  }
@@ -39,28 +39,18 @@ export default css`
39
39
  justify-content: center;
40
40
  }
41
41
 
42
- .bd-features-tab-image {
43
- width: 100%;
44
- max-width: 410px;
45
- height: auto;
46
- border-radius: var(--radius-lg, 16px);
47
- object-fit: cover;
48
- display: block;
42
+ ::slotted([slot="heading"]) {
43
+ margin: 0;
49
44
  }
50
45
 
51
- ::slotted([slot="image"]) {
46
+ ::slotted([slot="media"]) {
52
47
  width: 100%;
53
48
  max-width: 520px;
54
49
  height: auto;
55
50
  border-radius: var(--radius-lg, 16px);
56
- object-fit: cover;
57
51
  display: block;
58
52
  }
59
53
 
60
- ::slotted([slot="heading"]) {
61
- margin: 0;
62
- }
63
-
64
54
  @keyframes bd-fade-slide-right {
65
55
  from {
66
56
  opacity: 0;
@@ -87,11 +77,7 @@ export default css`
87
77
  text-align: center;
88
78
  }
89
79
 
90
- .bd-features-tab-image {
91
- max-width: 100%;
92
- }
93
-
94
- ::slotted([slot="image"]) {
80
+ ::slotted([slot="media"]) {
95
81
  max-width: 100%;
96
82
  }
97
83
  }
@@ -3,12 +3,11 @@ import { tokens } from "../../tokens/tokens.js";
3
3
  import "../button/button.js";
4
4
  import "../heading/heading.js";
5
5
  import "../paragraph/paragraph.js";
6
+ import "../video-player/video-player.js";
6
7
  import featuresTabCSS from "./features-tab.css.js";
7
8
 
8
9
  class BdFeaturesTab extends LitElement {
9
10
  static properties = {
10
- imageSrc: { type: String, attribute: "image-src" },
11
- imageAlt: { type: String, attribute: "image-alt" },
12
11
  ctaLabel: { type: String, attribute: "cta-label" },
13
12
  ctaHref : { type: String, attribute: "cta-href" },
14
13
  ctaKind : { type: String, attribute: "cta-kind" },
@@ -20,8 +19,6 @@ class BdFeaturesTab extends LitElement {
20
19
 
21
20
  constructor() {
22
21
  super();
23
- this.imageSrc = "";
24
- this.imageAlt = "";
25
22
  this.ctaLabel = "";
26
23
  this.ctaHref = "#";
27
24
  this.ctaKind = "danger";
@@ -30,8 +27,8 @@ class BdFeaturesTab extends LitElement {
30
27
  }
31
28
 
32
29
  render() {
33
- const hasCtaSlot = this.querySelector("[slot='cta']");
34
- const hasImgSlot = this.querySelector("[slot='image']");
30
+ const hasCtaSlot = this.querySelector("[slot='cta']");
31
+ const hasMediaSlot = this.querySelector("[slot='media']");
35
32
 
36
33
  const leftContent = html`
37
34
  <div class="bd-features-tab-left">
@@ -58,16 +55,9 @@ class BdFeaturesTab extends LitElement {
58
55
 
59
56
  const rightContent = html`
60
57
  <div class="bd-features-tab-right">
61
- ${hasImgSlot
62
- ? html`<slot name="image"></slot>`
63
- : this.imageSrc
64
- ? html`<img
65
- src="${this.imageSrc}"
66
- alt="${this.imageAlt}"
67
- class="bd-features-tab-image"
68
- loading="lazy"
69
- />`
70
- : ""}
58
+ ${hasMediaSlot
59
+ ? html`<slot name="media"></slot>`
60
+ : ""}
71
61
  </div>
72
62
  `;
73
63
 
@@ -3,6 +3,7 @@ import '../button/button.js';
3
3
  import '../heading/heading.js';
4
4
  import '../paragraph/paragraph.js';
5
5
  import '../tabs/tabs.js';
6
+ import '../video-player/video-player.js';
6
7
  import './features-tab.js';
7
8
 
8
9
  export default {
@@ -13,431 +14,426 @@ export default {
13
14
  docs : {
14
15
  description: {
15
16
  component: `
16
- **FeaturesTab** — layout component cu conținut stânga (heading + text + CTA) și imagine dreapta.
17
- Poate fi folosit standalone sau în interiorul unui \`bd-tab-panel\` din \`bd-tabs\`.
18
-
19
- ### Usage standalone
20
- \`\`\`html
21
- <bd-features-tab
22
- image-src="/assets/image.png"
23
- image-alt="Description"
24
- cta-label="Learn more"
25
- cta-href="#"
26
- cta-kind="danger"
27
- >
28
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">Your heading.</bd-h>
29
- <div slot="content">
30
- <bd-p kind="regular">Your content here.</bd-p>
31
- </div>
32
- </bd-features-tab>
33
- \`\`\`
34
-
35
- ### Usage cu bd-tabs
36
- \`\`\`html
37
- <bd-tabs title="..." highlight-text="..." subtitle="...">
38
- <bd-tab-panel title="Admin">
39
- <bd-features-tab image-src="/assets/image.png" cta-label="Stay worry free" cta-href="#">
40
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">Your heading.</bd-h>
41
- <div slot="content">
42
- <bd-p kind="regular">Your content here.</bd-p>
43
- </div>
44
- </bd-features-tab>
45
- </bd-tab-panel>
46
- </bd-tabs>
47
- \`\`\`
17
+ **FeaturesTab** — layout component cu conținut stânga și media dreapta.
18
+ Toate elementele sunt sloturi pentru consistență maximă.
19
+
20
+ ### Slot-uri
21
+ | Slot | Descriere |
22
+ |---|---|
23
+ | \`heading\` | Heading custom |
24
+ | \`content\` | Conținut text |
25
+ | \`media\` | Orice media — \`<img>\`, \`<picture>\`, \`<iframe>\`, \`<video>\`, \`<bd-video-player>\` |
26
+ | \`cta\` | Buton custom — suprascrie \`cta-label\` |
48
27
 
49
28
  ### Atribute
50
29
  | Atribut | Tip | Default | Descriere |
51
30
  |---|---|---|---|
52
- | \`image-src\` | String | — | Imaginea (fallback când nu există slot="image") |
53
- | \`image-alt\` | String | — | Alt text imagine |
54
31
  | \`cta-label\` | String | — | Text buton CTA |
55
32
  | \`cta-href\` | String | \`#\` | Href buton CTA |
56
33
  | \`cta-kind\` | String | \`danger\` | Kind buton |
57
34
  | \`cta-size\` | String | \`md\` | Size buton |
58
- | \`reverse\` | Boolean | \`false\` | Imagine stânga, conținut dreapta |
59
-
60
- ### Slot-uri
61
- | Slot | Descriere |
62
- |---|---|
63
- | \`heading\` | Heading custom |
64
- | \`content\` | Conținut text |
65
- | \`image\` | Imagine custom — suprascrie \`image-src\` |
66
- | \`cta\` | Buton custom — suprascrie \`cta-label\` |
35
+ | \`reverse\` | Boolean | \`false\` | Media stânga, conținut dreapta |
67
36
  `
68
37
  }
69
38
  }
70
39
  },
71
40
  argTypes: {
72
- imageSrc: {
73
- control : 'text',
74
- description: 'URL imaginea',
75
- table : { type: { summary: 'string' }, category: 'FeaturesTab' }
76
- },
77
- ctaLabel: {
78
- control : 'text',
79
- description: 'Text buton CTA',
80
- table : { type: { summary: 'string' }, category: 'FeaturesTab' }
41
+ reverse: {
42
+ control : 'boolean',
43
+ description: 'Media stânga, conținut dreapta',
44
+ table : { type: { summary: 'boolean' }, defaultValue: { summary: 'false' } }
81
45
  },
82
46
  ctaKind: {
83
47
  control : { type: 'select' },
84
48
  options : ['primary', 'danger', 'secondary', 'outline'],
85
49
  description: 'Kind buton CTA',
86
- table : { type: { summary: 'string' }, defaultValue: { summary: 'danger' }, category: 'FeaturesTab' }
87
- },
88
- reverse: {
89
- control : 'boolean',
90
- description: 'Inversează layout — imagine stânga, conținut dreapta',
91
- table : { type: { summary: 'boolean' }, defaultValue: { summary: 'false' }, category: 'FeaturesTab' }
50
+ table : { type: { summary: 'string' }, defaultValue: { summary: 'danger' } }
92
51
  }
93
52
  }
94
53
  };
95
54
 
96
- const panels = [
97
- {
98
- tab : 'Admin',
99
- imageSrc: '/assets/tabs-img1.png',
100
- imageAlt: 'Admin using laptop',
101
- heading : 'Keep your loved ones protected.',
102
- content : 'As the Subscription Manager, you can oversee and adjust online safety through an intuitive dashboard. Effortlessly manage settings, monitor real-time alerts, and maintain control without compromising simplicity or security.',
103
- ctaLabel: 'Stay worry free',
104
- ctaHref : '#admin'
105
- },
106
- {
107
- tab : 'Adult',
108
- imageSrc: '/assets/tabs-img2.png',
109
- imageAlt: 'Adult protection',
110
- heading : 'Stay safe online, every day.',
111
- content : 'Advanced privacy and security tools tailored for adults. Browse safely, protect your identity, and keep your data private at all times.',
112
- ctaLabel: 'Learn more',
113
- ctaHref : '#adult'
114
- },
115
- {
116
- tab : 'Teen',
117
- imageSrc: '/assets/tabs-img3.png',
118
- imageAlt: 'Teen protection',
119
- heading : 'Safe browsing for teens.',
120
- content : 'Give teens the freedom to explore online while keeping them protected from inappropriate content, cyberbullying, and online threats.',
121
- ctaLabel: 'Explore features',
122
- ctaHref : '#teen'
123
- },
124
- {
125
- tab : 'Child',
126
- imageSrc: '/assets/tabs-img3.png',
127
- imageAlt: 'Child protection',
128
- heading : 'A safe digital world for children.',
129
- content : 'Comprehensive parental controls and content filtering ensure your child has a safe, age-appropriate online experience every time they connect.',
130
- ctaLabel: 'Protect your child',
131
- ctaHref : '#child'
132
- }
133
- ];
55
+ const heading = html`
56
+ <bd-h as="h4" slot="heading" color="var(--color-blue-500)">
57
+ Keep your loved ones protected.
58
+ </bd-h>
59
+ `;
134
60
 
135
- // ─── Stories standalone ────────────────────────────────────────────────────────
61
+ const content = html`
62
+ <div slot="content">
63
+ <bd-p kind="regular">
64
+ As the Subscription Manager, you can oversee and adjust online safety
65
+ through an intuitive dashboard. Effortlessly manage settings, monitor
66
+ real-time alerts, and maintain control without compromising simplicity
67
+ or security.
68
+ </bd-p>
69
+ </div>
70
+ `;
71
+
72
+ const mediaStyle = "width:100%;max-width:520px;height:auto;border-radius:var(--radius-lg,16px);object-fit:cover;display:block;";
136
73
 
137
- export const Default = {
138
- name : 'Standalone — Default (imagine dreapta)',
74
+ // ─── Imagine ──────────────────────────────────────────────────────────────────
75
+
76
+ export const WithImage = {
77
+ name : 'Cu imagine',
139
78
  render: () => html`
140
- <bd-features-tab
141
- image-src="${panels[0].imageSrc}"
142
- image-alt="${panels[0].imageAlt}"
143
- cta-label="${panels[0].ctaLabel}"
144
- cta-href="${panels[0].ctaHref}"
145
- cta-kind="danger"
146
- >
147
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${panels[0].heading}</bd-h>
148
- <div slot="content">
149
- <bd-p kind="regular">${panels[0].content}</bd-p>
150
- </div>
79
+ <bd-features-tab cta-label="Stay worry free" cta-href="#" cta-kind="danger">
80
+ ${heading}
81
+ ${content}
82
+ <img slot="media" src="/assets/tabs-img1.png" alt="Admin using laptop" loading="lazy" style="${mediaStyle}" />
151
83
  </bd-features-tab>
152
84
  `,
153
- parameters: { docs: { description: { story: 'Standalone, fără bd-tabs — conținut stânga, imagine dreapta (default).' } } }
85
+ parameters: { docs: { description: { story: 'Imagine simplă via `slot="media"`.' } } }
154
86
  };
155
87
 
156
- export const StandaloneReverse = {
157
- name : 'Standalone — Reverse (imagine stânga)',
88
+ export const WithImageReverse = {
89
+ name : 'Cu imagine — Reverse',
158
90
  render: () => html`
159
- <bd-features-tab
160
- image-src="${panels[0].imageSrc}"
161
- image-alt="${panels[0].imageAlt}"
162
- cta-label="${panels[0].ctaLabel}"
163
- cta-href="${panels[0].ctaHref}"
164
- cta-kind="danger"
165
- reverse
166
- >
167
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${panels[0].heading}</bd-h>
168
- <div slot="content">
169
- <bd-p kind="regular">${panels[0].content}</bd-p>
170
- </div>
91
+ <bd-features-tab cta-label="Stay worry free" cta-href="#" cta-kind="danger" reverse>
92
+ ${heading}
93
+ ${content}
94
+ <img slot="media" src="/assets/tabs-img1.png" alt="Admin using laptop" loading="lazy" style="${mediaStyle}" />
171
95
  </bd-features-tab>
172
96
  `,
173
- parameters: { docs: { description: { story: 'Standalone cu `reverse` — imagine stânga, conținut dreapta.' } } }
97
+ parameters: { docs: { description: { story: 'Imagine cu layout reverse.' } } }
174
98
  };
175
99
 
176
- export const StandaloneAlternating = {
177
- name : 'Standalone — Alternating Layout',
100
+ // ─── Picture ──────────────────────────────────────────────────────────────────
101
+
102
+ export const WithPicture = {
103
+ name : 'Cu picture element',
178
104
  render: () => html`
179
- <div style="display:flex;flex-direction:column;gap:var(--spacing-64);">
180
- ${panels.map((p, i) => html`
181
- <bd-features-tab
182
- image-src="${p.imageSrc}"
183
- image-alt="${p.imageAlt}"
184
- cta-label="${p.ctaLabel}"
185
- cta-href="${p.ctaHref}"
186
- cta-kind="danger"
187
- ?reverse=${i % 2 !== 0}
188
- >
189
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${p.heading}</bd-h>
190
- <div slot="content">
191
- <bd-p kind="regular">${p.content}</bd-p>
192
- </div>
193
- </bd-features-tab>
194
- `)}
195
- </div>
105
+ <bd-features-tab cta-label="Stay worry free" cta-href="#" cta-kind="danger">
106
+ ${heading}
107
+ ${content}
108
+ <picture slot="media" style="display:block;width:100%;max-width:520px;">
109
+ <source type="image/webp" srcset="/assets/tabs-img1.png?width=2000&format=webp&optimize=medium" media="(min-width: 600px)" />
110
+ <img src="/assets/tabs-img1.png" alt="Admin using laptop" loading="lazy" style="width:100%;height:auto;border-radius:var(--radius-lg,16px);object-fit:cover;display:block;" />
111
+ </picture>
112
+ </bd-features-tab>
196
113
  `,
197
- parameters: { docs: { description: { story: 'Layout alternant — par: imagine dreapta, impar: imagine stânga.' } } }
114
+ parameters: { docs: { description: { story: '`<picture>` element cu srcset webp via `slot="media"`.' } } }
198
115
  };
199
116
 
200
- export const StandaloneWithImageSlot = {
201
- name : 'Standalone — Cu slot="image"',
117
+ // ─── YouTube embed direct ─────────────────────────────────────────────────────
118
+
119
+ export const WithYouTube = {
120
+ name : 'Cu YouTube embed',
202
121
  render: () => html`
203
- <bd-features-tab
204
- cta-label="${panels[0].ctaLabel}"
205
- cta-href="${panels[0].ctaHref}"
206
- cta-kind="danger"
207
- >
208
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${panels[0].heading}</bd-h>
209
- <div slot="content">
210
- <bd-p kind="regular">${panels[0].content}</bd-p>
122
+ <bd-features-tab cta-label="Learn more" cta-href="#" cta-kind="danger">
123
+ ${heading}
124
+ ${content}
125
+ <div slot="media" style="position:relative;width:100%;max-width:520px;padding-bottom:56.25%;border-radius:var(--radius-lg,16px);overflow:hidden;">
126
+ <iframe
127
+ style="position:absolute;top:0;left:0;width:100%;height:100%;border:none;"
128
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
129
+ title="YouTube video player"
130
+ frameborder="0"
131
+ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
132
+ referrerpolicy="strict-origin-when-cross-origin"
133
+ allowfullscreen
134
+ ></iframe>
211
135
  </div>
212
- <picture slot="image" style="display:block;">
213
- <source type="image/webp" srcset="${panels[0].imageSrc}?width=2000&format=webp&optimize=medium" media="(min-width: 600px)" />
214
- <source type="image/webp" srcset="${panels[0].imageSrc}?width=750&format=webp&optimize=medium" />
215
- <img
216
- src="${panels[0].imageSrc}"
217
- alt="${panels[0].imageAlt}"
218
- loading="lazy"
219
- style="width:100%;max-width:520px;height:auto;border-radius:var(--radius-lg,16px);object-fit:cover;display:block;"
220
- />
221
- </picture>
222
136
  </bd-features-tab>
223
137
  `,
224
- parameters: { docs: { description: { story: 'Standalone cu slot="image" — element picture cu srcset webp.' } } }
138
+ parameters: { docs: { description: { story: 'YouTube iframe embed direct via `slot="media"`.' } } }
225
139
  };
226
140
 
227
- export const StandaloneNoCTA = {
228
- name : 'Standalone — Fără CTA',
141
+ // ─── YouTube cu thumbnail ─────────────────────────────────────────────────────
142
+
143
+ export const WithYouTubeThumbnail = {
144
+ name : 'Cu YouTube + thumbnail (bd-video-player)',
229
145
  render: () => html`
230
- <bd-features-tab
231
- image-src="${panels[1].imageSrc}"
232
- image-alt="${panels[1].imageAlt}"
233
- >
234
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${panels[1].heading}</bd-h>
235
- <div slot="content">
236
- <bd-p kind="regular">${panels[1].content}</bd-p>
237
- </div>
146
+ <bd-features-tab cta-label="Learn more" cta-href="#" cta-kind="danger">
147
+ ${heading}
148
+ ${content}
149
+ <bd-video-player
150
+ slot="media"
151
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
152
+ thumb="/assets/tabs-img1.png"
153
+ thumb-alt="Click to play video"
154
+ style="width:100%;max-width:520px;"
155
+ ></bd-video-player>
238
156
  </bd-features-tab>
239
157
  `,
240
- parameters: { docs: { description: { story: 'Standalone fără buton CTA.' } } }
158
+ parameters: { docs: { description: { story: 'YouTube cu thumbnail via `bd-video-player` — click pe imagine deschide player-ul.' } } }
241
159
  };
242
160
 
243
- export const StandaloneMobileView = {
244
- name : 'Standalone — Mobile View (375px)',
245
- parameters: { viewport: { defaultViewport: 'mobile1' } },
246
- render : () => html`
247
- <bd-features-tab
248
- image-src="${panels[0].imageSrc}"
249
- image-alt="${panels[0].imageAlt}"
250
- cta-label="${panels[0].ctaLabel}"
251
- cta-href="${panels[0].ctaHref}"
252
- cta-kind="danger"
253
- >
254
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${panels[0].heading}</bd-h>
255
- <div slot="content">
256
- <bd-p kind="regular">${panels[0].content}</bd-p>
257
- </div>
161
+ export const WithYouTubeThumbnailReverse = {
162
+ name : 'Cu YouTube + thumbnail — Reverse',
163
+ render: () => html`
164
+ <bd-features-tab cta-label="Learn more" cta-href="#" cta-kind="danger" reverse>
165
+ ${heading}
166
+ ${content}
167
+ <bd-video-player
168
+ slot="media"
169
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
170
+ thumb="/assets/tabs-img2.png"
171
+ thumb-alt="Click to play video"
172
+ style="width:100%;max-width:520px;"
173
+ ></bd-video-player>
258
174
  </bd-features-tab>
259
- `
175
+ `,
176
+ parameters: { docs: { description: { story: 'YouTube cu thumbnail și layout reverse.' } } }
260
177
  };
261
178
 
262
- // ─── Stories cu bd-tabs ────────────────────────────────────────────────────────
179
+ // ─── Video nativ ──────────────────────────────────────────────────────────────
263
180
 
264
- export const WithTabs = {
265
- name : 'Cu bd-tabs — Default',
181
+ export const WithVideoNative = {
182
+ name : 'Cu video nativ (.webm)',
266
183
  render: () => html`
267
- <bd-tabs
268
- title="Customized online protection for each family member – Smart, Private & Safe"
269
- highlight-text="family member"
270
- subtitle="Your family is unique and so should be your online security."
271
- >
272
- ${panels.map(p => html`
273
- <bd-tab-panel title="${p.tab}">
274
- <bd-features-tab
275
- image-src="${p.imageSrc}"
276
- image-alt="${p.imageAlt}"
277
- cta-label="${p.ctaLabel}"
278
- cta-href="${p.ctaHref}"
279
- cta-kind="danger"
280
- >
281
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${p.heading}</bd-h>
282
- <div slot="content">
283
- <bd-p kind="regular">${p.content}</bd-p>
284
- </div>
285
- </bd-features-tab>
286
- </bd-tab-panel>
287
- `)}
288
- </bd-tabs>
184
+ <bd-features-tab cta-label="Learn more" cta-href="#" cta-kind="danger">
185
+ ${heading}
186
+ ${content}
187
+ <video
188
+ slot="media"
189
+ src="https://www.bitdefender.com/content/dam/bitdefender/consumers/solutions/ultimate-small-business-security/Bitdefender_Final_1080p_V.webm"
190
+ controls
191
+ playsinline
192
+ style="width:100%;max-width:520px;height:auto;border-radius:var(--radius-lg,16px);display:block;"
193
+ ></video>
194
+ </bd-features-tab>
289
195
  `,
290
- parameters: { docs: { description: { story: 'bd-features-tab în bd-tabs — 4 tab-uri, conținut stânga, imagine dreapta.' } } }
196
+ parameters: { docs: { description: { story: 'Video nativ .webm direct via `slot="media"`.' } } }
291
197
  };
292
198
 
293
- export const WithTabsReverse = {
294
- name : 'Cu bd-tabs — Reverse',
199
+ // ─── Video nativ cu thumbnail ─────────────────────────────────────────────────
200
+
201
+ export const WithVideoThumbnail = {
202
+ name : 'Cu video nativ + thumbnail (bd-video-player)',
295
203
  render: () => html`
296
- <bd-tabs
297
- title="Customized online protection for each family member – Smart, Private & Safe"
298
- highlight-text="family member"
299
- subtitle="Your family is unique and so should be your online security."
300
- >
301
- ${panels.map(p => html`
302
- <bd-tab-panel title="${p.tab}">
303
- <bd-features-tab
304
- image-src="${p.imageSrc}"
305
- image-alt="${p.imageAlt}"
306
- cta-label="${p.ctaLabel}"
307
- cta-href="${p.ctaHref}"
308
- cta-kind="danger"
309
- reverse
310
- >
311
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${p.heading}</bd-h>
312
- <div slot="content">
313
- <bd-p kind="regular">${p.content}</bd-p>
314
- </div>
315
- </bd-features-tab>
316
- </bd-tab-panel>
317
- `)}
318
- </bd-tabs>
204
+ <bd-features-tab cta-label="Learn more" cta-href="#" cta-kind="danger">
205
+ ${heading}
206
+ ${content}
207
+ <bd-video-player
208
+ slot="media"
209
+ src="https://www.bitdefender.com/content/dam/bitdefender/consumers/solutions/ultimate-small-business-security/Bitdefender_Final_1080p_V.webm"
210
+ thumb="/assets/tabs-img2.png"
211
+ thumb-alt="Click to play video"
212
+ style="width:100%;max-width:520px;"
213
+ ></bd-video-player>
214
+ </bd-features-tab>
319
215
  `,
320
- parameters: { docs: { description: { story: 'bd-features-tab cu `reverse` în bd-tabs — imagine stânga, conținut dreapta.' } } }
216
+ parameters: { docs: { description: { story: 'Video nativ .webm cu thumbnail via `bd-video-player` — click pe imagine deschide player-ul cu autoplay.' } } }
321
217
  };
322
218
 
323
- export const WithTabsImageSlot = {
324
- name : 'Cu bd-tabs — slot="image"',
219
+ export const WithVideoThumbnailReverse = {
220
+ name : 'Cu video nativ + thumbnail — Reverse',
325
221
  render: () => html`
326
- <bd-tabs
327
- title="Customized online protection for each family member – Smart, Private & Safe"
328
- highlight-text="family member"
329
- subtitle="Your family is unique and so should be your online security."
330
- >
331
- ${panels.map(p => html`
332
- <bd-tab-panel title="${p.tab}">
333
- <bd-features-tab
334
- cta-label="${p.ctaLabel}"
335
- cta-href="${p.ctaHref}"
336
- cta-kind="danger"
337
- >
338
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${p.heading}</bd-h>
339
- <div slot="content">
340
- <bd-p kind="regular">${p.content}</bd-p>
341
- </div>
342
- <picture slot="image" style="display:block;">
343
- <source type="image/webp" srcset="${p.imageSrc}?width=2000&format=webp&optimize=medium" media="(min-width: 600px)" />
344
- <source type="image/webp" srcset="${p.imageSrc}?width=750&format=webp&optimize=medium" />
345
- <img
346
- src="${p.imageSrc}"
347
- alt="${p.imageAlt}"
348
- loading="lazy"
349
- style="width:100%;max-width:520px;height:auto;border-radius:var(--radius-lg,16px);object-fit:cover;display:block;"
350
- />
351
- </picture>
352
- </bd-features-tab>
353
- </bd-tab-panel>
354
- `)}
355
- </bd-tabs>
222
+ <bd-features-tab cta-label="Learn more" cta-href="#" cta-kind="danger" reverse>
223
+ ${heading}
224
+ ${content}
225
+ <bd-video-player
226
+ slot="media"
227
+ src="https://www.bitdefender.com/content/dam/bitdefender/consumers/solutions/ultimate-small-business-security/Bitdefender_Final_1080p_V.webm"
228
+ thumb="/assets/tabs-img3.png"
229
+ thumb-alt="Click to play video"
230
+ style="width:100%;max-width:520px;"
231
+ ></bd-video-player>
232
+ </bd-features-tab>
356
233
  `,
357
- parameters: { docs: { description: { story: 'bd-features-tab cu slot="image" picture element în bd-tabs.' } } }
234
+ parameters: { docs: { description: { story: 'Video nativ cu thumbnail și layout reverse.' } } }
358
235
  };
359
236
 
360
- export const WithTabsBlueBg = {
361
- name : 'Cu bd-tabs — Blue Background',
237
+ // ─── Fără CTA ─────────────────────────────────────────────────────────────────
238
+
239
+ export const NoCTA = {
240
+ name : 'Fără CTA',
241
+ render: () => html`
242
+ <bd-features-tab>
243
+ ${heading}
244
+ ${content}
245
+ <img slot="media" src="/assets/tabs-img2.png" alt="Protection" loading="lazy" style="${mediaStyle}" />
246
+ </bd-features-tab>
247
+ `,
248
+ parameters: { docs: { description: { story: 'Fără buton CTA.' } } }
249
+ };
250
+
251
+ // ─── CTA custom ───────────────────────────────────────────────────────────────
252
+
253
+ export const WithCTASlot = {
254
+ name : 'Cu slot="cta" custom',
255
+ render: () => html`
256
+ <bd-features-tab>
257
+ ${heading}
258
+ ${content}
259
+ <img slot="media" src="/assets/tabs-img1.png" alt="Admin" loading="lazy" style="${mediaStyle}" />
260
+ <bd-button-link slot="cta" href="#" kind="primary" size="md">Custom CTA button</bd-button-link>
261
+ </bd-features-tab>
262
+ `,
263
+ parameters: { docs: { description: { story: 'Buton CTA custom via `slot="cta"`.' } } }
264
+ };
265
+
266
+ // ─── În bd-tabs ───────────────────────────────────────────────────────────────
267
+
268
+ export const WithTabs = {
269
+ name : 'Cu bd-tabs',
362
270
  render: () => html`
363
271
  <bd-tabs
364
- bg-blue
365
272
  title="Customized online protection for each family member – Smart, Private & Safe"
366
273
  highlight-text="family member"
367
274
  subtitle="Your family is unique and so should be your online security."
368
275
  >
369
- ${panels.map(p => html`
370
- <bd-tab-panel title="${p.tab}">
371
- <bd-features-tab
372
- image-src="${p.imageSrc}"
373
- image-alt="${p.imageAlt}"
374
- cta-label="${p.ctaLabel}"
375
- cta-href="${p.ctaHref}"
376
- cta-kind="danger"
377
- >
378
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${p.heading}</bd-h>
379
- <div slot="content">
380
- <bd-p kind="regular">${p.content}</bd-p>
381
- </div>
382
- </bd-features-tab>
383
- </bd-tab-panel>
384
- `)}
276
+ <bd-tab-panel title="Imagine">
277
+ <bd-features-tab cta-label="Stay worry free" cta-href="#" cta-kind="danger">
278
+ <bd-h as="h4" slot="heading" color="var(--color-blue-500)">Keep your loved ones protected.</bd-h>
279
+ <div slot="content">
280
+ <bd-p kind="regular">As the Subscription Manager, you can oversee and adjust online safety.</bd-p>
281
+ </div>
282
+ <img slot="media" src="/assets/tabs-img1.png" alt="Admin using laptop" loading="lazy" style="${mediaStyle}" />
283
+ </bd-features-tab>
284
+ </bd-tab-panel>
285
+
286
+ <bd-tab-panel title="YouTube">
287
+ <bd-features-tab cta-label="Learn more" cta-href="#" cta-kind="danger">
288
+ <bd-h as="h4" slot="heading" color="var(--color-blue-500)">Watch how it works.</bd-h>
289
+ <div slot="content">
290
+ <bd-p kind="regular">See Bitdefender in action with our video walkthrough.</bd-p>
291
+ </div>
292
+ <bd-video-player
293
+ slot="media"
294
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
295
+ thumb="/assets/tabs-img2.png"
296
+ thumb-alt="Click to play"
297
+ style="width:100%;max-width:520px;"
298
+ ></bd-video-player>
299
+ </bd-features-tab>
300
+ </bd-tab-panel>
301
+
302
+ <bd-tab-panel title="Video">
303
+ <bd-features-tab cta-label="Get started" cta-href="#" cta-kind="danger">
304
+ <bd-h as="h4" slot="heading" color="var(--color-blue-500)">See the full demo.</bd-h>
305
+ <div slot="content">
306
+ <bd-p kind="regular">Watch our full product demo and discover all features.</bd-p>
307
+ </div>
308
+ <bd-video-player
309
+ slot="media"
310
+ src="https://www.bitdefender.com/content/dam/bitdefender/consumers/solutions/ultimate-small-business-security/Bitdefender_Final_1080p_V.webm"
311
+ thumb="/assets/tabs-img3.png"
312
+ thumb-alt="Click to play"
313
+ style="width:100%;max-width:520px;"
314
+ ></bd-video-player>
315
+ </bd-features-tab>
316
+ </bd-tab-panel>
385
317
  </bd-tabs>
386
318
  `,
387
- parameters: { docs: { description: { story: 'bd-tabs cu `bg-blue` — fundal albastru deschis.' } } }
319
+ parameters: { docs: { description: { story: 'bd-features-tab în bd-tabs — imagine, YouTube cu thumbnail și video nativ cu thumbnail.' } } }
388
320
  };
389
321
 
390
- export const WithTabsMobile = {
391
- name : 'Cu bd-tabs — Mobile View (375px)',
322
+ // ─── Mobile ───────────────────────────────────────────────────────────────────
323
+
324
+ export const MobileView = {
325
+ name : 'Mobile View (375px)',
392
326
  parameters: { viewport: { defaultViewport: 'mobile1' } },
393
327
  render : () => html`
394
- <bd-tabs
395
- title="Customized online protection for each family member"
396
- highlight-text="family member"
397
- subtitle="Your family is unique and so should be your online security."
398
- >
399
- ${panels.map(p => html`
400
- <bd-tab-panel title="${p.tab}">
401
- <bd-features-tab
402
- image-src="${p.imageSrc}"
403
- image-alt="${p.imageAlt}"
404
- cta-label="${p.ctaLabel}"
405
- cta-href="${p.ctaHref}"
406
- cta-kind="danger"
407
- >
408
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">${p.heading}</bd-h>
409
- <div slot="content">
410
- <bd-p kind="regular">${p.content}</bd-p>
411
- </div>
412
- </bd-features-tab>
413
- </bd-tab-panel>
414
- `)}
415
- </bd-tabs>
328
+ <bd-features-tab cta-label="Stay worry free" cta-href="#" cta-kind="danger">
329
+ ${heading}
330
+ ${content}
331
+ <img slot="media" src="/assets/tabs-img1.png" alt="Admin using laptop" loading="lazy" style="${mediaStyle}" />
332
+ </bd-features-tab>
416
333
  `
417
334
  };
418
335
 
336
+ // ─── Playground ───────────────────────────────────────────────────────────────
337
+
419
338
  export const Playground = {
420
- name: '🛝 Playground',
339
+ name: 'Playground',
421
340
  args: {
422
- imageSrc: '/assets/tabs-img1.png',
423
- ctaLabel: 'Stay worry free',
424
- ctaKind : 'danger',
425
- reverse : false
341
+ reverse: false,
342
+ ctaKind: 'danger'
426
343
  },
427
344
  render: (args) => html`
428
345
  <bd-features-tab
429
- image-src="${args.imageSrc}"
430
- image-alt="Demo image"
431
- cta-label="${args.ctaLabel}"
346
+ cta-label="Stay worry free"
432
347
  cta-href="#"
433
348
  cta-kind="${args.ctaKind}"
434
349
  ?reverse=${args.reverse}
435
350
  >
436
- <bd-h as="h4" slot="heading" color="var(--color-blue-500)">Keep your loved ones protected.</bd-h>
437
- <div slot="content">
438
- <bd-p kind="regular">As the Subscription Manager, you can oversee and adjust online safety through an intuitive dashboard.</bd-p>
439
- </div>
351
+ ${heading}
352
+ ${content}
353
+ <img slot="media" src="/assets/tabs-img1.png" alt="Demo image" loading="lazy" style="${mediaStyle}" />
440
354
  </bd-features-tab>
441
355
  `,
442
- parameters: { docs: { description: { story: 'Playground interactiv — ajustează image-src, cta-label, cta-kind și reverse din Controls.' } } }
356
+ parameters: { docs: { description: { story: 'Playground interactiv.' } } }
357
+ };
358
+
359
+ export const WithFeaturesTabVideo = {
360
+ name : 'Cu bd-features-tab + video',
361
+ render: () => html`
362
+ <bd-tabs
363
+ title="Customized online protection for each family member – Smart, Private & Safe"
364
+ highlight-text="family member"
365
+ subtitle="Your family is unique and so should be your online security."
366
+ >
367
+ <bd-tab-panel title="Admin">
368
+ <bd-features-tab cta-label="Stay worry free" cta-href="#" cta-kind="danger">
369
+ <bd-h as="h4" slot="heading" color="var(--color-blue-500)">Keep your loved ones protected.</bd-h>
370
+ <div slot="content">
371
+ <bd-p kind="regular">As the Subscription Manager, you can oversee and adjust online safety through an intuitive dashboard.</bd-p>
372
+ </div>
373
+ <img
374
+ slot="media"
375
+ src="/assets/tabs-img1.png"
376
+ alt="Admin using laptop"
377
+ loading="lazy"
378
+ style="width:100%;max-width:520px;height:auto;border-radius:var(--radius-lg,16px);object-fit:cover;display:block;"
379
+ />
380
+ </bd-features-tab>
381
+ </bd-tab-panel>
382
+
383
+ <bd-tab-panel title="YouTube">
384
+ <bd-features-tab cta-label="Learn more" cta-href="#" cta-kind="danger">
385
+ <bd-h as="h4" slot="heading" color="var(--color-blue-500)">Watch how it works.</bd-h>
386
+ <div slot="content">
387
+ <bd-p kind="regular">See Bitdefender in action with our full video walkthrough.</bd-p>
388
+ </div>
389
+ <bd-video-player
390
+ slot="media"
391
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
392
+ thumb="/assets/tabs-img2.png"
393
+ thumb-alt="Click to play YouTube video"
394
+ style="width:100%;max-width:520px;"
395
+ ></bd-video-player>
396
+ </bd-features-tab>
397
+ </bd-tab-panel>
398
+
399
+ <bd-tab-panel title="Video">
400
+ <bd-features-tab cta-label="Get started" cta-href="#" cta-kind="danger">
401
+ <bd-h as="h4" slot="heading" color="var(--color-blue-500)">See the full demo.</bd-h>
402
+ <div slot="content">
403
+ <bd-p kind="regular">Watch our full product demo and discover all the features available.</bd-p>
404
+ </div>
405
+ <bd-video-player
406
+ slot="media"
407
+ src="https://www.bitdefender.com/content/dam/bitdefender/consumers/solutions/ultimate-small-business-security/Bitdefender_Final_1080p_V.webm"
408
+ thumb="/assets/tabs-img3.png"
409
+ thumb-alt="Click to play video"
410
+ style="width:100%;max-width:520px;"
411
+ ></bd-video-player>
412
+ </bd-features-tab>
413
+ </bd-tab-panel>
414
+
415
+ <bd-tab-panel title="Teen">
416
+ <bd-features-tab cta-label="Explore features" cta-href="#" cta-kind="danger">
417
+ <bd-h as="h4" slot="heading" color="var(--color-blue-500)">Safe browsing for teens.</bd-h>
418
+ <div slot="content">
419
+ <bd-p kind="regular">Give teens the freedom to explore online while keeping them protected from threats.</bd-p>
420
+ </div>
421
+ <img
422
+ slot="media"
423
+ src="/assets/tabs-img3.png"
424
+ alt="Teen protection"
425
+ loading="lazy"
426
+ style="width:100%;max-width:520px;height:auto;border-radius:var(--radius-lg,16px);object-fit:cover;display:block;"
427
+ />
428
+ </bd-features-tab>
429
+ </bd-tab-panel>
430
+ </bd-tabs>
431
+ `,
432
+ parameters: {
433
+ docs: {
434
+ description: {
435
+ story: 'bd-tabs cu bd-features-tab — mix de imagine, YouTube cu thumbnail și video nativ cu thumbnail.'
436
+ }
437
+ }
438
+ }
443
439
  };
@@ -0,0 +1,95 @@
1
+ import { css } from "lit";
2
+
3
+ export default css`
4
+ :host {
5
+ display: block;
6
+ width: 100%;
7
+ }
8
+
9
+ .bd-video-thumb {
10
+ position: relative;
11
+ display: block;
12
+ width: 100%;
13
+ padding: 0;
14
+ border: none;
15
+ background: none;
16
+ cursor: pointer;
17
+ border-radius: var(--radius-lg, 16px);
18
+ overflow: hidden;
19
+ }
20
+
21
+ .bd-video-thumb img {
22
+ width: 100%;
23
+ height: auto;
24
+ display: block;
25
+ border-radius: var(--radius-lg, 16px);
26
+ transition: transform 300ms ease;
27
+ }
28
+
29
+ .bd-video-thumb:hover img {
30
+ transform: scale(1.02);
31
+ }
32
+
33
+ .bd-video-play-btn {
34
+ position: absolute;
35
+ top: 50%;
36
+ left: 50%;
37
+ transform: translate(-50%, -50%);
38
+ width: 64px;
39
+ height: 64px;
40
+ pointer-events: none;
41
+ filter: drop-shadow(0 4px 12px rgba(0,0,0,0.3));
42
+ transition: transform 300ms ease;
43
+ }
44
+
45
+ .bd-video-thumb:hover .bd-video-play-btn {
46
+ transform: translate(-50%, -50%) scale(1.1);
47
+ }
48
+
49
+ .bd-video-play-btn svg {
50
+ width: 64px;
51
+ height: 64px;
52
+ }
53
+
54
+ .bd-video-player {
55
+ position: relative;
56
+ width: 100%;
57
+ padding-bottom: 56.25%;
58
+ border-radius: var(--radius-lg, 16px);
59
+ overflow: hidden;
60
+ background: var(--color-neutral-900);
61
+ }
62
+
63
+ .bd-video-player iframe,
64
+ .bd-video-player video {
65
+ position: absolute;
66
+ top: 0;
67
+ left: 0;
68
+ width: 100%;
69
+ height: 100%;
70
+ border: none;
71
+ }
72
+
73
+ .bd-video-close {
74
+ position: absolute;
75
+ top: var(--spacing-8);
76
+ right: var(--spacing-8);
77
+ width: 32px;
78
+ height: 32px;
79
+ border-radius: 50%;
80
+ border: none;
81
+ background: rgba(0,0,0,0.6);
82
+ color: white;
83
+ font-size: 16px;
84
+ cursor: pointer;
85
+ display: flex;
86
+ align-items: center;
87
+ justify-content: center;
88
+ z-index: 10;
89
+ transition: background 150ms ease;
90
+ }
91
+
92
+ .bd-video-close:hover {
93
+ background: rgba(0,0,0,0.9);
94
+ }
95
+ `;
@@ -0,0 +1,93 @@
1
+ import { LitElement, html } from "lit";
2
+ import { tokens } from "../../tokens/tokens.js";
3
+ import videoPlayerCSS from "./video-player.css.js";
4
+
5
+ class BdVideoPlayer extends LitElement {
6
+ static properties = {
7
+ src : { type: String },
8
+ thumb : { type: String },
9
+ thumbAlt: { type: String, attribute: "thumb-alt" },
10
+ _open : { state: true }
11
+ };
12
+
13
+ static styles = [tokens, videoPlayerCSS];
14
+
15
+ constructor() {
16
+ super();
17
+ this.src = "";
18
+ this.thumb = "";
19
+ this.thumbAlt = "";
20
+ this._open = false;
21
+ }
22
+
23
+ _isYoutube() {
24
+ return this.src.includes("youtube.com") || this.src.includes("youtu.be");
25
+ }
26
+
27
+ _openVideo() {
28
+ this._open = true;
29
+ }
30
+
31
+ _closeVideo() {
32
+ this._open = false;
33
+ }
34
+
35
+ render() {
36
+ if (!this.thumb || this._open) {
37
+ return html`
38
+ <div class="bd-video-player">
39
+ ${this._isYoutube()
40
+ ? html`
41
+ <iframe
42
+ src="${this.src}${this.thumb ? '?autoplay=1' : ''}"
43
+ title="Video player"
44
+ frameborder="0"
45
+ allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
46
+ referrerpolicy="strict-origin-when-cross-origin"
47
+ allowfullscreen
48
+ ></iframe>
49
+ `
50
+ : html`
51
+ <video
52
+ src="${this.src}"
53
+ autoplay
54
+ controls
55
+ playsinline
56
+ ></video>
57
+ `}
58
+ ${this.thumb
59
+ ? html`
60
+ <button
61
+ class="bd-video-close"
62
+ @click=${this._closeVideo}
63
+ aria-label="Close video"
64
+ >✕</button>
65
+ `
66
+ : ""}
67
+ </div>
68
+ `;
69
+ }
70
+
71
+ return html`
72
+ <button
73
+ class="bd-video-thumb"
74
+ @click=${this._openVideo}
75
+ aria-label="Play video"
76
+ >
77
+ <img
78
+ src="${this.thumb}"
79
+ alt="${this.thumbAlt || 'Video preview'}"
80
+ loading="lazy"
81
+ />
82
+ <span class="bd-video-play-btn" aria-hidden="true">
83
+ <svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
84
+ <circle cx="32" cy="32" r="32" fill="white" fill-opacity="0.9"/>
85
+ <path d="M26 20L46 32L26 44V20Z" fill="#006DFF"/>
86
+ </svg>
87
+ </span>
88
+ </button>
89
+ `;
90
+ }
91
+ }
92
+
93
+ customElements.define("bd-video-player", BdVideoPlayer);
@@ -0,0 +1,188 @@
1
+ // src/components/video-player/video-player.stories.js
2
+ import { html } from 'lit';
3
+ import './video-player.js';
4
+
5
+ export default {
6
+ title : 'Components/VideoPlayer',
7
+ tags : ['autodocs'],
8
+ parameters: {
9
+ docs: {
10
+ description: {
11
+ component: `
12
+ **VideoPlayer** is a component for embedding videos with a thumbnail preview.
13
+
14
+ - Click the thumbnail to open the video
15
+ - Supports YouTube and direct video sources
16
+ - Close button to return to thumbnail
17
+
18
+ ### Usage
19
+ \`\`\`html
20
+ <bd-video-player
21
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
22
+ thumb="/assets/tabs-img1.png"
23
+ thumb-alt="Video preview"
24
+ ></bd-video-player>
25
+ \`\`\`
26
+
27
+ ### Props
28
+ | Prop | Type | Default | Description |
29
+ |------|------|---------|-------------|
30
+ | \`src\` | String | \`''\` | Video source URL (YouTube embed or direct video) |
31
+ | \`thumb\` | String | \`''\` | Thumbnail image URL |
32
+ | \`thumb-alt\` | String | \`''\` | Alt text for the thumbnail image |
33
+ `
34
+ }
35
+ }
36
+ },
37
+ argTypes: {
38
+ src: {
39
+ control : 'text',
40
+ description: 'Video source URL (YouTube embed or direct video)',
41
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Content' }
42
+ },
43
+ thumb: {
44
+ control : 'text',
45
+ description: 'Thumbnail image URL',
46
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Content' }
47
+ },
48
+ thumbAlt: {
49
+ control : 'text',
50
+ description: 'Alt text for the thumbnail image',
51
+ table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Content' }
52
+ }
53
+ }
54
+ };
55
+
56
+ // ─── Default ─────────────────────────────────────────────────────────────
57
+
58
+ export const DefaultVideo = {
59
+ name : 'Default (YouTube)',
60
+ render: () => html`
61
+ <div style="max-width: 800px; margin: 0 auto;">
62
+ <bd-video-player
63
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
64
+ thumb="/assets/tabs-img1.png"
65
+ thumb-alt="Video preview"
66
+ ></bd-video-player>
67
+ </div>
68
+ `,
69
+ parameters: { docs: { description: { story: 'Default YouTube video with thumbnail.' } } }
70
+ };
71
+
72
+ // ─── With Custom Thumbnail ─────────────────────────────────────────────
73
+
74
+ export const CustomThumbnailVideo = {
75
+ name : 'Custom Thumbnail',
76
+ render: () => html`
77
+ <div style="max-width: 800px; margin: 0 auto;">
78
+ <bd-video-player
79
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
80
+ thumb="/assets/tabs-img2.png"
81
+ thumb-alt="Custom video preview"
82
+ ></bd-video-player>
83
+ </div>
84
+ `,
85
+ parameters: { docs: { description: { story: 'Video with a custom thumbnail image.' } } }
86
+ };
87
+
88
+ // ─── No Thumbnail ────────────────────────────────────────────────────────
89
+
90
+ export const VideoNoThumbnail = {
91
+ name : 'No Thumbnail (direct play)',
92
+ render: () => html`
93
+ <div style="max-width: 800px; margin: 0 auto;">
94
+ <bd-video-player
95
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
96
+ ></bd-video-player>
97
+ </div>
98
+ `,
99
+ parameters: { docs: { description: { story: 'Video without thumbnail — plays directly.' } } }
100
+ };
101
+
102
+ // ─── Direct Video Source ──────────────────────────────────────────────────────────────
103
+
104
+ export const DirectVideoSource = {
105
+ name : 'Direct Video (webm)',
106
+ render: () => html`
107
+ <div style="max-width: 800px; margin: 0 auto;">
108
+ <bd-video-player
109
+ src="https://www.bitdefender.com/content/dam/bitdefender/consumers/solutions/ultimate-small-business-security/Bitdefender_Final_1080p_V.webm"
110
+ thumb="/assets/tabs-img3.png"
111
+ thumb-alt="Video preview"
112
+ ></bd-video-player>
113
+ </div>
114
+ `,
115
+ parameters: { docs: { description: { story: 'Direct webm video source with thumbnail.' } } }
116
+ };
117
+
118
+ // ─── YouTube with Autoplay ─────────────────────────────────────────────
119
+
120
+ export const YouTubeAutoplayVideo = {
121
+ name : 'YouTube with Autoplay',
122
+ render: () => html`
123
+ <div style="max-width: 800px; margin: 0 auto;">
124
+ <bd-video-player
125
+ src="https://www.youtube.com/embed/zal9Mt02ErM?autoplay=1"
126
+ thumb="/assets/tabs-img2.png"
127
+ thumb-alt="Video preview"
128
+ ></bd-video-player>
129
+ </div>
130
+ `,
131
+ parameters: { docs: { description: { story: 'YouTube video with autoplay parameter in URL.' } } }
132
+ };
133
+
134
+ // ─── With Different Thumbnails ─────────────────────────────────────────
135
+
136
+ export const DifferentThumbnails = {
137
+ name : 'Different Thumbnails',
138
+ render: () => html`
139
+ <div style="display:grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 24px; max-width: 1200px; margin: 0 auto; padding: 20px;">
140
+ <div>
141
+ <h4 style="margin-bottom: 8px;">Thumbnail 1</h4>
142
+ <bd-video-player
143
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
144
+ thumb="/assets/tabs-img1.png"
145
+ thumb-alt="Video 1"
146
+ ></bd-video-player>
147
+ </div>
148
+ <div>
149
+ <h4 style="margin-bottom: 8px;">Thumbnail 2</h4>
150
+ <bd-video-player
151
+ src="https://www.youtube.com/embed/zal9Mt02ErM"
152
+ thumb="/assets/tabs-img2.png"
153
+ thumb-alt="Video 2"
154
+ ></bd-video-player>
155
+ </div>
156
+ <div>
157
+ <h4 style="margin-bottom: 8px;">Thumbnail 3</h4>
158
+ <bd-video-player
159
+ src="https://www.bitdefender.com/content/dam/bitdefender/consumers/solutions/ultimate-small-business-security/Bitdefender_Final_1080p_V.webm"
160
+ thumb="/assets/tabs-img3.png"
161
+ thumb-alt="Video 3"
162
+ ></bd-video-player>
163
+ </div>
164
+ </div>
165
+ `,
166
+ parameters: { docs: { description: { story: 'Different thumbnails side by side.' } } }
167
+ };
168
+
169
+ // ─── Playground ──────────────────────────────────────────────────────────
170
+
171
+ export const VideoPlayerPlayground = {
172
+ name: '🛝 Playground',
173
+ args: {
174
+ src : 'https://www.youtube.com/embed/zal9Mt02ErM',
175
+ thumb : '/assets/tabs-img1.png',
176
+ thumbAlt: 'Video preview'
177
+ },
178
+ render: (args) => html`
179
+ <div style="max-width: 800px; margin: 0 auto;">
180
+ <bd-video-player
181
+ src="${args.src}"
182
+ thumb="${args.thumb}"
183
+ thumb-alt="${args.thumbAlt}"
184
+ ></bd-video-player>
185
+ </div>
186
+ `,
187
+ parameters: { docs: { description: { story: 'Interactive playground for bd-video-player.' } } }
188
+ };