@repobit/dex-system-design 0.11.0 → 0.12.0

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 (105) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/package.json +2 -2
  3. package/src/assets/icons/Identity_protection.png +0 -0
  4. package/src/assets/icons/arrow_down.png +0 -0
  5. package/src/assets/icons/arrow_up.png +0 -0
  6. package/src/assets/icons/device_protection.png +0 -0
  7. package/src/assets/icons/financial_insurance.png +0 -0
  8. package/src/assets/icons/privacy_protection.png +0 -0
  9. package/src/assets/icons/user_guide.png +0 -0
  10. package/src/components/Button/Button.js +19 -16
  11. package/src/components/Button/button.css.js +18 -16
  12. package/src/components/Button/icons.js +8 -8
  13. package/src/components/FAQ/faq.css.js +48 -49
  14. package/src/components/FAQ/faq.js +0 -86
  15. package/src/components/Input/Input.js +68 -6
  16. package/src/components/Input/custom-form.stories.js +88 -0
  17. package/src/components/Input/input-clipboard.css.js +168 -0
  18. package/src/components/Input/input-clipboard.js +137 -0
  19. package/src/components/Input/input.css.js +122 -42
  20. package/src/components/accordion/accordion-bg.css.js +117 -0
  21. package/src/components/accordion/accordion-bg.js +80 -0
  22. package/src/components/accordion/accordion-no-bg.css.js +114 -0
  23. package/src/components/accordion/accordion-no-bg.js +80 -0
  24. package/src/components/accordion/accordion.css.js +88 -0
  25. package/src/components/accordion/accordion.js +81 -0
  26. package/src/components/anchor/anchor-nav.css.js +15 -15
  27. package/src/components/anchor/anchor-nav.js +0 -1
  28. package/src/components/anchor/anchor.stories.js +10 -13
  29. package/src/components/badge/badge.css.js +6 -6
  30. package/src/components/badge/badge.js +1 -2
  31. package/src/components/badge/badge.stories.js +6 -6
  32. package/src/components/carousel/carousel.css.js +60 -60
  33. package/src/components/carousel/carousel.js +26 -30
  34. package/src/components/carousel/carousel.stories.js +55 -55
  35. package/src/components/checkbox/checkbox.css.js +14 -14
  36. package/src/components/divider/divider-horizontal.js +19 -14
  37. package/src/components/divider/divider-vertical.js +23 -14
  38. package/src/components/divider/divider.css.js +19 -0
  39. package/src/components/dropdown/dropdown.css.js +138 -0
  40. package/src/components/dropdown/dropdown.js +111 -0
  41. package/src/components/footer/footer-links-group.css.js +42 -0
  42. package/src/components/footer/footer-links-group.js +25 -0
  43. package/src/components/footer/footer-lp.css.js +625 -0
  44. package/src/components/footer/footer-lp.js +368 -0
  45. package/src/components/footer/footer-lp.stories.js +69 -0
  46. package/src/components/footer/footer-nav-menu.css.js +24 -0
  47. package/src/components/footer/footer-nav-menu.js +36 -0
  48. package/src/components/footer/footer.css.js +625 -0
  49. package/src/components/footer/footer.js +465 -0
  50. package/src/components/footer/footer.stories.js +60 -0
  51. package/src/components/footer/localeMap.js +1 -0
  52. package/src/components/grid/grid.css.js +38 -0
  53. package/src/components/grid/grid.js +55 -0
  54. package/src/components/header/header.css.js +81 -52
  55. package/src/components/header/header.js +19 -19
  56. package/src/components/highlight/highlight.css.js +32 -22
  57. package/src/components/highlight/highlight.js +15 -4
  58. package/src/components/highlight/highlight.stories.js +4 -4
  59. package/src/components/light-carousel/light-carousel-simple.css.js +183 -0
  60. package/src/components/light-carousel/light-carousel-simple.js +73 -0
  61. package/src/components/light-carousel/light-carousel.css.js +50 -31
  62. package/src/components/light-carousel/light-carousel.js +14 -57
  63. package/src/components/light-carousel/light-carousel.stories.js +51 -10
  64. package/src/components/link/link.css.js +41 -0
  65. package/src/components/link/link.js +54 -0
  66. package/src/components/modal/modal.css.js +75 -0
  67. package/src/components/modal/modal.js +41 -0
  68. package/src/components/modal/modal.stories.js +40 -0
  69. package/src/components/paragraph/paragraph.css.js +1 -3
  70. package/src/components/pricing-cards/new-pricing-card.js +30 -0
  71. package/src/components/pricing-cards/new-pricing.css.js +58 -0
  72. package/src/components/pricing-cards/pricing-card-actions.css.js +16 -0
  73. package/src/components/pricing-cards/pricing-card-actions.js +20 -0
  74. package/src/components/pricing-cards/pricing-card-container.css.js +41 -0
  75. package/src/components/pricing-cards/pricing-card-container.js +31 -0
  76. package/src/components/pricing-cards/pricing-card-header.css.js +70 -0
  77. package/src/components/pricing-cards/pricing-card-header.js +46 -0
  78. package/src/components/pricing-cards/pricing-card-pricing.css.js +63 -0
  79. package/src/components/pricing-cards/pricing-card-pricing.js +101 -0
  80. package/src/components/pricing-cards/pricing-card-show-more.css.js +22 -0
  81. package/src/components/pricing-cards/pricing-card-show-more.js +33 -0
  82. package/src/components/pricing-cards/pricing-card.css.js +91 -89
  83. package/src/components/pricing-cards/pricing-card.js +13 -16
  84. package/src/components/pricing-cards/pricing-feature-item.css.js +18 -0
  85. package/src/components/pricing-cards/pricing-feature-item.js +14 -0
  86. package/src/components/radio/radio.css.js +18 -18
  87. package/src/components/radio/radio.js +1 -0
  88. package/src/components/tabs/tabs.css.js +21 -11
  89. package/src/components/tabs/tabs.js +24 -18
  90. package/src/components/termsOfUse/terms.css.js +6 -6
  91. package/src/components/termsOfUse/terms.js +0 -1
  92. package/src/stories/demo.stories.js +271 -0
  93. package/src/tokens/colors.js +10 -10
  94. package/src/tokens/fonts.stories.js +5 -5
  95. package/src/tokens/layout.css +4 -3
  96. package/src/tokens/new-tokens.css +698 -0
  97. package/src/tokens/spacing.stories.js +1 -1
  98. package/src/tokens/tokens.css +1063 -0
  99. package/src/tokens/tokens.stories.js +3 -3
  100. package/src/tokens/typography.css.js +0 -4
  101. package/src/tokens/typography.stories.js +2 -2
  102. package/src/components/Input/index.js +0 -0
  103. package/src/components/highlight/highlight-s.css.js +0 -88
  104. package/src/components/highlight/highlight-s.js +0 -35
  105. package/src/components/highlight/highlight-s.stories.js +0 -22
