@repobit/dex-system-design 0.18.1 → 0.19.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.
- package/CHANGELOG.md +12 -0
- package/package.json +15 -4
- package/src/components/anchor/anchor.stories.js +9 -9
- package/src/components/badge/badge.css.js +52 -5
- package/src/components/badge/badge.js +58 -5
- package/src/components/badge/badge.stories.js +183 -15
- package/src/components/carousel/carousel.css.js +13 -13
- package/src/components/footer/footer-links-group.css.js +1 -5
- package/src/components/footer/footer-lp.css.js +49 -533
- package/src/components/footer/footer-lp.js +86 -203
- package/src/components/footer/footer-nav-menu.css.js +33 -19
- package/src/components/footer/footer-nav-menu.js +3 -3
- package/src/components/footer/footer.css.js +263 -193
- package/src/components/footer/footer.js +163 -166
- package/src/tokens/tokens.js +24 -46
- package/src/components/Button/icons.css +0 -5
- package/src/components/Button/index.js +0 -0
- package/src/components/FAQ/faq.css.js +0 -117
- package/src/components/FAQ/faq.js +0 -0
- package/src/components/FAQ/faq.stories.js +0 -66
|
@@ -10,30 +10,20 @@ import { localeMap } from './localeMap.js';
|
|
|
10
10
|
|
|
11
11
|
export class BdFooterLP extends LitElement {
|
|
12
12
|
static properties = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
currentLocale : { type: String },
|
|
16
|
-
maxColumnsPerRow : { type: Number },
|
|
17
|
-
_isMobile : { state: true },
|
|
18
|
-
_countriesContainer: { state: true } // Referință la containerul cu țări
|
|
13
|
+
currentLocale: { type: String },
|
|
14
|
+
_isMobile : { state: true }
|
|
19
15
|
};
|
|
20
16
|
|
|
21
17
|
constructor() {
|
|
22
18
|
super();
|
|
23
|
-
this._countriesOpen = false;
|
|
24
|
-
this.maxColumnsPerRow = 2;
|
|
25
19
|
this.currentLocale = 'en';
|
|
26
|
-
this.selectedCountry = 'Choose your country';
|
|
27
20
|
this._isMobile = window.innerWidth <= 768;
|
|
28
|
-
this._countriesContainer = null;
|
|
29
|
-
console.log('Constructor - isMobile:', this._isMobile, 'Window width:', window.innerWidth);
|
|
30
21
|
}
|
|
31
22
|
|
|
32
23
|
connectedCallback() {
|
|
33
24
|
super.connectedCallback();
|
|
34
|
-
this._initLocaleFromUrl();
|
|
25
|
+
this._initLocaleFromUrl(); // Adaugă inițializarea locale-ului din URL
|
|
35
26
|
window.addEventListener('resize', this._handleResize.bind(this));
|
|
36
|
-
console.log('Connected - isMobile:', this._isMobile);
|
|
37
27
|
}
|
|
38
28
|
|
|
39
29
|
disconnectedCallback() {
|
|
@@ -43,54 +33,12 @@ export class BdFooterLP extends LitElement {
|
|
|
43
33
|
|
|
44
34
|
firstUpdated() {
|
|
45
35
|
super.firstUpdated();
|
|
46
|
-
this.
|
|
47
|
-
// Obține referința la containerul cu țări
|
|
48
|
-
// this._countriesContainer = this.shadowRoot.querySelector('.footer-countries-container');
|
|
36
|
+
this._toggleImpressumVisibility(); // Apelează la initializare
|
|
49
37
|
}
|
|
50
38
|
|
|
51
39
|
updated(changedProps) {
|
|
52
40
|
if (changedProps.has('currentLocale')) {
|
|
53
|
-
this.
|
|
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);
|
|
41
|
+
this._toggleImpressumVisibility(); // Apelează când se schimbă locale-ul
|
|
94
42
|
}
|
|
95
43
|
}
|
|
96
44
|
|
|
@@ -98,7 +46,6 @@ export class BdFooterLP extends LitElement {
|
|
|
98
46
|
const urlLocale = window.location.pathname.split('/')[1]?.toLowerCase();
|
|
99
47
|
|
|
100
48
|
if (!urlLocale) {
|
|
101
|
-
this._updateNavLinks();
|
|
102
49
|
return;
|
|
103
50
|
}
|
|
104
51
|
|
|
@@ -150,134 +97,60 @@ export class BdFooterLP extends LitElement {
|
|
|
150
97
|
}
|
|
151
98
|
}
|
|
152
99
|
|
|
153
|
-
// Setează valorile pentru țară și locale
|
|
154
|
-
if (country) {
|
|
155
|
-
this.selectedCountry = country;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
100
|
if (this.currentLocale !== urlLocale) {
|
|
159
101
|
const originalKey = Object.keys(localeMap).find(k =>
|
|
160
102
|
k.toLowerCase() === urlLocale
|
|
161
103
|
);
|
|
162
104
|
this.currentLocale = originalKey || urlLocale;
|
|
163
105
|
}
|
|
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
106
|
}
|
|
186
107
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
this.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
108
|
+
_toggleImpressumVisibility() {
|
|
109
|
+
const showImpressum = this.locale === 'de-de' || this.locale === 'de';
|
|
110
|
+
const slot = this.shadowRoot?.querySelector('slot[name="secondary-nav"]');
|
|
111
|
+
const assignedElements = slot?.assignedElements({ flatten: true }) || [];
|
|
112
|
+
|
|
113
|
+
if (assignedElements.length > 0) {
|
|
114
|
+
const footerNav = assignedElements[0];
|
|
115
|
+
const impressumLink = footerNav.querySelector('.impressum-link');
|
|
116
|
+
|
|
117
|
+
// Găsește separatorul care precede link-ul Impressum
|
|
118
|
+
let impressumDivider = null;
|
|
119
|
+
if (impressumLink) {
|
|
120
|
+
impressumDivider = impressumLink.previousElementSibling;
|
|
121
|
+
|
|
122
|
+
// Verifică dacă elementul anterior este un divider și este imediat înainte
|
|
123
|
+
if (impressumDivider && impressumDivider.tagName === 'BD-DIVIDER-VERTICAL' &&
|
|
124
|
+
impressumDivider.nextElementSibling === impressumLink) {
|
|
125
|
+
// Este separatorul corect
|
|
126
|
+
} else {
|
|
127
|
+
impressumDivider = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
199
130
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
);
|
|
131
|
+
if (impressumLink) {
|
|
132
|
+
// Ascunde/afișează link-ul Impressum
|
|
133
|
+
impressumLink.style.display = showImpressum ? '' : 'none';
|
|
204
134
|
|
|
205
|
-
|
|
206
|
-
|
|
135
|
+
// Ascunde/afișează și separatorul dinaintea lui
|
|
136
|
+
if (impressumDivider && impressumDivider.tagName === 'BD-DIVIDER-VERTICAL') {
|
|
137
|
+
impressumDivider.style.display = showImpressum ? '' : 'none';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
207
140
|
}
|
|
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
141
|
}
|
|
219
142
|
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
`;
|
|
143
|
+
_handleResize() {
|
|
144
|
+
this._isMobile = window.innerWidth <= 768;
|
|
241
145
|
}
|
|
242
146
|
|
|
243
147
|
get locale() {
|
|
244
|
-
|
|
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
|
-
});
|
|
148
|
+
return (this.currentLocale || 'en').toLowerCase();
|
|
275
149
|
}
|
|
276
150
|
|
|
277
151
|
render() {
|
|
278
152
|
const year = new Date().getFullYear();
|
|
279
153
|
const showAnpc = this.locale.startsWith('ro');
|
|
280
|
-
const showImpressum = this.locale === 'de-de' || this.locale === 'de';
|
|
281
154
|
|
|
282
155
|
const masterbrandUrl = this._isMobile
|
|
283
156
|
? '/assets/Bitdefender-Masterbrand_mobile.png'
|
|
@@ -289,8 +162,6 @@ export class BdFooterLP extends LitElement {
|
|
|
289
162
|
|
|
290
163
|
const logoUrl = '/assets/BD_logo.png';
|
|
291
164
|
|
|
292
|
-
|
|
293
|
-
|
|
294
165
|
return html`
|
|
295
166
|
<div class="footer-top-bleed">
|
|
296
167
|
<div class="container">
|
|
@@ -302,8 +173,8 @@ export class BdFooterLP extends LitElement {
|
|
|
302
173
|
</div>
|
|
303
174
|
<div class="footer-top-right">
|
|
304
175
|
<slot name="top-right">
|
|
305
|
-
<div
|
|
306
|
-
<span
|
|
176
|
+
<div>
|
|
177
|
+
<span>
|
|
307
178
|
<img src="${masterbrandUrl}" alt="Bitdefender Masterbrand">
|
|
308
179
|
</span>
|
|
309
180
|
</div>
|
|
@@ -314,54 +185,66 @@ export class BdFooterLP extends LitElement {
|
|
|
314
185
|
</div>
|
|
315
186
|
|
|
316
187
|
<footer class="container">
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
|
|
188
|
+
<div class="footer-main-content">
|
|
189
|
+
<slot name="content"></slot>
|
|
342
190
|
</div>
|
|
343
191
|
|
|
344
|
-
|
|
192
|
+
<div class="footer-secondary-nav">
|
|
193
|
+
<slot name="secondary-nav"></slot>
|
|
194
|
+
</div>
|
|
195
|
+
<bd-divider-horizontal width="100%" color="white" opacity="0.25"></bd-divider-horizontal>
|
|
345
196
|
<div class="footer-extra">
|
|
346
|
-
<div class="footer-copy">
|
|
197
|
+
<div class="footer-copy">
|
|
198
|
+
<slot name="copyright">
|
|
199
|
+
Copyright © 1997 - ${year} Bitdefender
|
|
200
|
+
</slot>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
347
203
|
${showAnpc
|
|
348
204
|
? html`
|
|
349
205
|
<div class="footer-anpc-lp">
|
|
350
206
|
<slot name="anpc">
|
|
351
|
-
<
|
|
352
|
-
<img src="${anpcUrl}" alt="Certificat" />
|
|
353
|
-
</div>
|
|
207
|
+
<img src="${anpcUrl}" alt="Certificat" />
|
|
354
208
|
</slot>
|
|
355
209
|
</div>
|
|
356
210
|
`
|
|
357
|
-
:
|
|
358
|
-
|
|
211
|
+
: ''}
|
|
359
212
|
</div>
|
|
360
|
-
|
|
361
|
-
|
|
362
213
|
</footer>
|
|
363
214
|
`;
|
|
364
215
|
}
|
|
216
|
+
|
|
217
|
+
// Metodă specifică pentru secondary-nav care verifică și elementele custom
|
|
218
|
+
_hasSecondaryNavContent() {
|
|
219
|
+
const slot = this.shadowRoot?.querySelector('slot[name="secondary-nav"]');
|
|
220
|
+
if (!slot) return false;
|
|
221
|
+
|
|
222
|
+
const assignedNodes = slot.assignedNodes({ flatten: true });
|
|
223
|
+
|
|
224
|
+
// Verifică dacă există noduri care nu sunt doar spații albe
|
|
225
|
+
const hasContent = assignedNodes.some(node => {
|
|
226
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
230
|
+
return node.textContent.trim() !== '';
|
|
231
|
+
}
|
|
232
|
+
return false;
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
return hasContent;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Metodă helper pentru a verifica dacă un slot are conținut
|
|
239
|
+
_hasSlotContent(slotName) {
|
|
240
|
+
const slot = this.shadowRoot?.querySelector(`slot[name="${slotName}"]`);
|
|
241
|
+
if (!slot) return false;
|
|
242
|
+
|
|
243
|
+
const assignedNodes = slot.assignedNodes({ flatten: true });
|
|
244
|
+
return assignedNodes.length > 0 &&
|
|
245
|
+
!(assignedNodes.length === 1 && assignedNodes[0].nodeType === Node.TEXT_NODE && assignedNodes[0].textContent.trim() === '');
|
|
246
|
+
}
|
|
247
|
+
|
|
365
248
|
static styles = [tokens, footerCSS];
|
|
366
249
|
}
|
|
367
250
|
|
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
2
|
|
|
3
3
|
export default css`
|
|
4
|
+
.footer-nav-main {
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: flex-start;
|
|
8
|
+
gap: var(--spacing-16);
|
|
9
|
+
flex-wrap: wrap;
|
|
10
|
+
font-size: var(--typography-body-regular-fontSize);
|
|
11
|
+
font-family: var(--typography-fontFamily-sans, 'IBM Plex Sans');
|
|
12
|
+
font-weight: var(--typography-label-default-fontWeight);
|
|
13
|
+
}
|
|
4
14
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
}
|
|
15
|
+
.footer-nav-main.footer-nav-bold {
|
|
16
|
+
font-weight: var(--typography-heading-h3-fontWeight);
|
|
17
|
+
}
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
/* Corect: stilizare pentru elementele slottate */
|
|
20
|
+
::slotted(a) {
|
|
21
|
+
color: white !important;
|
|
22
|
+
text-decoration: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Stiluri pentru mobil */
|
|
26
|
+
@media (max-width: 768px) {
|
|
27
|
+
.footer-nav-main {
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
align-items: flex-start;
|
|
30
|
+
gap: var(--spacing-16);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.footer-nav-main ::slotted(bd-divider-vertical) {
|
|
34
|
+
display: none !important;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
`;
|