@repobit/dex-system-design 0.21.2 → 0.22.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/package.json +4 -2
  3. package/src/components/Button/Button.js +7 -2
  4. package/src/components/Button/button.css.js +30 -0
  5. package/src/components/accordion/accordion-bg.stories.js +341 -171
  6. package/src/components/accordion/accordion.stories.js +345 -0
  7. package/src/components/anchor/anchor.stories.js +134 -76
  8. package/src/components/back/back.css.js +1 -1
  9. package/src/components/back/back.stories.js +301 -63
  10. package/src/components/badge/badge.js +4 -7
  11. package/src/components/badge/badge.stories.js +89 -96
  12. package/src/components/breadcrumb/breadcrumb.stories.js +167 -3
  13. package/src/components/cards/card.stories.js +153 -3
  14. package/src/components/display/display.css.js +7 -10
  15. package/src/components/display/display.js +14 -2
  16. package/src/components/display/display.stories.js +213 -219
  17. package/src/components/divider/divider.stories.js +337 -30
  18. package/src/components/footer/footer-lp.stories.js +346 -3
  19. package/src/components/footer/footer.js +0 -3
  20. package/src/components/footer/footer.stories.js +267 -4
  21. package/src/components/header/header.css.js +1 -1
  22. package/src/components/header/header.js +77 -56
  23. package/src/components/header/header.stories.js +298 -22
  24. package/src/components/heading/heading.css.js +1 -1
  25. package/src/components/heading/heading.stories.js +355 -113
  26. package/src/components/image/image.css.js +146 -98
  27. package/src/components/image/image.js +13 -2
  28. package/src/components/image/image.stories.js +546 -160
  29. package/src/components/input/custom-form.stories.js +209 -12
  30. package/src/components/link/link.css.js +2 -2
  31. package/src/components/link/link.stories.js +383 -53
  32. package/src/components/paragraph/paragraph.css.js +1 -1
  33. package/src/components/paragraph/paragraph.stories.js +365 -157
  34. package/src/components/picture/picture.css.js +209 -0
  35. package/src/components/picture/picture.js +16 -2
  36. package/src/components/picture/picture.stories.js +525 -180
  37. package/src/components/pricing-cards/new-pricing-card.js +19 -4
  38. package/src/components/pricing-cards/new-pricing-card.stories.js +422 -0
  39. package/src/components/pricing-cards/new-pricing.css.js +8 -0
  40. package/src/components/pricing-cards/pricing-card-actions.js +49 -9
  41. package/src/components/pricing-cards/pricing-card-container.css.js +1 -1
  42. package/src/components/pricing-cards/pricing-card-header.css.js +73 -63
  43. package/src/components/pricing-cards/pricing-card-header.js +44 -10
  44. package/src/components/pricing-cards/pricing-card-pricing.js +63 -64
  45. package/src/components/pricing-cards/pricing-card.css.js +7 -15
  46. package/src/components/pricing-cards/pricing-card.js +353 -270
  47. package/src/components/pricing-cards/pricing-card.stories.js +3 -3
  48. package/src/tokens/fonts.stories.js +335 -8
  49. package/src/tokens/spacing.stories.js +701 -34
  50. package/src/tokens/tokens-grid.stories.js +897 -48
  51. package/src/tokens/typography.stories.js +980 -38
  52. package/src/components/accordion/accordion-light.stories.js +0 -241
@@ -1,16 +1,32 @@
1
1
  import { LitElement, html } from "lit";
2
2
  import { tokens } from "../../tokens/tokens.js";
3
+ import "../badge/badge.js";
3
4
  import newPricingCSS from "../pricing-cards/new-pricing.css";
4
5
 
