@repobit/dex-system-design 0.24.18 → 0.24.20

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 (29) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/package.json +4 -4
  3. package/src/components/ai-guardian-demo.stories.js +454 -33
  4. package/src/components/bento-grid/bento-grid.css.js +12 -1
  5. package/src/components/bento-grid/bento-grid.js +59 -1
  6. package/src/components/bento-grid/bento-grid.stories.js +45 -0
  7. package/src/components/cards/card.css.js +56 -0
  8. package/src/components/cards/card.js +64 -11
  9. package/src/components/cards/card.stories.js +65 -2
  10. package/src/components/comparison-panel/comparison-panel.css.js +52 -1
  11. package/src/components/comparison-panel/comparison-panel.js +6 -1
  12. package/src/components/compatibility-table/compatibility-table.css.js +29 -13
  13. package/src/components/compatibility-table/compatibility-table.js +13 -7
  14. package/src/components/cta-banner/cta-banner.css.js +11 -0
  15. package/src/components/cta-banner/cta-banner.js +7 -0
  16. package/src/components/footer/footer-lp.css.js +10 -21
  17. package/src/components/footer/footer-lp.js +3 -18
  18. package/src/components/footer/footer-nav-menu.css.js +0 -2
  19. package/src/components/footer/footer.css.js +18 -35
  20. package/src/components/footer/footer.js +5 -1
  21. package/src/components/header/header-code.css.js +208 -10
  22. package/src/components/header/header-code.js +148 -5
  23. package/src/components/header/header-code.stories.js +83 -27
  24. package/src/components/page-switcher/page-switcher.js +1 -1
  25. package/src/components/paragraph/paragraph.js +6 -0
  26. package/src/components/quick-answer/quick-answer.css.js +2 -0
  27. package/src/components/quick-answer/quick-answer.js +1 -1
  28. package/src/components/terminal/terminal-message.css.js +153 -13
  29. package/src/components/terminal/terminal-message.js +37 -11
@@ -6,12 +6,13 @@ import compatibilityTableCSS from "./compatibility-table.css.js";
6
6
 
