@repobit/dex-system-design 0.22.12 → 0.23.1
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 +32 -0
- package/package.json +3 -2
- package/src/components/Button/button.stories.js +292 -120
- package/src/components/accordion/accordion-bg.css.js +7 -2
- package/src/components/accordion/accordion-bg.stories.js +268 -449
- package/src/components/accordion/accordion.stories.js +259 -265
- package/src/components/anchor/anchor.stories.js +160 -159
- package/src/components/awards/awards-icon.js +44 -0
- package/src/components/awards/awards.css.js +328 -0
- package/src/components/awards/awards.js +224 -0
- package/src/components/awards/awards.stories.js +447 -0
- package/src/components/back/back.stories.js +100 -375
- package/src/components/badge/badge.stories.js +241 -129
- package/src/components/breadcrumb/breadcrumb.stories.js +218 -219
- package/src/components/cards/card.stories.js +174 -622
- package/src/components/carousel/carousel.stories.js +196 -225
- package/src/components/checkbox/checkbox.stories.js +136 -51
- package/src/components/compare/compare.css.js +237 -0
- package/src/components/compare/compare.js +253 -0
- package/src/components/compare/compare.stories.js +372 -0
- package/src/components/display/display.stories.js +91 -297
- package/src/components/divider/divider.stories.js +160 -342
- package/src/components/footer/footer.stories.js +177 -402
- package/src/components/header/header.stories.js +130 -338
- package/src/components/heading/heading.js +8 -5
- package/src/components/heading/heading.stories.js +162 -471
- package/src/components/highlight/highlight.stories.js +153 -38
- package/src/components/image/image.stories.js +135 -563
- package/src/components/input/custom-form.stories.js +761 -224
- package/src/components/link/link.js +29 -12
- package/src/components/link/link.stories.js +130 -468
- package/src/components/modal/modal.stories.js +174 -28
- package/src/components/paragraph/paragraph.css.js +10 -1
- package/src/components/paragraph/paragraph.stories.js +85 -410
- package/src/components/picture/picture.stories.js +147 -561
- package/src/components/radio/radio.stories.js +230 -81
- package/src/components/tabs/tabs.stories.js +126 -10
- package/src/components/termsOfUse/terms.stories.js +223 -8
- package/src/tokens/tokens.js +1 -0
|
@@ -1,620 +1,206 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
|
-
import '../heading/heading.js';
|
|
3
|
-
import '../paragraph/paragraph.js';
|
|
4
2
|
import './picture.js';
|
|
5
3
|
|
|
6
4
|
export default {
|
|
7
|
-
title
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
title : 'Components/Picture',
|
|
6
|
+
tags : ['autodocs'],
|
|
7
|
+
parameters: {
|
|
8
|
+
docs: {
|
|
9
|
+
description: {
|
|
10
|
+
component: `
|
|
11
|
+
**BdPicture** is a Lit responsive picture component that wraps \`<picture>\` with multiple \`<source>\` elements and a fallback \`<img>\`.
|
|
12
|
+
|
|
13
|
+
### Usage
|
|
14
|
+
\`\`\`html
|
|
15
|
+
<bd-picture
|
|
16
|
+
fallback-src="/assets/product.png"
|
|
17
|
+
alt="Product screenshot"
|
|
18
|
+
width="800"
|
|
19
|
+
height="600"
|
|
20
|
+
fit="cover"
|
|
21
|
+
radius="md"
|
|
22
|
+
loading="lazy"
|
|
23
|
+
.sources="${[
|
|
24
|
+
{ type: 'image/webp', srcset: '/assets/product.webp', media: '(min-width: 600px)' },
|
|
25
|
+
{ type: 'image/png', srcset: '/assets/product.png' }
|
|
26
|
+
]}"
|
|
27
|
+
></bd-picture>
|
|
28
|
+
\`\`\`
|
|
29
|
+
|
|
30
|
+
### Sources Array
|
|
31
|
+
Each source object supports:
|
|
32
|
+
- \`type\` — MIME type (e.g. \`"image/webp"\`)
|
|
33
|
+
- \`srcset\` — srcset value
|
|
34
|
+
- \`media\` — optional media query
|
|
35
|
+
- \`sizes\` — optional sizes attribute
|
|
36
|
+
|
|
37
|
+
### CSS Classes Applied
|
|
38
|
+
| Prop | Class Pattern |
|
|
39
|
+
|---|---|
|
|
40
|
+
| \`fit\` | \`fit-{value}\` |
|
|
41
|
+
| \`radius\` | \`radius-{value}\` |
|
|
42
|
+
`
|
|
17
43
|
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
argTypes: {
|
|
47
|
+
fallbackSrc: {
|
|
48
|
+
control : 'text',
|
|
49
|
+
description: 'Fallback `<img>` src used when no `<source>` matches',
|
|
50
|
+
table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Content' }
|
|
18
51
|
},
|
|
19
52
|
alt: {
|
|
20
53
|
control : 'text',
|
|
21
|
-
description: '
|
|
22
|
-
table : {
|
|
23
|
-
type : { summary: 'string' },
|
|
24
|
-
defaultValue: { summary: '' }
|
|
25
|
-
}
|
|
54
|
+
description: 'Alt text for the fallback `<img>`',
|
|
55
|
+
table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Content' }
|
|
26
56
|
},
|
|
27
|
-
|
|
28
|
-
control : '
|
|
29
|
-
description: '
|
|
30
|
-
table : {
|
|
31
|
-
type : { summary: 'string' },
|
|
32
|
-
defaultValue: { summary: '' }
|
|
33
|
-
}
|
|
57
|
+
sources: {
|
|
58
|
+
control : 'object',
|
|
59
|
+
description: 'Array of source objects: `{ type, srcset, media?, sizes? }`',
|
|
60
|
+
table : { type: { summary: 'Array<{type, srcset, media?, sizes?}>' }, defaultValue: { summary: '[]' }, category: 'Content' }
|
|
34
61
|
},
|
|
35
62
|
width: {
|
|
36
63
|
control : 'number',
|
|
37
|
-
description: '
|
|
38
|
-
table : {
|
|
39
|
-
type : { summary: 'number' },
|
|
40
|
-
defaultValue: { summary: 'null' }
|
|
41
|
-
}
|
|
64
|
+
description: 'Intrinsic width of the fallback image',
|
|
65
|
+
table : { type: { summary: 'number' }, defaultValue: { summary: 'null' }, category: 'Dimensions' }
|
|
42
66
|
},
|
|
43
67
|
height: {
|
|
44
68
|
control : 'number',
|
|
45
|
-
description: '
|
|
46
|
-
table : {
|
|
47
|
-
type : { summary: 'number' },
|
|
48
|
-
defaultValue: { summary: 'null' }
|
|
49
|
-
}
|
|
69
|
+
description: 'Intrinsic height of the fallback image',
|
|
70
|
+
table : { type: { summary: 'number' }, defaultValue: { summary: 'null' }, category: 'Dimensions' }
|
|
50
71
|
},
|
|
51
72
|
loading: {
|
|
52
73
|
control : { type: 'select' },
|
|
53
74
|
options : ['lazy', 'eager'],
|
|
54
|
-
description: '
|
|
55
|
-
table : {
|
|
56
|
-
type : { summary: 'string' },
|
|
57
|
-
defaultValue: { summary: 'lazy' }
|
|
58
|
-
}
|
|
75
|
+
description: 'Native browser loading strategy',
|
|
76
|
+
table : { type: { summary: "'lazy'|'eager'" }, defaultValue: { summary: 'lazy' }, category: 'Performance' }
|
|
59
77
|
},
|
|
60
78
|
fit: {
|
|
61
79
|
control : { type: 'select' },
|
|
62
80
|
options : ['cover', 'contain', 'fill', 'none', 'scale-down'],
|
|
63
|
-
description: '
|
|
64
|
-
table : {
|
|
65
|
-
type : { summary: 'string' },
|
|
66
|
-
defaultValue: { summary: 'cover' }
|
|
67
|
-
}
|
|
81
|
+
description: 'Object-fit class applied as `fit-{value}`',
|
|
82
|
+
table : { type: { summary: 'string' }, defaultValue: { summary: 'cover' }, category: 'Appearance' }
|
|
68
83
|
},
|
|
69
84
|
radius: {
|
|
70
85
|
control : { type: 'select' },
|
|
71
|
-
options : ['none', 'sm', 'md', 'lg', 'full'],
|
|
72
|
-
description: 'Border radius
|
|
73
|
-
table : {
|
|
74
|
-
type : { summary: 'string' },
|
|
75
|
-
defaultValue: { summary: 'none' }
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
parameters: {
|
|
80
|
-
docs: {
|
|
81
|
-
description: {
|
|
82
|
-
component: 'A responsive picture component that supports multiple image formats, breakpoints, and modern web features. Provides optimal performance and accessibility with fallback support for older browsers.'
|
|
83
|
-
}
|
|
86
|
+
options : ['none', 'sm', 'md', 'lg', 'xl', 'full'],
|
|
87
|
+
description: 'Border radius class applied as `radius-{value}`',
|
|
88
|
+
table : { type: { summary: 'string' }, defaultValue: { summary: 'none' }, category: 'Appearance' }
|
|
84
89
|
}
|
|
85
90
|
}
|
|
86
91
|
};
|
|
87
92
|
|
|
88
|
-
const
|
|
93
|
+
const placeholder = 'https://via.placeholder.com/800x450';
|
|
94
|
+
|
|
95
|
+
const defaultSources = [
|
|
96
|
+
{ type: 'image/webp', srcset: placeholder + '?format=webp', media: '(min-width: 600px)' },
|
|
97
|
+
{ type: 'image/png', srcset: placeholder }
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
const defaultArgs = {
|
|
101
|
+
fallbackSrc: placeholder, alt : 'Product image',
|
|
102
|
+
sources : defaultSources, width : 800, height : 450,
|
|
103
|
+
loading : 'lazy', fit : 'cover', radius : 'none'
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const render = (args) => html`
|
|
89
107
|
<bd-picture
|
|
90
|
-
.sources="${args.sources}"
|
|
91
|
-
alt="${args.alt}"
|
|
92
108
|
fallback-src="${args.fallbackSrc}"
|
|
109
|
+
alt="${args.alt}"
|
|
93
110
|
width="${args.width}"
|
|
94
111
|
height="${args.height}"
|
|
95
112
|
loading="${args.loading}"
|
|
96
113
|
fit="${args.fit}"
|
|
97
114
|
radius="${args.radius}"
|
|
115
|
+
.sources="${args.sources}"
|
|
98
116
|
></bd-picture>
|
|
99
117
|
`;
|
|
100
118
|
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
export const Default = Template.bind({});
|
|
104
|
-
Default.args = {
|
|
105
|
-
sources: [
|
|
106
|
-
{
|
|
107
|
-
type : 'image/webp',
|
|
108
|
-
srcset: '/assets/bd-header-us-2000.webp',
|
|
109
|
-
media : '(min-width: 1200px)'
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
type : 'image/webp',
|
|
113
|
-
srcset: '/assets/bd-header-us-1000.webp',
|
|
114
|
-
media : '(min-width: 768px)'
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
type : 'image/webp',
|
|
118
|
-
srcset: '/assets/bd-header-us-750.webp'
|
|
119
|
-
}
|
|
120
|
-
],
|
|
121
|
-
alt : 'Bitdefender Security Illustration showing comprehensive protection features',
|
|
122
|
-
fallbackSrc: '/assets/bd-header-us.jpg',
|
|
123
|
-
width : 750,
|
|
124
|
-
height : 500,
|
|
125
|
-
loading : 'lazy',
|
|
126
|
-
fit : 'cover',
|
|
127
|
-
radius : 'none'
|
|
128
|
-
};
|
|
129
|
-
Default.parameters = {
|
|
130
|
-
docs: {
|
|
131
|
-
description: {
|
|
132
|
-
story: 'Default picture component with responsive WebP sources and JPEG fallback. Optimized for performance with lazy loading and proper aspect ratio.'
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
export const AllSourceTypes = () => html`
|
|
138
|
-
<div style="display: flex; flex-direction: column; gap: 3rem; max-width: 1000px; margin: 0 auto; padding: 2rem;">
|
|
139
|
-
<bd-h as="h2" style="margin-bottom: 1rem;">Picture Source Types and Strategies</bd-h>
|
|
140
|
-
<bd-p kind="regular" style="margin-bottom: 2rem;">
|
|
141
|
-
The picture element supports multiple image formats and responsive breakpoints for optimal performance and visual quality across different devices and browsers.
|
|
142
|
-
</bd-p>
|
|
143
|
-
|
|
144
|
-
<div style="border: 2px solid #e2e8f0; padding: 2rem; border-radius: 8px;">
|
|
145
|
-
<bd-h as="h3" style="color: #3b82f6; margin-bottom: 1rem;">WebP with JPEG Fallback</bd-h>
|
|
146
|
-
<bd-picture
|
|
147
|
-
.sources="${[
|
|
148
|
-
{
|
|
149
|
-
type : 'image/webp',
|
|
150
|
-
srcset: '/assets/bd-header-us-2000.webp',
|
|
151
|
-
media : '(min-width: 1200px)'
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
type : 'image/webp',
|
|
155
|
-
srcset: '/assets/bd-header-us-1000.webp',
|
|
156
|
-
media : '(min-width: 768px)'
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
type : 'image/webp',
|
|
160
|
-
srcset: '/assets/bd-header-us-750.webp'
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
type : 'image/jpeg',
|
|
164
|
-
srcset: '/assets/bd-header-us-2000.jpg',
|
|
165
|
-
media : '(min-width: 1200px)'
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
type : 'image/jpeg',
|
|
169
|
-
srcset: '/assets/bd-header-us-1000.jpg',
|
|
170
|
-
media : '(min-width: 768px)'
|
|
171
|
-
}
|
|
172
|
-
]}"
|
|
173
|
-
alt="Bitdefender Security with WebP and JPEG fallback support"
|
|
174
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
175
|
-
width="800"
|
|
176
|
-
height="500"
|
|
177
|
-
loading="lazy"
|
|
178
|
-
fit="cover"
|
|
179
|
-
radius="md"
|
|
180
|
-
></bd-picture>
|
|
181
|
-
<bd-p kind="regular" style="margin-top: 1.5rem;">
|
|
182
|
-
<strong>Strategy:</strong> Modern WebP format for supported browsers with JPEG fallback for compatibility<br>
|
|
183
|
-
<strong>Benefits:</strong> Better compression + wide browser support<br>
|
|
184
|
-
<strong>Use case:</strong> Production websites requiring optimal performance
|
|
185
|
-
</bd-p>
|
|
186
|
-
<bd-p kind="small" style="color: #64748b; margin-top: 1rem;">
|
|
187
|
-
💡 <strong>Best practice:</strong> Always provide JPEG fallback for maximum browser compatibility
|
|
188
|
-
</bd-p>
|
|
189
|
-
</div>
|
|
190
|
-
|
|
191
|
-
<div style="border: 2px solid #e2e8f0; padding: 2rem; border-radius: 8px;">
|
|
192
|
-
<bd-h as="h3" style="color: #3b82f6; margin-bottom: 1rem;">Multiple Breakpoint Strategy</bd-h>
|
|
193
|
-
<bd-picture
|
|
194
|
-
.sources="${[
|
|
195
|
-
{
|
|
196
|
-
type : 'image/webp',
|
|
197
|
-
srcset: '/assets/bd-header-us-2000.webp',
|
|
198
|
-
media : '(min-width: 1440px)'
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
type : 'image/webp',
|
|
202
|
-
srcset: '/assets/bd-header-us-1200.webp',
|
|
203
|
-
media : '(min-width: 1024px)'
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
type : 'image/webp',
|
|
207
|
-
srcset: '/assets/bd-header-us-800.webp',
|
|
208
|
-
media : '(min-width: 768px)'
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
type : 'image/webp',
|
|
212
|
-
srcset: '/assets/bd-header-us-600.webp',
|
|
213
|
-
media : '(min-width: 480px)'
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
type : 'image/webp',
|
|
217
|
-
srcset: '/assets/bd-header-us-400.webp'
|
|
218
|
-
}
|
|
219
|
-
]}"
|
|
220
|
-
alt="Bitdefender Security optimized for multiple screen sizes"
|
|
221
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
222
|
-
width="800"
|
|
223
|
-
height="500"
|
|
224
|
-
loading="lazy"
|
|
225
|
-
fit="cover"
|
|
226
|
-
radius="md"
|
|
227
|
-
></bd-picture>
|
|
228
|
-
<bd-p kind="regular" style="margin-top: 1.5rem;">
|
|
229
|
-
<strong>Breakpoints:</strong> 1440px+ (desktop), 1024px+ (laptop), 768px+ (tablet), 480px+ (large mobile), default (mobile)<br>
|
|
230
|
-
<strong>Benefits:</strong> Optimal image size for each device, faster loading<br>
|
|
231
|
-
<strong>Use case:</strong> High-traffic websites with diverse device usage
|
|
232
|
-
</bd-p>
|
|
233
|
-
<bd-p kind="small" style="color: #64748b; margin-top: 1rem;">
|
|
234
|
-
📱 <strong>Performance:</strong> Mobile users download smaller images, improving page speed
|
|
235
|
-
</bd-p>
|
|
236
|
-
</div>
|
|
237
|
-
|
|
238
|
-
<div style="border: 2px solid #e2e8f0; padding: 2rem; border-radius: 8px;">
|
|
239
|
-
<bd-h as="h3" style="color: #3b82f6; margin-bottom: 1rem;">Single Source Simplicity</bd-h>
|
|
240
|
-
<bd-picture
|
|
241
|
-
.sources="${[
|
|
242
|
-
{
|
|
243
|
-
type : 'image/jpeg',
|
|
244
|
-
srcset: '/assets/bd-header-us.jpg'
|
|
245
|
-
}
|
|
246
|
-
]}"
|
|
247
|
-
alt="Simple Bitdefender Security image implementation"
|
|
248
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
249
|
-
width="600"
|
|
250
|
-
height="400"
|
|
251
|
-
loading="lazy"
|
|
252
|
-
fit="cover"
|
|
253
|
-
radius="lg"
|
|
254
|
-
></bd-picture>
|
|
255
|
-
<bd-p kind="regular" style="margin-top: 1.5rem;">
|
|
256
|
-
<strong>Strategy:</strong> Single image source without responsive variants<br>
|
|
257
|
-
<strong>Benefits:</strong> Simpler implementation, fewer image files to manage<br>
|
|
258
|
-
<strong>Use case:</strong> Internal applications, prototypes, simple websites
|
|
259
|
-
</bd-p>
|
|
260
|
-
<bd-p kind="small" style="color: #64748b; margin-top: 1rem;">
|
|
261
|
-
⚡ <strong>Quick setup:</strong> Perfect for MVPs and projects with limited image requirements
|
|
262
|
-
</bd-p>
|
|
263
|
-
</div>
|
|
264
|
-
</div>
|
|
265
|
-
`;
|
|
266
|
-
AllSourceTypes.parameters = {
|
|
267
|
-
docs: {
|
|
268
|
-
description: {
|
|
269
|
-
story: 'Comprehensive demonstration of different picture source strategies including WebP with JPEG fallback, multiple breakpoint optimization, and simple single-source implementations with detailed use case recommendations.'
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
};
|
|
119
|
+
// ─── Stories ───────────────────────────────────────────────────────────────
|
|
273
120
|
|
|
274
|
-
export const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
{
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
],
|
|
282
|
-
alt : 'Simple Bitdefender Security Image showing protection interface',
|
|
283
|
-
fallbackSrc: '/assets/bd-header-us.jpg',
|
|
284
|
-
width : 600,
|
|
285
|
-
height : 400,
|
|
286
|
-
loading : 'eager',
|
|
287
|
-
fit : 'cover',
|
|
288
|
-
radius : 'none'
|
|
289
|
-
};
|
|
290
|
-
SimplePicture.parameters = {
|
|
291
|
-
docs: {
|
|
292
|
-
description: {
|
|
293
|
-
story: 'Simple picture implementation with single JPEG source. Ideal for prototypes, internal applications, or situations where multiple image formats and breakpoints are not required.'
|
|
294
|
-
}
|
|
295
|
-
}
|
|
121
|
+
export const Default = {
|
|
122
|
+
name : 'Default',
|
|
123
|
+
render: () => html`
|
|
124
|
+
<bd-picture fallback-src="${placeholder}" alt="Product image" width="800" height="450" .sources="${defaultSources}"></bd-picture>
|
|
125
|
+
`,
|
|
126
|
+
parameters: { docs: { description: { story: 'Default picture with WebP and PNG sources and a PNG fallback.' } } }
|
|
296
127
|
};
|
|
297
128
|
|
|
298
|
-
export const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
{
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
media : '(min-width: 1440px)'
|
|
305
|
-
},
|
|
306
|
-
{
|
|
307
|
-
type : 'image/webp',
|
|
308
|
-
srcset: '/assets/bd-header-us-1200.webp',
|
|
309
|
-
media : '(min-width: 1024px)'
|
|
310
|
-
},
|
|
311
|
-
{
|
|
312
|
-
type : 'image/webp',
|
|
313
|
-
srcset: '/assets/bd-header-us-800.webp',
|
|
314
|
-
media : '(min-width: 768px)'
|
|
315
|
-
},
|
|
316
|
-
{
|
|
317
|
-
type : 'image/webp',
|
|
318
|
-
srcset: '/assets/bd-header-us-400.webp'
|
|
319
|
-
}
|
|
320
|
-
],
|
|
321
|
-
alt : 'Advanced Bitdefender Security with AVIF and WebP formats',
|
|
322
|
-
fallbackSrc: '/assets/bd-header-us.jpg',
|
|
323
|
-
width : 800,
|
|
324
|
-
height : 500,
|
|
325
|
-
loading : 'lazy',
|
|
326
|
-
fit : 'cover',
|
|
327
|
-
radius : 'md'
|
|
328
|
-
};
|
|
329
|
-
AdvancedResponsive.parameters = {
|
|
330
|
-
docs: {
|
|
331
|
-
description: {
|
|
332
|
-
story: 'Advanced responsive picture with AVIF format for modern browsers, WebP for broader support, and multiple breakpoints for optimal performance across all device types.'
|
|
333
|
-
}
|
|
334
|
-
}
|
|
129
|
+
export const NoSources = {
|
|
130
|
+
name : 'No Sources (fallback only)',
|
|
131
|
+
render: () => html`
|
|
132
|
+
<bd-picture fallback-src="${placeholder}" alt="Fallback only" width="600" height="400" .sources="${[]}"></bd-picture>
|
|
133
|
+
`,
|
|
134
|
+
parameters: { docs: { description: { story: 'Empty `sources` array — only the fallback `<img>` is used.' } } }
|
|
335
135
|
};
|
|
336
136
|
|
|
337
|
-
export const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
<
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
<div style="text-align: center;">
|
|
346
|
-
<bd-h as="h4" style="margin-bottom: 1rem;">Cover</bd-h>
|
|
347
|
-
<div style="width: 250px; height: 200px; margin: 0 auto; border: 2px solid #e2e8f0; border-radius: 8px; overflow: hidden;">
|
|
348
|
-
<bd-picture
|
|
349
|
-
.sources="${[{ type: 'image/jpeg', srcset: '/assets/bd-header-us.jpg' }]}"
|
|
350
|
-
alt="Cover fit example"
|
|
351
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
352
|
-
width="250"
|
|
353
|
-
height="200"
|
|
354
|
-
fit="cover"
|
|
355
|
-
></bd-picture>
|
|
356
|
-
</div>
|
|
357
|
-
<bd-p kind="small" style="color: #64748b; margin-top: 1rem;">
|
|
358
|
-
<strong>Use case:</strong> Hero images, profile pictures<br>
|
|
359
|
-
<strong>Behavior:</strong> Fills container, may crop edges
|
|
360
|
-
</bd-p>
|
|
361
|
-
</div>
|
|
362
|
-
|
|
363
|
-
<div style="text-align: center;">
|
|
364
|
-
<bd-h as="h4" style="margin-bottom: 1rem;">Contain</bd-h>
|
|
365
|
-
<div style="width: 250px; height: 200px; margin: 0 auto; border: 2px solid #e2e8f0; border-radius: 8px; overflow: hidden; background: #f8fafc;">
|
|
366
|
-
<bd-picture
|
|
367
|
-
.sources="${[{ type: 'image/jpeg', srcset: '/assets/bd-header-us.jpg' }]}"
|
|
368
|
-
alt="Contain fit example"
|
|
369
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
370
|
-
width="250"
|
|
371
|
-
height="200"
|
|
372
|
-
fit="contain"
|
|
373
|
-
></bd-picture>
|
|
137
|
+
export const WithRadius = {
|
|
138
|
+
name : 'Radius Variants',
|
|
139
|
+
render: () => html`
|
|
140
|
+
<div style="display:flex; gap:16px; flex-wrap:wrap;">
|
|
141
|
+
${['none', 'sm', 'md', 'lg', 'full'].map(r => html`
|
|
142
|
+
<div>
|
|
143
|
+
<p style="font-size:12px; margin-bottom:4px;">radius-${r}</p>
|
|
144
|
+
<bd-picture fallback-src="${placeholder}" alt="radius ${r}" width="180" height="180" radius="${r}" fit="cover" .sources="${[]}"></bd-picture>
|
|
374
145
|
</div>
|
|
375
|
-
|
|
376
|
-
<strong>Use case:</strong> Product images, logos<br>
|
|
377
|
-
<strong>Behavior:</strong> Fits entirely, may have empty space
|
|
378
|
-
</bd-p>
|
|
379
|
-
</div>
|
|
380
|
-
|
|
381
|
-
<div style="text-align: center;">
|
|
382
|
-
<bd-h as="h4" style="margin-bottom: 1rem;">Fill</bd-h>
|
|
383
|
-
<div style="width: 250px; height: 200px; margin: 0 auto; border: 2px solid #e2e8f0; border-radius: 8px; overflow: hidden;">
|
|
384
|
-
<bd-picture
|
|
385
|
-
.sources="${[{ type: 'image/jpeg', srcset: '/assets/bd-header-us.jpg' }]}"
|
|
386
|
-
alt="Fill fit example"
|
|
387
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
388
|
-
width="250"
|
|
389
|
-
height="200"
|
|
390
|
-
fit="fill"
|
|
391
|
-
></bd-picture>
|
|
392
|
-
</div>
|
|
393
|
-
<bd-p kind="small" style="color: #64748b; margin-top: 1rem;">
|
|
394
|
-
<strong>Use case:</strong> Background patterns<br>
|
|
395
|
-
<strong>Behavior:</strong> Stretches to fill, may distort
|
|
396
|
-
</bd-p>
|
|
397
|
-
</div>
|
|
146
|
+
`)}
|
|
398
147
|
</div>
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
ObjectFitOptions.parameters = {
|
|
402
|
-
docs: {
|
|
403
|
-
description: {
|
|
404
|
-
story: 'Demonstration of different object-fit properties (cover, contain, fill) with visual examples and recommendations for when to use each option based on layout requirements and image content.'
|
|
405
|
-
}
|
|
406
|
-
}
|
|
148
|
+
`,
|
|
149
|
+
parameters: { docs: { description: { story: 'Five radius values applied to equal-dimension images.' } } }
|
|
407
150
|
};
|
|
408
151
|
|
|
409
|
-
export const
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
420
|
-
width="300"
|
|
421
|
-
height="200"
|
|
422
|
-
loading="lazy"
|
|
423
|
-
fit="cover"
|
|
424
|
-
radius="md"
|
|
425
|
-
></bd-picture>
|
|
426
|
-
<bd-p kind="regular" style="margin-top: 1.5rem;">
|
|
427
|
-
<strong>When to use:</strong> Images below the fold, gallery items, non-critical content<br>
|
|
428
|
-
<strong>Performance:</strong> Improves initial page load time<br>
|
|
429
|
-
<strong>User experience:</strong> Images load as user scrolls near them
|
|
430
|
-
</bd-p>
|
|
431
|
-
<bd-p kind="small" style="color: #64748b; margin-top: 1rem;">
|
|
432
|
-
✅ <strong>Best practice:</strong> Use for all non-essential images
|
|
433
|
-
</bd-p>
|
|
434
|
-
</div>
|
|
435
|
-
|
|
436
|
-
<div style="border: 2px solid #e2e8f0; padding: 2rem; border-radius: 12px;">
|
|
437
|
-
<bd-h as="h3" style="color: #3b82f6; margin-bottom: 1rem;">Eager Loading</bd-h>
|
|
438
|
-
<bd-picture
|
|
439
|
-
.sources="${[{ type: 'image/jpeg', srcset: '/assets/bd-header-us.jpg' }]}"
|
|
440
|
-
alt="Eager loaded security image"
|
|
441
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
442
|
-
width="300"
|
|
443
|
-
height="200"
|
|
444
|
-
loading="eager"
|
|
445
|
-
fit="cover"
|
|
446
|
-
radius="md"
|
|
447
|
-
></bd-picture>
|
|
448
|
-
<bd-p kind="regular" style="margin-top: 1.5rem;">
|
|
449
|
-
<strong>When to use:</strong> Hero images, above-the-fold content, LCP elements<br>
|
|
450
|
-
<strong>Performance:</strong> Loads immediately, may impact initial load<br>
|
|
451
|
-
<strong>User experience:</strong> Critical images ready when page renders
|
|
452
|
-
</bd-p>
|
|
453
|
-
<bd-p kind="small" style="color: #64748b; margin-top: 1rem;">
|
|
454
|
-
⚠️ <strong>Use sparingly:</strong> Only for images essential to initial rendering
|
|
455
|
-
</bd-p>
|
|
456
|
-
</div>
|
|
152
|
+
export const FitVariants = {
|
|
153
|
+
name : 'Fit Variants',
|
|
154
|
+
render: () => html`
|
|
155
|
+
<div style="display:flex; gap:16px; flex-wrap:wrap;">
|
|
156
|
+
${['cover', 'contain', 'fill', 'none'].map(fit => html`
|
|
157
|
+
<div>
|
|
158
|
+
<p style="font-size:12px; margin-bottom:4px;">${fit}</p>
|
|
159
|
+
<bd-picture fallback-src="${placeholder}" alt="${fit}" width="200" height="150" fit="${fit}" .sources="${[]}"></bd-picture>
|
|
160
|
+
</div>
|
|
161
|
+
`)}
|
|
457
162
|
</div>
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
LoadingStrategies.parameters = {
|
|
461
|
-
docs: {
|
|
462
|
-
description: {
|
|
463
|
-
story: 'Comparison of lazy vs eager loading strategies with performance implications and guidelines for when to use each approach based on image importance and position in the page layout.'
|
|
464
|
-
}
|
|
465
|
-
}
|
|
163
|
+
`,
|
|
164
|
+
parameters: { docs: { description: { story: 'Fit variants: cover, contain, fill, none.' } } }
|
|
466
165
|
};
|
|
467
166
|
|
|
468
|
-
export const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
radius="md"
|
|
484
|
-
></bd-picture>
|
|
485
|
-
|
|
486
|
-
<bd-p kind="regular" style="margin-top: 1.5rem;">
|
|
487
|
-
<strong>Descriptive:</strong> Clearly describes the image content and context<br>
|
|
488
|
-
<strong>Concise:</strong> Meaningful but not overly verbose<br>
|
|
489
|
-
<strong>Relevant:</strong> Relates to the surrounding content and purpose
|
|
490
|
-
</bd-p>
|
|
491
|
-
<bd-p kind="small" style="color: #059669; margin-top: 1rem;">
|
|
492
|
-
✅ Screen readers will provide meaningful context about the image content
|
|
493
|
-
</bd-p>
|
|
494
|
-
</div>
|
|
495
|
-
|
|
496
|
-
<div style="border: 2px solid #ef4444; padding: 2rem; border-radius: 12px; background: #fef2f2;">
|
|
497
|
-
<bd-h as="h3" style="color: #dc2626; margin-bottom: 1rem;">❌ Poor Alt Text Examples</bd-h>
|
|
498
|
-
|
|
499
|
-
<bd-picture
|
|
500
|
-
.sources="${[{ type: 'image/jpeg', srcset: '/assets/bd-header-us.jpg' }]}"
|
|
501
|
-
alt="image123.jpg"
|
|
502
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
503
|
-
width="600"
|
|
504
|
-
height="400"
|
|
505
|
-
loading="lazy"
|
|
506
|
-
fit="cover"
|
|
507
|
-
radius="md"
|
|
508
|
-
></bd-picture>
|
|
509
|
-
|
|
510
|
-
<bd-p kind="regular" style="margin-top: 1.5rem;">
|
|
511
|
-
<strong>Avoid:</strong> File names, placeholder text, or generic descriptions<br>
|
|
512
|
-
<strong>Don't:</strong> Start with "image of" or "picture of"<br>
|
|
513
|
-
<strong>Never:</strong> Leave alt text empty for meaningful images
|
|
514
|
-
</bd-p>
|
|
515
|
-
<bd-p kind="small" style="color: #dc2626; margin-top: 1rem;">
|
|
516
|
-
❌ Screen readers will announce meaningless file names to users
|
|
517
|
-
</bd-p>
|
|
518
|
-
</div>
|
|
519
|
-
|
|
520
|
-
<div style="border: 2px solid #e2e8f0; padding: 2rem; border-radius: 12px;">
|
|
521
|
-
<bd-h as="h3" style="color: #3b82f6; margin-bottom: 1rem;">Decorative Images</bd-h>
|
|
522
|
-
<bd-p kind="regular" style="margin-bottom: 1.5rem;">
|
|
523
|
-
For purely decorative images that don't convey meaningful content, use empty alt text to prevent screen readers from announcing them.
|
|
524
|
-
</bd-p>
|
|
525
|
-
<bd-picture
|
|
526
|
-
.sources="${[{ type: 'image/jpeg', srcset: '/assets/bd-header-us.jpg' }]}"
|
|
527
|
-
alt=""
|
|
528
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
529
|
-
width="400"
|
|
530
|
-
height="200"
|
|
531
|
-
loading="lazy"
|
|
532
|
-
fit="cover"
|
|
533
|
-
radius="md"
|
|
534
|
-
></bd-picture>
|
|
535
|
-
<bd-p kind="small" style="color: #64748b; margin-top: 1rem;">
|
|
536
|
-
✅ Empty alt attribute: <code>alt=""</code> - Screen readers will skip this image entirely
|
|
537
|
-
</bd-p>
|
|
538
|
-
</div>
|
|
539
|
-
</div>
|
|
540
|
-
`;
|
|
541
|
-
AccessibilityExamples.parameters = {
|
|
542
|
-
docs: {
|
|
543
|
-
description: {
|
|
544
|
-
story: 'Accessibility guidelines and examples showing proper alt text usage, common mistakes to avoid, and how to handle decorative images. Essential for creating inclusive experiences for screen reader users.'
|
|
545
|
-
}
|
|
546
|
-
}
|
|
167
|
+
export const ResponsiveSources = {
|
|
168
|
+
name : 'Responsive Sources (media queries)',
|
|
169
|
+
render: () => html`
|
|
170
|
+
<bd-picture
|
|
171
|
+
fallback-src="${placeholder}"
|
|
172
|
+
alt="Responsive product image"
|
|
173
|
+
width="800" height="450"
|
|
174
|
+
.sources="${[
|
|
175
|
+
{ type: 'image/webp', srcset: placeholder + '?w=800', media: '(min-width: 600px)' },
|
|
176
|
+
{ type: 'image/webp', srcset: placeholder + '?w=400', media: '' },
|
|
177
|
+
{ type: 'image/png', srcset: placeholder }
|
|
178
|
+
]}"
|
|
179
|
+
></bd-picture>
|
|
180
|
+
`,
|
|
181
|
+
parameters: { docs: { description: { story: 'Three sources: large WebP for desktop, small WebP for mobile, PNG fallback.' } } }
|
|
547
182
|
};
|
|
548
183
|
|
|
549
|
-
export const
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
.sources="${[
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
},
|
|
561
|
-
{
|
|
562
|
-
type : 'image/webp',
|
|
563
|
-
srcset: '/assets/bd-header-us-1000.webp',
|
|
564
|
-
media : '(min-width: 768px)'
|
|
565
|
-
},
|
|
566
|
-
{
|
|
567
|
-
type : 'image/webp',
|
|
568
|
-
srcset: '/assets/bd-header-us-750.webp'
|
|
569
|
-
}
|
|
570
|
-
]}"
|
|
571
|
-
alt="Bitdefender Security Suite dashboard showing comprehensive protection features including antivirus, firewall, and privacy tools"
|
|
572
|
-
fallback-src="/assets/bd-header-us.jpg"
|
|
573
|
-
width="800"
|
|
574
|
-
height="400"
|
|
575
|
-
loading="eager"
|
|
576
|
-
fit="cover"
|
|
577
|
-
radius="lg"
|
|
578
|
-
></bd-picture>
|
|
579
|
-
|
|
580
|
-
<div style="margin-top: 2rem; text-align: center;">
|
|
581
|
-
<bd-h as="h3" style="color: white; margin-bottom: 1rem;">Complete Digital Protection</bd-h>
|
|
582
|
-
<bd-p kind="lead" style="color: white; opacity: 0.9;">
|
|
583
|
-
Enterprise-grade security solutions for home and business users.
|
|
584
|
-
Real-time threat detection, advanced firewall, and privacy protection in one package.
|
|
585
|
-
</bd-p>
|
|
184
|
+
export const LazyVsEager = {
|
|
185
|
+
name : 'Lazy vs Eager Loading',
|
|
186
|
+
render: () => html`
|
|
187
|
+
<div style="display:flex; gap:16px; flex-wrap:wrap;">
|
|
188
|
+
<div>
|
|
189
|
+
<p style="font-size:12px; margin-bottom:4px;">loading="lazy"</p>
|
|
190
|
+
<bd-picture fallback-src="${placeholder}" alt="Lazy" width="300" height="200" loading="lazy" .sources="${[]}"></bd-picture>
|
|
191
|
+
</div>
|
|
192
|
+
<div>
|
|
193
|
+
<p style="font-size:12px; margin-bottom:4px;">loading="eager"</p>
|
|
194
|
+
<bd-picture fallback-src="${placeholder}" alt="Eager" width="300" height="200" loading="eager" .sources="${[]}"></bd-picture>
|
|
586
195
|
</div>
|
|
587
196
|
</div>
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
HeaderImageExample.parameters = {
|
|
591
|
-
docs: {
|
|
592
|
-
description: {
|
|
593
|
-
story: 'Real-world example of a hero section using the picture component with responsive images, eager loading for above-the-fold content, and proper accessibility attributes in a marketing context.'
|
|
594
|
-
}
|
|
595
|
-
}
|
|
197
|
+
`,
|
|
198
|
+
parameters: { docs: { description: { story: 'Comparison of `loading="lazy"` and `loading="eager"` side by side.' } } }
|
|
596
199
|
};
|
|
597
200
|
|
|
598
|
-
export const
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
srcset: '/assets/bd-header-us.jpg'
|
|
604
|
-
}
|
|
605
|
-
],
|
|
606
|
-
alt : 'Customizable picture component example',
|
|
607
|
-
fallbackSrc: '/assets/bd-header-us.jpg',
|
|
608
|
-
width : 400,
|
|
609
|
-
height : 300,
|
|
610
|
-
loading : 'lazy',
|
|
611
|
-
fit : 'cover',
|
|
612
|
-
radius : 'none'
|
|
613
|
-
};
|
|
614
|
-
InteractivePlayground.parameters = {
|
|
615
|
-
docs: {
|
|
616
|
-
description: {
|
|
617
|
-
story: 'Interactive playground where you can test all picture properties in real-time. Use the controls panel to modify the image sources, dimensions, loading strategy, fit behavior, and styling options.'
|
|
618
|
-
}
|
|
619
|
-
}
|
|
201
|
+
export const Playground = {
|
|
202
|
+
name : '🛝 Playground',
|
|
203
|
+
args : { ...defaultArgs },
|
|
204
|
+
render,
|
|
205
|
+
parameters: { docs: { description: { story: 'Interactive playground. Adjust all props via Controls.' } } }
|
|
620
206
|
};
|