5
6
  class PricingCard extends LitElement {
6
7
  static properties = {
7
- highlight: { type: Boolean }
8
+ highlight : { type: Boolean },
9
+ productId : { type: String },
10
+ devices : { type: String },
11
+ subscription: { type: String },
12
+ shadow : { type: Boolean, reflect: true }
8
13
  };
9
14
 
10
-
15
+ constructor() {
16
+ super();
17
+ this.productId = "vsb";
18
+ this.devices = "5";
19
+ this.subscription = "1";
20
+ this.shadow = true;
21
+ }
11
22
 
12
23
  render() {
13
24
  return html`
25
+ <style>
26
+ ${tokens}
27
+ ${newPricingCSS}
28
+ </style>
29
+
14
30
  <div class="card-wrapper">
15
31
  ${this.highlight
16
32
  ? html`<div class="highlight-banner">Best Value</div>`
@@ -25,6 +41,5 @@ class PricingCard extends LitElement {
25
41
  `;
26
42
  }
27
43
  }
28
- PricingCard.styles = [tokens, newPricingCSS];
29
44
 
30
- customElements.define("new-pricing-card", PricingCard);
45
+ customElements.define("new-pricing-card", PricingCard);
@@ -0,0 +1,422 @@
1
+ import { html } from 'lit';
2
+ import './new-pricing-card.js';
3
+ import './pricing-card-actions.js';
4
+ import './pricing-card-container.js';
5
+ import './pricing-card-header.js';
6
+ import './pricing-card-pricing.js';
7
+ import './pricing-card-show-more.js';
8
+ import './pricing-feature-item.js';
9
+
10
+ export default {
11
+ title : 'Components/Pricing Cards[v2]',
12
+ tags : ['autodocs'],
13
+ parameters: {
14
+ docs: {
15
+ description: {
16
+ component: 'Store-integrated pricing cards with bd-context, bd-product, and bd-option wrappers in each component.'
17
+ }
18
+ }
19
+ },
20
+ argTypes: {
21
+ productId: {
22
+ control : 'text',
23
+ description: 'Product ID for store integration',
24
+ table : {
25
+ type : { summary: 'string' },
26
+ defaultValue: { summary: 'vsb' }
27
+ }
28
+ },
29
+ devices: {
30
+ control : 'text',
31
+ description: 'Number of devices',
32
+ table : {
33
+ type : { summary: 'string' },
34
+ defaultValue: { summary: '5' }
35
+ }
36
+ },
37
+ subscription: {
38
+ control : 'text',
39
+ description: 'Subscription type',
40
+ table : {
41
+ type : { summary: 'string' },
42
+ defaultValue: { summary: '1' }
43
+ }
44
+ },
45
+ dataLayerEvent: {
46
+ control : 'text',
47
+ description: 'Data layer event name',
48
+ table : {
49
+ type : { summary: 'string' },
50
+ defaultValue: { summary: 'info' }
51
+ }
52
+ }
53
+ }
54
+ };
55
+
56
+ // ============ TEMPLATE DE BAZĂ ============
57
+
58
+ const PricingCardTemplate = (args) => html`
59
+ <new-pricing-card
60
+ ?highlight="${args.highlight}"
61
+ product-id="${args.productId}"
62
+ devices="${args.devices}"
63
+ subscription="${args.subscription}"
64
+ data-layer-event="${args.dataLayerEvent}"
65
+ >
66
+ <pricing-card-header
67
+ slot="header"
68
+ title="${args.title}"
69
+ subtitle="${args.subtitle}"
70
+ badges="${args.badges}"
71
+ ></pricing-card-header>
72
+
73
+ <pricing-card-pricing
74
+ slot="pricing"
75
+ product-id="${args.productId}"
76
+ devices="${args.devices}"
77
+ subscription="${args.subscription}"
78
+ data-layer-event="${args.dataLayerEvent}"
79
+ ></pricing-card-pricing>
80
+
81
+ <pricing-card-actions
82
+ slot="actions"
83
+ product-id="${args.productId}"
84
+ devices="${args.devices}"
85
+ subscription="${args.subscription}"
86
+ data-layer-event="${args.dataLayerEvent}"
87
+ ></pricing-card-actions>
88
+
89
+ <pricing-card-show-more slot="features">
90
+ ${args.features?.map(feature =>
91
+ html`<pricing-feature-item>${feature}</pricing-feature-item>`
92
+ )}
93
+ </pricing-card-show-more>
94
+ </new-pricing-card>
95
+ `;
96
+
97
+ // ============ STORY-URI INDIVIDUALE ============
98
+
99
+ export const VSBCard = PricingCardTemplate.bind({});
100
+ VSBCard.args = {
101
+ productId : 'vsb',
102
+ devices : '5',
103
+ subscription : '1',
104
+ dataLayerEvent: 'info',
105
+ title : 'Bitdefender Total Security',
106
+ subtitle : '1 account – 5 devices',
107
+ badges : 'Premium',
108
+ features : [
109
+ 'Antivirus & malware protection',
110
+ 'Unlimited VPN',
111
+ 'Identity Theft Protection',
112
+ 'Advanced Threat Defense',
113
+ 'Parental Controls',
114
+ 'Webcam Protection'
115
+ ],
116
+ highlight: true,
117
+ shadow : true
118
+ };
119
+ VSBCard.parameters = {
120
+ docs: {
121
+ description: {
122
+ story: 'Premium security card with product ID "vsb" (Bitdefender Total Security). Includes all advanced features.'
123
+ }
124
+ }
125
+ };
126
+
127
+ export const TSI_Card = PricingCardTemplate.bind({});
128
+ TSI_Card.args = {
129
+ productId : 'ts_i',
130
+ devices : '5',
131
+ subscription : '1',
132
+ dataLayerEvent: 'info',
133
+ title : 'Bitdefender Internet Security',
134
+ subtitle : '1 account – 5 devices',
135
+ badges : 'Most Popular',
136
+ features : [
137
+ 'Antivirus & antimalware',
138
+ 'Two-way firewall',
139
+ 'Anti-phishing',
140
+ 'Anti-fraud',
141
+ 'Web Protection',
142
+ 'Vulnerability Scan'
143
+ ],
144
+ highlight: false,
145
+ shadow : true
146
+ };
147
+ TSI_Card.parameters = {
148
+ docs: {
149
+ description: {
150
+ story: 'Internet Security card with product ID "ts_i". Balanced protection for everyday use.'
151
+ }
152
+ }
153
+ };
154
+
155
+ export const PSI_Card = PricingCardTemplate.bind({});
156
+ PSI_Card.args = {
157
+ productId : 'ps_i',
158
+ devices : '5',
159
+ subscription : '1',
160
+ dataLayerEvent: 'info',
161
+ title : 'Bitdefender Antivirus Plus',
162
+ subtitle : 'Basic protection for your devices',
163
+ badges : '1 account – 5 devices',
164
+ features : [
165
+ 'Antivirus protection',
166
+ 'Real-time scanning',
167
+ 'Automatic updates',
168
+ 'Quick scan mode',
169
+ 'Rescue mode'
170
+ ],
171
+ highlight: false,
172
+ shadow : true
173
+ };
174
+ PSI_Card.parameters = {
175
+ docs: {
176
+ description: {
177
+ story: 'Basic antivirus card with product ID "ps_i". Lightweight protection for fewer devices.'
178
+ }
179
+ }
180
+ };
181
+
182
+ // ============ EXEMPLU CU DIFERITE DATA LAYER EVENTS ============
183
+
184
+ export const WithCustomDataLayerEvents = () => html`
185
+ <div style="padding: 20px;">
186
+ <h2 style="text-align: center; margin-bottom: 20px;">Pricing Cards with Custom Data Layer Events</h2>
187
+ <p style="text-align: center; color: #6c757d; margin-bottom: 30px;">Each card has different analytics events for tracking</p>
188
+
189
+ <pricing-cards-container count="3">
190
+ <!-- Card with click event -->
191
+ ${PricingCardTemplate({
192
+ productId : 'ps_i',
193
+ devices : '5',
194
+ subscription : '1',
195
+ dataLayerEvent: 'info',
196
+ title : 'Basic Plan',
197
+ subtitle : 'For personal use',
198
+ badges : 'Click Tracked',
199
+ features : [
200
+ 'Basic protection',
201
+ 'Real-time scanning',
202
+ '3 devices'
203
+ ],
204
+ highlight: false,
205
+ shadow : true
206
+ })}
207
+
208
+ <!-- Card with view event -->
209
+ ${PricingCardTemplate({
210
+ productId : 'ts_i',
211
+ devices : '5',
212
+ subscription : '1',
213
+ dataLayerEvent: 'info',
214
+ title : 'Family Plan',
215
+ subtitle : 'For families',
216
+ badges : 'View Tracked',
217
+ features : [
218
+ 'Family protection',
219
+ 'Parental controls',
220
+ '5 devices',
221
+ 'Password manager'
222
+ ],
223
+ highlight: true,
224
+ shadow : true
225
+ })}
226
+
227
+ <!-- Card with purchase intent event -->
228
+ ${PricingCardTemplate({
229
+ productId : 'vsb',
230
+ devices : '10',
231
+ subscription : '1',
232
+ dataLayerEvent: 'info',
233
+ title : 'Business Plan',
234
+ subtitle : 'For small businesses',
235
+ badges : 'Purchase Tracked',
236
+ features : [
237
+ 'Advanced protection',
238
+ 'Unlimited devices',
239
+ 'Priority support',
240
+ 'System optimization',
241
+ 'Identity protection'
242
+ ],
243
+ highlight: false,
244
+ shadow : true
245
+ })}
246
+ </pricing-cards-container>
247
+
248
+ <div style="margin-top: 30px; padding: 15px; background: #f8f9fa; border-radius: 8px;">
249
+ <h4 style="margin-top: 0;">Data Layer Events Explanation:</h4>
250
+ <ul style="margin-bottom: 0;">
251
+ <li><strong>pricing_card_click</strong>: Tracks when user clicks on the card</li>
252
+ <li><strong>pricing_card_view</strong>: Tracks when card becomes visible in viewport</li>
253
+ <li><strong>purchase_intent</strong>: Tracks when user shows purchase intent</li>
254
+ <li><strong>info</strong>: Default event for general information</li>
255
+ </ul>
256
+ </div>
257
+ </div>
258
+ `;
259
+ WithCustomDataLayerEvents.parameters = {
260
+ docs: {
261
+ description: {
262
+ story: 'Cards with different data layer events for analytics tracking. Each event triggers different analytics data.'
263
+ }
264
+ }
265
+ };
266
+
267
+ // ============ GRID CU 3 CARD-URI DIFFERITE ============
268
+
269
+ export const ThreeProductGrid = () => html`
270
+ <div style="padding: 20px; min-height: 100vh;">
271
+ <h2 style="text-align: center; margin-bottom: 30px; color: #212529;">Compare Security Plans</h2>
272
+
273
+ <pricing-cards-container count="3">
274
+ <!-- Card 1: PSI - Basic -->
275
+ ${PricingCardTemplate({
276
+ productId : 'ps_i',
277
+ devices : '5',
278
+ subscription : '1',
279
+ dataLayerEvent: 'info',
280
+ title : 'Bitdefender Antivirus Plus',
281
+ subtitle : '1 account – 5 devices',
282
+ badges : 'Basic',
283
+ features : [
284
+ 'Real-time antivirus',
285
+ 'Web protection',
286
+ 'Automatic updates',
287
+ 'Quick scan'
288
+ ],
289
+ highlight: false,
290
+ shadow : true
291
+ })}
292
+
293
+ <!-- Card 2: TSI - Standard (Highlighted) -->
294
+ ${PricingCardTemplate({
295
+ productId : 'ts_i',
296
+ devices : '5',
297
+ subscription : '1',
298
+ dataLayerEvent: 'info',
299
+ title : 'Bitdefender Internet Security',
300
+ subtitle : '1 account – 5 devices',
301
+ badges : 'Most Popular',
302
+ features : [
303
+ 'All Antivirus Plus features',
304
+ 'Two-way firewall',
305
+ 'Anti-phishing',
306
+ 'Parental controls',
307
+ 'Webcam protection',
308
+ 'File encryption'
309
+ ],
310
+ highlight: true,
311
+ shadow : true
312
+ })}
313
+
314
+ <!-- Card 3: VSB - Premium -->
315
+ ${PricingCardTemplate({
316
+ productId : 'vsb',
317
+ devices : '10',
318
+ subscription : '1',
319
+ dataLayerEvent: 'info',
320
+ title : 'Bitdefender Total Security',
321
+ subtitle : '1 account – 5 devices',
322
+ badges : 'Premium',
323
+ features : [
324
+ 'All Internet Security features',
325
+ 'Unlimited VPN traffic',
326
+ 'Password manager',
327
+ 'System optimizer',
328
+ 'Identity protection',
329
+ 'Priority support'
330
+ ],
331
+ highlight: false,
332
+ shadow : true
333
+ })}
334
+ </pricing-cards-container>
335
+
336
+ <div style="margin-top: 30px; text-align: center; color: #6c757d; font-size: 14px;">
337
+ <p>Each card has its own bd-context, bd-product, and bd-option wrappers for store integration.</p>
338
+ <p>Inspect each component to see the BrightData structure.</p>
339
+ </div>
340
+ </div>
341
+ `;
342
+ ThreeProductGrid.parameters = {
343
+ docs: {
344
+ description: {
345
+ story: 'Grid comparing three different security products: Basic (ps_i), Standard (ts_i), and Premium (vsb). Each card has independent store integration.'
346
+ }
347
+ }
348
+ };
349
+
350
+ // ============ STORY CU YEARLY SUBSCRIPTION ============
351
+
352
+ export const YearlySubscriptionCards = () => html`
353
+ <div style="padding: 20px;">
354
+ <h2 style="text-align: center; margin-bottom: 20px;">Yearly Subscription Plans</h2>
355
+ <p style="text-align: center; color: #6c757d; margin-bottom: 30px;">All plans with 1-year subscription for maximum savings</p>
356
+
357
+ <pricing-cards-container count="3">
358
+ <!-- Monthly vs Yearly comparison -->
359
+ ${PricingCardTemplate({
360
+ productId : 'ps_i',
361
+ devices : '5',
362
+ subscription : '12',
363
+ dataLayerEvent: 'info',
364
+ title : 'Bitdefender Monthly Plan',
365
+ subtitle : '1 account – 5 devices',
366
+ badges : 'Monthly',
367
+ features : [
368
+ 'Cancel anytime',
369
+ 'Monthly billing',
370
+ 'Standard price',
371
+ '3 devices'
372
+ ],
373
+ highlight: false,
374
+ shadow : true
375
+ })}
376
+
377
+ ${PricingCardTemplate({
378
+ productId : 'ts_i',
379
+ devices : '5',
380
+ subscription : '12',
381
+ dataLayerEvent: 'info',
382
+ title : 'Bitdefender Yearly Plan',
383
+ subtitle : '1 account – 5 devices',
384
+ badges : 'Save 25%',
385
+ features : [
386
+ 'Annual billing',
387
+ '25% discount',
388
+ '5 devices',
389
+ 'Priority support'
390
+ ],
391
+ highlight: true,
392
+ shadow : true
393
+ })}
394
+
395
+ ${PricingCardTemplate({
396
+ productId : 'vsb',
397
+ devices : '5',
398
+ subscription : '12',
399
+ dataLayerEvent: 'info',
400
+ title : 'Bitdefender 1-Year Plan',
401
+ subtitle : '1 account – 5 devices',
402
+ badges : 'Save 40%',
403
+ features : [
404
+ '2-year commitment',
405
+ '40% discount',
406
+ '10 devices',
407
+ 'Premium support',
408
+ 'Free 3 months'
409
+ ],
410
+ highlight: false,
411
+ shadow : true
412
+ })}
413
+ </pricing-cards-container>
414
+ </div>
415
+ `;
416
+ YearlySubscriptionCards.parameters = {
417
+ docs: {
418
+ description: {
419
+ story: 'Cards showing different subscription durations. Each card has store integration for its specific subscription period.'
420
+ }
421
+ }
422
+ };
@@ -1,11 +1,17 @@
1
1
  import { css } from "lit";