@@ -0,0 +1,368 @@
1
+ import { LitElement, html } from 'lit';
2
+ import '../../components/divider/divider-horizontal.js';
3
+ import '../../components/divider/divider-vertical.js';
4
+ import '../../components/footer/footer-links-group.js';
5
+ import '../../components/footer/footer-nav-menu.js';
6
+ import '../../components/grid/grid.js';
7
+ import { tokens } from "../../tokens/tokens.js";
8
+ import footerCSS from './footer.css.js';
9
+ import { localeMap } from './localeMap.js';
10
+
11
+ export class BdFooterLP extends LitElement {
12
+ static properties = {
13
+ _countriesOpen : { state: true },
14
+ selectedCountry : { state: true },
15
+ currentLocale : { type: String },
16
+ maxColumnsPerRow : { type: Number },
17
+ _isMobile : { state: true },
18
+ _countriesContainer: { state: true } // Referință la containerul cu țări
19
+ };
20
+
21
+ constructor() {
22
+ super();
23
+ this._countriesOpen = false;
24
+ this.maxColumnsPerRow = 2;
25
+ this.currentLocale = 'en';
26
+ this.selectedCountry = 'Choose your country';
27
+ this._isMobile = window.innerWidth <= 768;
28
+ this._countriesContainer = null;
29
+ console.log('Constructor - isMobile:', this._isMobile, 'Window width:', window.innerWidth);
30
+ }
31
+
32
+ connectedCallback() {
33
+ super.connectedCallback();
34
+ this._initLocaleFromUrl();
35
+ window.addEventListener('resize', this._handleResize.bind(this));
36
+ console.log('Connected - isMobile:', this._isMobile);
37
+ }
38
+
39
+ disconnectedCallback() {
40
+ super.disconnectedCallback();
41
+ window.removeEventListener('resize', this._handleResize.bind(this));
42
+ }
43
+
44
+ firstUpdated() {
45
+ super.firstUpdated();
46
+ this._updateNavLinks();
47
+ // Obține referința la containerul cu țări
48
+ // this._countriesContainer = this.shadowRoot.querySelector('.footer-countries-container');
49
+ }
50
+
51
+ updated(changedProps) {
52
+ if (changedProps.has('currentLocale')) {
53
+ this._updateNavLinks();
54
+ }
55
+
56
+ // Dacă s-a deschis lista de țări, fac scroll smooth către ea
57
+ if (changedProps.has('_countriesOpen') && this._countriesOpen) {
58
+ // Obține referința la containerul cu țări doar când este deschis
59
+ this._countriesContainer = this.shadowRoot.querySelector('.footer-countries-container');
60
+ this._scrollToCountries();
61
+ }
62
+ }
63
+
64
+ _scrollToCountries() {
65
+ // Obține referința la container doar atunci când este necesar
66
+ const container = this.shadowRoot.querySelector('.footer-countries-container');
67
+ if (container) {
68
+ // Așteaptă ca render-ul să se finalizeze
69
+ setTimeout(() => {
70
+ container.scrollIntoView({
71
+ behavior: 'smooth',
72
+ block : 'start'
73
+ });
74
+ }, 100);
75
+ }
76
+ }
77
+
78
+ _scrollToTop() {
79
+ // Scroll smooth către începutul footer-ului
80
+ this.scrollIntoView({
81
+ behavior: 'smooth',
82
+ block : 'start'
83
+ });
84
+ }
85
+
86
+ _handleResize() {
87
+ this._isMobile = window.innerWidth <= 768;
88
+ const newIsMobile = window.innerWidth <= 768;
89
+ console.log('Resize - Old isMobile:', this._isMobile, 'New isMobile:', newIsMobile, 'Window width:', window.innerWidth);
90
+
91
+ if (this._isMobile !== newIsMobile) {
92
+ this._isMobile = newIsMobile;
93
+ console.log('isMobile changed to:', this._isMobile);
94
+ }
95
+ }
96
+
97
+ _initLocaleFromUrl() {
98
+ const urlLocale = window.location.pathname.split('/')[1]?.toLowerCase();
99
+
100
+ if (!urlLocale) {
101
+ this._updateNavLinks();
102
+ return;
103
+ }
104
+
105
+ // Creează o versiune normalized a localeMap cu cheile lowercase
106
+ const normalizedLocaleMap = {};
107
+ Object.entries(localeMap).forEach(([key, value]) => {
108
+ normalizedLocaleMap[key.toLowerCase()] = value;
109
+ });
110
+
111
+ // Încearcă mai întâi potrivire exactă
112
+ let country = normalizedLocaleMap[urlLocale];
113
+
114
+ // Dacă nu găsești potrivire exactă, încearcă să găsești cea mai bună potrivire
115
+ if (!country && urlLocale) {
116
+ const localeParts = urlLocale.split('-');
117
+ const language = localeParts[0];
118
+ const region = localeParts[1];
119
+
120
+ // Caută o potrivire care să înceapă cu același limbaj
121
+ const possibleMatches = Object.entries(normalizedLocaleMap)
122
+ .filter(([key]) => key.startsWith(language));
123
+
124
+ if (possibleMatches.length > 0) {
125
+ // Preferă potrivirea cu aceeași regiune dacă există
126
+ const exactRegionMatch = possibleMatches.find(([key]) => {
127
+ const keyParts = key.split('-');
128
+ const keyRegion = keyParts[1];
129
+ const regionMatch = region && keyRegion === region;
130
+ const languageOnlyMatch = !region && keyParts.length === 1;
131
+
132
+ return regionMatch || languageOnlyMatch;
133
+ });
134
+
135
+ if (exactRegionMatch) {
136
+ country = exactRegionMatch[1];
137
+ // Recuperează cheia originală din localeMap
138
+ const originalKey = Object.keys(localeMap).find(k =>
139
+ k.toLowerCase() === exactRegionMatch[0]
140
+ );
141
+ this.currentLocale = originalKey || exactRegionMatch[0];
142
+ } else {
143
+ // Altfel, ia prima potrivire
144
+ country = possibleMatches[0][1];
145
+ const originalKey = Object.keys(localeMap).find(k =>
146
+ k.toLowerCase() === possibleMatches[0][0]
147
+ );
148
+ this.currentLocale = originalKey || possibleMatches[0][0];
149
+ }
150
+ }
151
+ }
152
+
153
+ // Setează valorile pentru țară și locale
154
+ if (country) {
155
+ this.selectedCountry = country;
156
+ }
157
+
158
+ if (this.currentLocale !== urlLocale) {
159
+ const originalKey = Object.keys(localeMap).find(k =>
160
+ k.toLowerCase() === urlLocale
161
+ );
162
+ this.currentLocale = originalKey || urlLocale;
163
+ }
164
+
165
+ // Actualizează linkurile de navigație
166
+ this._updateNavLinks();
167
+ }
168
+
169
+ _toggleCountries() {
170
+ this._countriesOpen = !this._countriesOpen;
171
+
172
+ // Dacă se închide dropdown-ul, fac scroll înapoi sus
173
+ if (!this._countriesOpen) {
174
+ this._scrollToTop();
175
+ }
176
+ }
177
+
178
+ _closeCountries() {
179
+ this._countriesOpen = false;
180
+
181
+ // Doar pentru desktop, facem scroll înapoi sus
182
+ if (!this._isMobile) {
183
+ this._scrollToTop();
184
+ }
185
+ }
186
+
187
+ _handleCountryClick(e, countryLabel, locale) {
188
+ e.preventDefault();
189
+ this._selectCountry(countryLabel);
190
+
191
+ // Redirect către pagina cu noul locale
192
+ const newPath = `/${locale.toLowerCase()}/`;
193
+ window.location.href = newPath;
194
+ }
195
+
196
+ _selectCountry(countryLabel) {
197
+ this.selectedCountry = countryLabel;
198
+ this._countriesOpen = false;
199
+
200
+ // Găsește locale-ul corespunzător pentru țara selectată
201
+ const localeEntry = Object.entries(localeMap).find(
202
+ ([, country]) => country === countryLabel
203
+ );
204
+
205
+ if (localeEntry) {
206
+ this.currentLocale = localeEntry[0];
207
+ }
208
+
209
+ this._updateNavLinks();
210
+ this._scrollToTop();
211
+ }
212
+
213
+ getCountriesList() {
214
+ return Object.entries(localeMap).map(([locale, country]) => ({
215
+ locale,
216
+ label: country
217
+ }));
218
+ }
219
+
220
+ renderQuickLinksSection(slotName) {
221
+ const assignedElements = this.shadowRoot?.querySelector(`slot[name="${slotName}"]`)?.assignedElements({ flatten: true }) || [];
222
+ if (assignedElements.length === 0) return null;
223
+
224
+ const maxCols = this.maxColumnsPerRow || 3;
225
+ const rows = Math.ceil(assignedElements.length / maxCols);
226
+
227
+ const groupedRows = Array.from({ length: rows }, (_, rowIndex) => {
228
+ const start = rowIndex * maxCols;
229
+ return assignedElements.slice(start, start + maxCols);
230
+ });
231
+
232
+ return html`
233
+ <div class="quick-links-section" style="display: flex; flex-direction: column; gap: 1rem;">
234
+ ${groupedRows.map(row => html`
235
+ <div style="display: grid; grid-template-columns: repeat(${row.length}, 1fr); gap: 1rem;">
236
+ ${row.map(el => html`${el}`)}
237
+ </div>
238
+ `)}
239
+ </div>
240
+ `;
241
+ }
242
+
243
+ get locale() {
244
+ const val = (this.currentLocale || 'en').toLowerCase();
245
+ return val;
246
+ }
247
+
248
+ _updateSlotStyles() {
249
+ const isMobile = window.innerWidth <= 768;
250
+ const slot = this.shadowRoot.querySelector('slot[name="nav"]');
251
+ const assignedElements = slot.assignedElements();
252
+
253
+ assignedElements.forEach(element => {
254
+ if (isMobile) {
255
+ element.style.color = '#151719';
256
+ element.style.setProperty('color', '#151719', 'important');
257
+ } else {
258
+ element.style.color = '';
259
+ element.style.removeProperty('color');
260
+ }
261
+ });
262
+ }
263
+
264
+ _updateNavLinks() {
265
+ // Actualizează linkurile care sunt acum în shadow DOM
266
+ const links = this.shadowRoot.querySelectorAll('.footer-nav-main a');
267
+ const linkPaths = ['consumer', 'small-business', 'business', 'partners'];
268
+ const currentLocale = this.locale;
269
+
270
+ links.forEach((link, index) => {
271
+ if (index < linkPaths.length) {
272
+ link.href = `/${currentLocale}/${linkPaths[index]}/`;
273
+ }
274
+ });
275
+ }
276
+
277
+ render() {
278
+ const year = new Date().getFullYear();
279
+ const showAnpc = this.locale.startsWith('ro');
280
+ const showImpressum = this.locale === 'de-de' || this.locale === 'de';
281
+
282
+ const masterbrandUrl = this._isMobile
283
+ ? '/assets/Bitdefender-Masterbrand_mobile.png'
284
+ : '/assets/Bitdefender-Masterbrand.png';
285
+
286
+ const anpcUrl = this._isMobile
287
+ ? '/assets/anpc_mobile.png'
288
+ : '/assets/anpc.png';
289
+
290
+ const logoUrl = '/assets/BD_logo.png';
291
+
292
+
293
+
294
+ return html`
295
+ <div class="footer-top-bleed">
296
+ <div class="container">
297
+ <div class="footer-top">
298
+ <div class="footer-logo">
299
+ <slot name="logo">
300
+ <span><img src="${logoUrl}" alt="Bitdefender Logo"></span>
301
+ </slot>
302
+ </div>
303
+ <div class="footer-top-right">
304
+ <slot name="top-right">
305
+ <div slot="top-right">
306
+ <span slot="logo">
307
+ <img src="${masterbrandUrl}" alt="Bitdefender Masterbrand">
308
+ </span>
309
+ </div>
310
+ </slot>
311
+ </div>
312
+ </div>
313
+ </div>
314
+ </div>
315
+
316
+ <footer class="container">
317
+
318
+ <div class="footer-middle-line-lp">
319
+ <bd-footer-nav>
320
+ <div class="footer-nav-main">
321
+ <a href="legal/">Legal Information</a>
322
+ <bd-divider-vertical color="white" height="18px"></bd-divider-vertical>
323
+ <a href="site/view/legal-privacy-policy-for-bitdefender-websites/">Privacy Policy</a>
324
+ <bd-divider-vertical color="white" height="18px"></bd-divider-vertical>
325
+ <a href="sitemap/">Site Map</a>
326
+ <bd-divider-vertical color="white" height="18px"></bd-divider-vertical>
327
+ <a href="company/">Company</a>
328
+ <bd-divider-vertical color="white" height="18px"></bd-divider-vertical>
329
+ <a href="https://www.bitdefender.com/consumer/support/">Contact Us</a>
330
+ <bd-divider-vertical color="white" height="18px"></bd-divider-vertical>
331
+ <a href="#">Privacy Settings</a>
332
+ ${showImpressum
333
+ ? html`
334
+ <bd-divider-vertical color="white" height="18px"></bd-divider-vertical>
335
+ <a href="#" class="impressum-link">Impressum</a>
336
+ `
337
+ : ''}
338
+ </div>
339
+ </bd-footer-nav>
340
+ <bd-divider-horizontal width="100%" color="white" opacity="0.25"></bd-divider-horizontal>
341
+
342
+ </div>
343
+
344
+
345
+ <div class="footer-extra">
346
+ <div class="footer-copy">Copyright © 1997 - ${year} Bitdefender</div>
347
+ ${showAnpc
348
+ ? html`
349
+ <div class="footer-anpc-lp">
350
+ <slot name="anpc">
351
+ <div slot="anpc">
352
+ <img src="${anpcUrl}" alt="Certificat" />
353
+ </div>
354
+ </slot>
355
+ </div>
356
+ `
357
+ : null}
358
+
359
+ </div>
360
+
361
+
362
+ </footer>
363
+ `;
364
+ }
365
+ static styles = [tokens, footerCSS];
366
+ }
367
+
368
+ customElements.define('bd-footer-lp', BdFooterLP);
@@ -0,0 +1,69 @@
1
+ // BdFooterLP.stories.js
2
+ import { html } from 'lit';
3
+ import './footer-lp.js';
4
+
5
+ export default {
6
+ title : 'Components/Footer/BdFooterLP',
7
+ component: 'bd-footer-lp',
8
+ argTypes : {
9
+ currentLocale: {
10
+ control : 'text',
11
+ description: 'Codul de locale curent (ex: en, ro, de-de)',
12
+ table : { defaultValue: { summary: 'en' } }
13
+ },
14
+ maxColumnsPerRow: {
15
+ control : { type: 'number', min: 1, max: 4 },
16
+ description: 'Numărul maxim de coloane pentru quick links',
17
+ table : { defaultValue: { summary: 2 } }
18
+ },
19
+ selectedCountry: {
20
+ control : 'text',
21
+ description: 'Țara selectată în footer',
22
+ table : { defaultValue: { summary: 'Choose your country' } }
23
+ },
24
+ _isMobile: {
25
+ control : 'boolean',
26
+ description: 'Forțează modul mobile pentru testare',
27
+ table : { defaultValue: { summary: false } }
28
+ },
29
+ _countriesOpen: {
30
+ control : 'boolean',
31
+ description: 'Controlează dacă dropdown-ul cu țări este deschis',
32
+ table : { defaultValue: { summary: false } }
33
+ }
34
+ }
35
+ };
36
+
37
+ const Template = (args) => {
38
+ return html`
39
+ <bd-footer-lp
40
+ .currentLocale=${args.currentLocale}
41
+ .maxColumnsPerRow=${args.maxColumnsPerRow}
42
+ .selectedCountry=${args.selectedCountry}
43
+ ._isMobile=${args._isMobile}
44
+ ._countriesOpen=${args._countriesOpen}
45
+ >
46
+ <span slot="logo">
47
+ <img src="/assets/BD_logo.png" alt="Bitdefender Logo" style="height: 40px;" />
48
+ </span>
49
+
50
+ <div slot="top-right">
51
+ <img src="/assets/Bitdefender-Masterbrand.png" alt="Masterbrand" style="height: 40px;" />
52
+ </div>
53
+
54
+ <div slot="anpc">
55
+ <img src="/assets/anpc.png" alt="Certificat ANPC" style="height: 30px;" />
56
+ </div>
57
+ </bd-footer-lp>
58
+ `;
59
+ };
60
+
61
+ export const Default = Template.bind({});
62
+ Default.args = {
63
+ currentLocale : 'en',
64
+ maxColumnsPerRow: 2,
65
+ selectedCountry : 'Choose your country',
66
+ _isMobile : false,
67
+ _countriesOpen : false
68
+ };
69
+
@@ -0,0 +1,24 @@
1
+ import { css } from 'lit';
2
+
3
+ export default css`
4
+
5
+ .footer-nav-main {
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: flex-start;
9
+ gap: 1rem;
10
+ flex-wrap: wrap;
11
+ margin-top: 1rem;
12
+ margin-bottom: 1rem;
13
+ font-size: var(--typography-body-regular-fontSize);
14
+ font-family: var(--typography-fontFamily-sans, 'IBM Plex Sans');
15
+ font-weight: var(--typography-label-default-fontWeight)
16
+ }
17
+
18
+ .footer-nav-main.footer-nav-bold {
19
+ font-weight: var(--typography-heading-h3-fontWeight);
20
+ }
21
+ a{
22
+ color: white;
23
+ text-decoration: none}
24
+ `;
@@ -0,0 +1,36 @@
1
+ import { LitElement, html } from 'lit';
2
+ import { tokens } from '../../tokens/tokens.js';
3
+ import '../divider/divider-vertical.js';
4
+ import navCSS from './footer-nav-menu.css.js';
5
+
6
+ export class BdFooterNav extends LitElement {
7
+ static properties = {
8
+ bold: { type: Boolean }
9
+ };
10
+
11
+ constructor() {
12
+ super();
13
+ this.bold = false;
14
+ }
15
+
16
+ render() {
17
+ const classes = {
18
+ 'footer-nav-main': true,
19
+ 'footer-nav-bold': this.bold
20
+ };
21
+ const classString = Object.entries(classes)
22
+ .filter(([, value]) => value)
23
+ .map(([key]) => key)
24
+ .join(' ');
25
+
26
+ return html`
27
+ <nav class=${classString}>
28
+ <slot></slot>
29
+ </nav>
30
+ `;
31
+ }
32
+
33
+ static styles = [tokens, navCSS];
34
+ }
35
+
36
+ customElements.define('bd-footer-nav', BdFooterNav);