7
7
  class CompatibilityTable extends LitElement {
8
8
  static properties = {
9
- title : { type: String },
10
- description: { type: String },
11
- variant : { type: String, reflect: true }, // "default" | "outcome" | "risk" | "light"
12
- background : { type: String, reflect: true }, // "default" | "blue"
13
- columns : { type: Array },
14
- rows : { type: Array }
9
+ title : { type: String },
10
+ description : { type: String },
11
+ variant : { type: String, reflect: true },
12
+ background : { type: String, reflect: true },
13
+ lightColumns: { type: Number, attribute: "light-columns" },
14
+ columns : { type: Array },
15
+ rows : { type: Array }
15
16
  };
16
17
 
17
18
  static styles = [tokens, compatibilityTableCSS];
@@ -22,6 +23,7 @@ class CompatibilityTable extends LitElement {
22
23
  this.description = "";
23
24
  this.variant = "default";
24
25
  this.background = "default";
26
+ this.lightColumns = 2;
25
27
  this.columns = null;
26
28
  this.rows = [];
27
29
  }
@@ -95,7 +97,11 @@ class CompatibilityTable extends LitElement {
95
97
 
96
98
  ${this.variant === "light"
97
99
  ? html`
98
- <div class="bd-compattable-lightgrid" role="table">
100
+ <div
101
+ class="bd-compattable-lightgrid"
102
+ role="table"
103
+ style="--bd-compattable-light-columns: ${this.lightColumns};"
104
+ >
99
105
  ${this.rows.map((row) => this._renderRow(row))}
100
106
  <slot name="rows"></slot>
101
107
  </div>
@@ -16,7 +16,18 @@ export default css`
16
16
  text-align: center;
17
17
  gap: var(--spacing-16);
18
18
  }
19
+ .bd-ctabanner-footer {
20
+ margin-top: var(--spacing-24, 24px);
21
+ display: flex;
22
+ flex-direction: column;
23
+ align-items: center;
24
+ gap: var(--spacing-8, 8px);
25
+ text-align: center;
26
+ }
19
27
 
28
+ .bd-ctabanner-footer:not(:has(*)) {
29
+ display: none;
30
+ }
20
31
  .bd-ctabanner-title {
21
32
  display: block;
22
33
  margin: 0;
@@ -55,6 +55,13 @@ class CtaBanner extends LitElement {
55
55
  </bd-p>
56
56
  `
57
57
  : nothing}
58
+
59
+ <!-- Freeform slot for extra content below the caption — contact
60
+ info, legal disclaimers, links, etc. Empty by default,
61
+ collapses to nothing when unused. -->
62
+ <div class="bd-ctabanner-footer">
63
+ <slot name="footer"></slot>
64
+ </div>
58
65
  </div>
59
66
  `;
60
67
  }
@@ -10,11 +10,6 @@ export default css`
10
10
  line-height: var(--typography-lineHeight-normal);
11
11
  }
12
12
 
13
- .footer-secondary-nav {
14
- padding-top: var(--spacing-12);
15
- padding-bottom: var(--spacing-12);
16
- }
17
-
18
13
  bd-divider-vertical {
19
14
  display: inline-block;
20
15
  width: var(--form-input-default-borderWidth);
@@ -47,7 +42,15 @@ padding-bottom: var(--spacing-12);
47
42
  padding: var(--spacing-24) 0;
48
43
  }
49
44
 
45
+ /* Wraps the "secondary-nav" slot (Legal / Privacy Policy / etc). This
46
+ rule previously only had padding — no display:flex/gap — so the
47
+ slotted links ran together with no spacing between them, same root
48
+ cause as the bug that was fixed in bd-footer's own footer.css.js. */
50
49
  .footer-secondary-nav {
50
+ display: flex;
51
+ align-items: center;
52
+ flex-wrap: wrap;
53
+ gap: var(--spacing-16);
51
54
  padding: var(--spacing-24) 0;
52
55
  }
53
56
 
@@ -80,7 +83,6 @@ padding-bottom: var(--spacing-12);
80
83
  background: var(--color-blue-500);
81
84
  }
82
85
 
83
- /* Stiluri pentru link-uri */
84
86
  a {
85
87
  color: var(--color-neutral-0);
86
88
  text-decoration: none;
@@ -90,7 +92,6 @@ padding-bottom: var(--spacing-12);
90
92
  text-decoration: underline;
91
93
  }
92
94
 
93
- /* Stiluri de accesibilitate */
94
95
  a:focus {
95
96
  outline: none;
96
97
  border: 2px solid var(--color-blue-500);
@@ -98,18 +99,6 @@ padding-bottom: var(--spacing-12);
98
99
  border-radius: 4px;
99
100
  }
100
101
 
101
- /* Stiluri pentru navigație */
102
- .footer-nav-main {
103
- display: flex;
104
- align-items: center;
105
- justify-content: flex-start;
106
- gap: var(--spacing-16);
107
- flex-wrap: wrap;
108
- font-size: var(--typography-body-regular-fontSize);
109
- font-family: var(--typography-fontFamily-sans, 'IBM Plex Sans');
110
- }
111
-
112
- /* Responsive styles */
113
102
  @media (max-width: 768px) {
114
103
  .footer-top {
115
104
  flex-direction: column;
@@ -128,13 +117,13 @@ padding-bottom: var(--spacing-12);
128
117
  margin-bottom: var(--spacing-16);
129
118
  }
130
119
 
131
- .footer-nav-main {
120
+ .footer-secondary-nav {
132
121
  flex-direction: column;
133
122
  align-items: flex-start;
134
123
  gap: var(--spacing-8);
135
124
  }
136
125
 
137
- .footer-nav-main bd-divider-vertical {
126
+ .footer-secondary-nav bd-divider-vertical {
138
127
  display: none !important;
139
128
  }
140
129
  }
@@ -22,7 +22,7 @@ export class BdFooterLP extends LitElement {
22
22
 
23
23
  connectedCallback() {
24
24
  super.connectedCallback();
25
- this._initLocaleFromUrl(); // Adaugă inițializarea locale-ului din URL
25
+ this._initLocaleFromUrl();
26
26
  window.addEventListener('resize', this._handleResize.bind(this));
27
27
  }
28
28
 
@@ -33,12 +33,12 @@ export class BdFooterLP extends LitElement {
33
33
 
34
34
  firstUpdated() {
35
35
  super.firstUpdated();
36
- this._toggleImpressumVisibility(); // Apelează la initializare
36
+ this._toggleImpressumVisibility();
37
37
  }
38
38
 
39
39
  updated(changedProps) {
40
40
  if (changedProps.has('currentLocale')) {
41
- this._toggleImpressumVisibility(); // Apelează când se schimbă locale-ul
41
+ this._toggleImpressumVisibility();
42
42
  }
43
43
  }
44
44
 
@@ -49,27 +49,22 @@ export class BdFooterLP extends LitElement {
49
49
  return;
50
50
  }
51
51
 
52
- // Creează o versiune normalized a localeMap cu cheile lowercase
53
52
  const normalizedLocaleMap = {};
54
53
  Object.entries(localeMap).forEach(([key, value]) => {
55
54
  normalizedLocaleMap[key.toLowerCase()] = value;
56
55
  });
57
56
 
58
- // Încearcă mai întâi potrivire exactă
59
57
  let country = normalizedLocaleMap[urlLocale];
60
58
 
61
- // Dacă nu găsești potrivire exactă, încearcă să găsești cea mai bună potrivire
62
59
  if (!country && urlLocale) {
63
60
  const localeParts = urlLocale.split('-');
64
61
  const language = localeParts[0];
65
62
  const region = localeParts[1];
66
63
 
67
- // Caută o potrivire care să înceapă cu același limbaj
68
64
  const possibleMatches = Object.entries(normalizedLocaleMap)
69
65
  .filter(([key]) => key.startsWith(language));
70
66
 
71
67
  if (possibleMatches.length > 0) {
72
- // Preferă potrivirea cu aceeași regiune dacă există
73
68
  const exactRegionMatch = possibleMatches.find(([key]) => {
74
69
  const keyParts = key.split('-');
75
70
  const keyRegion = keyParts[1];
@@ -81,13 +76,11 @@ export class BdFooterLP extends LitElement {
81
76
 
82
77
  if (exactRegionMatch) {
83
78
  country = exactRegionMatch[1];
84
- // Recuperează cheia originală din localeMap
85
79
  const originalKey = Object.keys(localeMap).find(k =>
86
80
  k.toLowerCase() === exactRegionMatch[0]
87
81
  );
88
82
  this.currentLocale = originalKey || exactRegionMatch[0];
89
83
  } else {
90
- // Altfel, ia prima potrivire
91
84
  country = possibleMatches[0][1];
92
85
  const originalKey = Object.keys(localeMap).find(k =>
93
86
  k.toLowerCase() === possibleMatches[0][0]
@@ -114,25 +107,20 @@ export class BdFooterLP extends LitElement {
114
107
  const footerNav = assignedElements[0];
115
108
  const impressumLink = footerNav.querySelector('.impressum-link');
116
109
 
117
- // Găsește separatorul care precede link-ul Impressum
118
110
  let impressumDivider = null;
119
111
  if (impressumLink) {
120
112
  impressumDivider = impressumLink.previousElementSibling;
121
113
 
122
- // Verifică dacă elementul anterior este un divider și este imediat înainte
123
114
  if (impressumDivider && impressumDivider.tagName === 'BD-DIVIDER-VERTICAL' &&
124
115
  impressumDivider.nextElementSibling === impressumLink) {
125
- // Este separatorul corect
126
116
  } else {
127
117
  impressumDivider = null;
128
118
  }
129
119
  }
130
120
 
131
121
  if (impressumLink) {
132
- // Ascunde/afișează link-ul Impressum
133
122
  impressumLink.style.display = showImpressum ? '' : 'none';
134
123
 
135
- // Ascunde/afișează și separatorul dinaintea lui
136
124
  if (impressumDivider && impressumDivider.tagName === 'BD-DIVIDER-VERTICAL') {
137
125
  impressumDivider.style.display = showImpressum ? '' : 'none';
138
126
  }
@@ -214,14 +202,12 @@ export class BdFooterLP extends LitElement {
214
202
  `;
215
203
  }
216
204
 
217
- // Metodă specifică pentru secondary-nav care verifică și elementele custom
218
205
  _hasSecondaryNavContent() {
219
206
  const slot = this.shadowRoot?.querySelector('slot[name="secondary-nav"]');
220
207
  if (!slot) return false;
221
208
 
222
209
  const assignedNodes = slot.assignedNodes({ flatten: true });
223
210
 
224
- // Verifică dacă există noduri care nu sunt doar spații albe
225
211
  const hasContent = assignedNodes.some(node => {
226
212
  if (node.nodeType === Node.ELEMENT_NODE) {
227
213
  return true;
@@ -235,7 +221,6 @@ export class BdFooterLP extends LitElement {
235
221
  return hasContent;
236
222
  }
237
223
 
238
- // Metodă helper pentru a verifica dacă un slot are conținut
239
224
  _hasSlotContent(slotName) {
240
225
  const slot = this.shadowRoot?.querySelector(`slot[name="${slotName}"]`);
241
226
  if (!slot) return false;
@@ -16,7 +16,6 @@ export default css`
16
16
  font-weight: var(--typography-heading-h3-fontWeight);
17
17
  }
18
18
 
19
- /* Corect: stilizare pentru elementele slottate */
20
19
  ::slotted(a) {
21
20
  color: white !important;
22
21
  text-decoration: none;
@@ -33,5 +32,4 @@ export default css`
33
32
  display: none !important;
34
33
  }
35
34
  }
36
-
37
35
  `;
@@ -9,7 +9,7 @@ export default css`
9
9
  font-size: var(--typography-body-small-fontSize);
10
10
  line-height: var(--typography-lineHeight-normal);
11
11
  }
12
- .footer-nav-main a:focus,
12
+ .footer-nav-main-container a:focus,
13
13
  .footer-links a:focus,
14
14
  .footer-countries-container a:focus,
15
15
  .country-toggle:focus,
@@ -21,14 +21,12 @@ export default css`
21
21
  border-radius: 4px;
22
22
  }
23
23
 
24
- /* Stiluri specifice pentru butoane */
25
24
  .country-toggle:focus,
26
25
  .close-countries-button:focus {
27
26
  border-color: var(--color-blue-500);
28
27
  box-shadow: var(--focus-outline-primary, 0 0 0 2px rgba(0, 109, 255, 0.3));
29
28
  }
30
29
 
31
- /* Stiluri pentru link-urile din containerul de țări */
32
30
  .footer-countries-container a:focus {
33
31
  border-color: var(--color-blue-500);
34
32
  box-shadow: var(--focus-outline-primary, 0 0 0 2px rgba(0, 109, 255, 0.3));
@@ -36,8 +34,7 @@ export default css`
36
34
  padding: 2px 6px;
37
35
  }
38
36
 
39
- /* Stiluri pentru link-urile din navigația principală */
40
- .footer-nav-main a:focus {
37
+ .footer-nav-main-container a:focus {
41
38
  padding: 2px 6px;
42
39
  margin: -2px -6px;
43
40
  }
@@ -45,20 +42,12 @@ export default css`
45
42
  padding-top: var(--spacing-24);
46
43
  padding-bottom: var(--spacing-24);
47
44
  }
48
- .footer-nav-main-container {
49
- padding-top: var(--spacing-12);
50
- padding-bottom: var(--spacing-12);
51
- }
52
- /* Stiluri pentru link-urile din grupurile de link-uri */
53
45
  bd-footer-links-group a:focus {
54
46
  padding: 2px 6px;
55
47
  margin: -2px -6px;
56
48
  display: inline-block;
57
49
  }
58
50
 
59
-
60
-
61
-
62
51
  bd-divider-vertical {
63
52
  display: inline-block;
64
53
  width: var(--form-input-default-borderWidth);
@@ -85,14 +74,14 @@ bd-footer-links-group a:focus {
85
74
  background-color: var(--color-blue-500);
86
75
  }
87
76
 
88
- .footer-nav-main {
77
+ .footer-nav-main-container {
89
78
  display: flex;
90
79
  align-items: center;
91
80
  justify-content: flex-start;
92
81
  gap: var(--spacing-16);
93
82
  flex-wrap: wrap;
94
- padding-top: var(--spacing-24);
95
- padding-bottom: var(--spacing-24);
83
+ padding-top: var(--spacing-12);
84
+ padding-bottom: var(--spacing-12);
96
85
  font-size: var(--typography-body-regular-fontSize);
97
86
  font-family: var(--typography-fontFamily-sans, 'IBM Plex Sans');
98
87
  }
@@ -106,7 +95,6 @@ bd-footer-links-group a:focus {
106
95
  justify-content: space-between;
107
96
  align-items: flex-start;
108
97
  gap: var(--spacing-32);
109
- // margin-bottom: var(--spacing-24);
110
98
  flex-wrap: nowrap;
111
99
  padding-top: var(--spacing-24);
112
100
  padding-bottom: var(--spacing-24);
@@ -119,7 +107,13 @@ bd-footer-links-group a:focus {
119
107
  gap: var(--spacing-16);
120
108
  padding-top: var(--spacing-24);
121
109
  padding-bottom: var(--spacing-24);
110
+ }
122
111
 
112
+ .secondary-nav-container {
113
+ display: flex;
114
+ align-items: center;
115
+ flex-wrap: wrap;
116
+ gap: var(--spacing-16);
123
117
  }
124
118
 
125
119
  .footer-middle-line > :last-child {
@@ -242,7 +236,6 @@ bd-footer-links-group a:focus {
242
236
  content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M4.14286 1C2.40937 1 1 2.40937 1 4.14286V19.8571C1 21.5906 2.40937 23 4.14286 23H19.8571C21.5906 23 23 21.5906 23 19.8571V4.14286C23 2.40937 21.5906 1 19.8571 1H4.14286ZM18.7326 5.125L13.6353 10.9491L19.6312 18.875H14.9366L11.2634 14.0674L7.05491 18.875H4.72232L10.1732 12.6433L4.42277 5.125H9.23527L12.5598 9.52009L16.4 5.125H18.7326ZM16.8763 17.4804L8.53304 6.44598H7.1433L15.5799 17.4804H16.8714H16.8763Z" fill="white"/></svg>');
243
237
  }
244
238
 
245
-
246
239
  a {
247
240
  color: var(--color-neutral-0);
248
241
  text-decoration: none;
@@ -493,13 +486,13 @@ bd-footer-links-group a:focus {
493
486
  .footer-address{
494
487
  display: none !important;
495
488
  }
496
- .footer-nav-main {
489
+ .footer-nav-main-container {
497
490
  flex-direction: column;
498
491
  align-items: flex-start;
499
492
  gap: var(--spacing-8);
500
493
  }
501
494
 
502
- .footer-nav-main bd-divider-vertical {
495
+ .footer-nav-main-container bd-divider-vertical {
503
496
  display: none !important;
504
497
  }
505
498
 
@@ -537,7 +530,7 @@ bd-footer-links-group a:focus {
537
530
  width: 100%;
538
531
  }
539
532
 
540
- .footer-nav-main a[slot="nav"] {
533
+ .footer-nav-main-container a[slot="nav"] {
541
534
  color: #151719 !important;
542
535
  }
543
536
 
@@ -545,17 +538,17 @@ bd-footer-links-group a:focus {
545
538
  margin-bottom: 10px;
546
539
  }
547
540
 
548
- .second-nav .footer-nav-main {
541
+ .second-nav .footer-nav-main-container {
549
542
  flex-direction: column;
550
543
  align-items: flex-start;
551
544
  gap: var(--spacing-14);
552
545
  }
553
546
 
554
- .second-nav .footer-nav-main bd-divider-vertical {
547
+ .second-nav .footer-nav-main-container bd-divider-vertical {
555
548
  display: none !important;
556
549
  }
557
550
 
558
- .second-nav .footer-nav-main a {
551
+ .second-nav .footer-nav-main-container a {
559
552
  color: #151719 !important;
560
553
  padding: var(--spacing-4) 0;
561
554
  display: block;
@@ -578,7 +571,7 @@ bd-footer-links-group a:focus {
578
571
  gap: var(--spacing-8);
579
572
  }
580
573
 
581
- .second-nav.footer-nav-main {
574
+ .second-nav.footer-nav-main-container {
582
575
  display: inline-grid;
583
576
  }
584
577
 
@@ -620,7 +613,6 @@ bd-footer-links-group a:focus {
620
613
  width: 100%;
621
614
  }
622
615
 
623
- /* STILURI MODIFICATE PENTRU FOOTER-LINKS PE MOBILE */
624
616
  .footer-links {
625
617
  display: flex;
626
618
  flex-direction: column;
@@ -632,20 +624,16 @@ bd-footer-links-group a:focus {
632
624
  width: 100%;
633
625
  }
634
626
 
635
- /* QUICK LINKS - PRIMA POZIȚIE */
636
627
  .footer-links-left {
637
628
  order: 1;
638
629
  }
639
630
 
640
- /* DIVIDER - ÎNTRE QUICK LINKS ȘI SOCIAL LINKS */
641
- /* Targetăm divider-ul care este copil direct în .footer-links */
642
631
  .footer-links > bd-divider-horizontal {
643
632
  order: 2;
644
633
  margin: var(--spacing-16) 0;
645
634
  width: 100%;
646
635
  }
647
636
 
648
- /* SOCIAL LINKS - A TREIA POZIȚIE (DUPĂ DIVIDER) */
649
637
  .footer-links-right {
650
638
  order: 3;
651
639
  display: flex;
@@ -654,7 +642,6 @@ bd-footer-links-group a:focus {
654
642
  margin-bottom: 0;
655
643
  }
656
644
 
657
- /* STILURI PENTRU COMPONENTELE BD-FOOTER-LINKS-GROUP */
658
645
  bd-footer-links-group {
659
646
  width: 100% !important;
660
647
  min-width: 100% !important;
@@ -669,7 +656,6 @@ bd-footer-links-group a:focus {
669
656
  margin-bottom: var(--spacing-8) !important;
670
657
  }
671
658
 
672
- /* GRID PENTRU QUICK LINKS */
673
659
  .footer-links-left bd-grid {
674
660
  display: flex !important;
675
661
  flex-direction: column !important;
@@ -696,7 +682,6 @@ bd-footer-links-group a:focus {
696
682
  width: 100%;
697
683
  }
698
684
 
699
- /* Divider-ul imediat după secondary-nav */
700
685
  .secondary-nav-container bd-divider-horizontal {
701
686
  margin-top: var(--spacing-16);
702
687
  margin-bottom: var(--spacing-16);
@@ -713,7 +698,6 @@ bd-footer-links-group a:focus {
713
698
  display: none;
714
699
  }
715
700
 
716
- /* Afișează divider-ul doar pe tablete */
717
701
  @media (min-width: 768px) and (max-width: 1024px) {
718
702
  .tablet-divider {
719
703
  display: block;
@@ -744,7 +728,6 @@ bd-footer-links-group a:focus {
744
728
  margin: var(--spacing-16) 0;
745
729
  width: 100%;
746
730
  }
747
- /* Ascunde ultimul divider (cel din afara .footer-links) pe tablete */
748
731
  .footer-links + bd-divider-horizontal {
749
732
  display: none !important;
750
733
  }
@@ -241,7 +241,11 @@ export class BdFooter extends LitElement {
241
241
  }
242
242
 
243
243
  _updateNavLinks() {
244
- const links = this.shadowRoot.querySelectorAll('.footer-nav-main bd-link');
244
+ // Fixed: the wrapping div in render() below is class
245
+ // "footer-nav-main-container", not "footer-nav-main" — the old
246
+ // selector never matched anything, so link hrefs were never updated
247
+ // when the locale changed.
248
+ const links = this.shadowRoot.querySelectorAll('.footer-nav-main-container bd-link');
245
249
  const linkPaths = ['consumer', 'small-business', 'business', 'partners'];
246
250
  const currentLocale = this.locale;
247
251