2
2
 
3
3
  export default css`
4
+ :host {
5
+ --background-card-grey: var(--color-neutral-25);
6
+ --border-card-grey: var(--color-neutral-50);
7
+ }
8
+
4
9
  .card {
5
10
  background: white;
6
11
  border-radius: var(--spacing-20);
7
12
  padding: var(--spacing-32);
8
13
  background: #fafafa;
14
+ border: 1px solid var(--border-card-grey);
9
15
  }
10
16
 
11
17
  .highlight {
@@ -19,6 +25,8 @@ export default css`
19
25
  .card-wrapper {
20
26
  position: relative;
21
27
  padding-top: 2.5rem;
28
+ max-width: 400px;
29
+ margin: 0 auto;
22
30
  }
23
31
 
24
32
  .highlight-banner {
@@ -1,21 +1,61 @@
1
- import { LitElement, html } from 'lit';
1
+ import { LitElement, html } from "lit";
2
2
  import { tokens } from "../../tokens/tokens.js";
3
3
  import "../Button/Button.js";
4
- import newActionsPricingCSS from "../pricing-cards/pricing-card-actions.css.js";
4
+ import newPricingActionsCSS from "../pricing-cards/pricing-card-actions.css.js";
5
5
 
6
6
  class PricingCardActions extends LitElement {
7
+ static properties = {
8
+ productId : { type: String, attribute: "product-id" }, // <- aici e corect
9
+ devices : { type: String },
10
+ subscription : { type: String },
11
+ dataLayerEvent: { type: String }
12
+ };
7
13
 
14
+ constructor() {
15
+ super();
16
+ this.productId = "vsb";
17
+ this.devices = "5";
18
+ this.subscription = "1";
19
+ this.dataLayerEvent = "info";
20
+ }
21
+
22
+ createRenderRoot() {
23
+ return this;
24
+ }
8
25
 
9
26
  render() {
10
27
  return html`
11
- <div class="actions">
12
- <bd-button kind="danger" size="md" fullWidth strong>
13
- Buy Now
14
- </bd-button>
15
- </div>
28
+ <style>
29
+ ${tokens}
30
+ ${newPricingActionsCSS}
31
+ </style>
32
+
33
+ <bd-context ignore-events-parent>
34
+ <!-- AICI TREBUIE product-id CU CRATIMĂ! -->
35
+ <bd-product product-id="${this.productId}">
36
+ <bd-option
37
+ devices="${this.devices}"
38
+ subscription="${this.subscription}"
39
+ data-layer-event="${this.dataLayerEvent}">
40
+
41
+ <div class="actions">
42
+ <bd-button-link
43
+ label="Buy now"
44
+ kind="danger"
45
+ size="md"
46
+ fullwidth
47
+ strong
48
+ buyLink
49
+ >
50
+ Buy Now
51
+ </bd-button-link>
52
+ </div>
53
+
54
+ </bd-option>
55
+ </bd-product>
56
+ </bd-context>
16
57
  `;
17
58
  }
18
59
  }
19
- PricingCardActions.styles = [tokens, newActionsPricingCSS];
20
60
 
21
- customElements.define('pricing-card-actions', PricingCardActions);
61
+ customElements.define("pricing-card-actions", PricingCardActions);
@@ -2,7 +2,7 @@ import { css } from "lit";
2
2
 
3
3
  export default css`
4
4
  :host {
5
- display: block;
5
+ // display: block;
6
6
  padding: 0px 240px;
7
7
  }
8
8