@repobit/dex-system-design 0.11.0 → 0.14.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 +35 -0
- package/package.json +2 -2
- package/src/assets/icons/Identity_protection.png +0 -0
- package/src/assets/icons/device_protection.png +0 -0
- package/src/assets/icons/financial_insurance.png +0 -0
- package/src/assets/icons/privacy_protection.png +0 -0
- package/src/assets/icons/user_guide.png +0 -0
- package/src/components/Button/Button.js +19 -16
- package/src/components/Button/button.css.js +18 -16
- package/src/components/Button/icons.js +8 -8
- package/src/components/FAQ/faq.css.js +48 -49
- package/src/components/FAQ/faq.js +0 -86
- package/src/components/Input/Input.js +68 -6
- package/src/components/Input/custom-form.stories.js +88 -0
- package/src/components/Input/input-clipboard.css.js +168 -0
- package/src/components/Input/input-clipboard.js +137 -0
- package/src/components/Input/input.css.js +122 -42
- package/src/components/accordion/accordion-bg.css.js +117 -0
- package/src/components/accordion/accordion-bg.js +80 -0
- package/src/components/accordion/accordion-no-bg.css.js +114 -0
- package/src/components/accordion/accordion-no-bg.js +80 -0
- package/src/components/accordion/accordion.css.js +88 -0
- package/src/components/accordion/accordion.js +81 -0
- package/src/components/anchor/anchor-nav.css.js +15 -15
- package/src/components/anchor/anchor-nav.js +0 -1
- package/src/components/anchor/anchor.stories.js +10 -13
- package/src/components/badge/badge.css.js +6 -6
- package/src/components/badge/badge.js +1 -2
- package/src/components/badge/badge.stories.js +6 -6
- package/src/components/carousel/carousel.css.js +60 -60
- package/src/components/carousel/carousel.js +26 -30
- package/src/components/carousel/carousel.stories.js +55 -55
- package/src/components/checkbox/checkbox.css.js +14 -14
- package/src/components/divider/divider-horizontal.js +19 -14
- package/src/components/divider/divider-vertical.js +23 -14
- package/src/components/divider/divider.css.js +19 -0
- package/src/components/dropdown/dropdown.css.js +138 -0
- package/src/components/dropdown/dropdown.js +111 -0
- package/src/components/footer/footer-links-group.css.js +42 -0
- package/src/components/footer/footer-links-group.js +25 -0
- package/src/components/footer/footer-lp.css.js +625 -0
- package/src/components/footer/footer-lp.js +368 -0
- package/src/components/footer/footer-lp.stories.js +69 -0
- package/src/components/footer/footer-nav-menu.css.js +24 -0
- package/src/components/footer/footer-nav-menu.js +36 -0
- package/src/components/footer/footer.css.js +625 -0
- package/src/components/footer/footer.js +465 -0
- package/src/components/footer/footer.stories.js +60 -0
- package/src/components/footer/localeMap.js +1 -0
- package/src/components/grid/grid.css.js +38 -0
- package/src/components/grid/grid.js +55 -0
- package/src/components/header/header.css.js +81 -52
- package/src/components/header/header.js +19 -19
- package/src/components/highlight/highlight.css.js +32 -22
- package/src/components/highlight/highlight.js +15 -4
- package/src/components/highlight/highlight.stories.js +4 -4
- package/src/components/light-carousel/light-carousel-simple.css.js +183 -0
- package/src/components/light-carousel/light-carousel-simple.js +73 -0
- package/src/components/light-carousel/light-carousel.css.js +50 -31
- package/src/components/light-carousel/light-carousel.js +14 -57
- package/src/components/light-carousel/light-carousel.stories.js +51 -10
- package/src/components/link/link.css.js +41 -0
- package/src/components/link/link.js +54 -0
- package/src/components/modal/modal.css.js +75 -0
- package/src/components/modal/modal.js +41 -0
- package/src/components/modal/modal.stories.js +40 -0
- package/src/components/paragraph/paragraph.css.js +1 -3
- package/src/components/pricing-cards/new-pricing-card.js +30 -0
- package/src/components/pricing-cards/new-pricing.css.js +58 -0
- package/src/components/pricing-cards/pricing-card-actions.css.js +16 -0
- package/src/components/pricing-cards/pricing-card-actions.js +20 -0
- package/src/components/pricing-cards/pricing-card-container.css.js +41 -0
- package/src/components/pricing-cards/pricing-card-container.js +31 -0
- package/src/components/pricing-cards/pricing-card-header.css.js +70 -0
- package/src/components/pricing-cards/pricing-card-header.js +46 -0
- package/src/components/pricing-cards/pricing-card-pricing.css.js +63 -0
- package/src/components/pricing-cards/pricing-card-pricing.js +101 -0
- package/src/components/pricing-cards/pricing-card-show-more.css.js +22 -0
- package/src/components/pricing-cards/pricing-card-show-more.js +33 -0
- package/src/components/pricing-cards/pricing-card.css.js +91 -89
- package/src/components/pricing-cards/pricing-card.js +13 -16
- package/src/components/pricing-cards/pricing-feature-item.css.js +18 -0
- package/src/components/pricing-cards/pricing-feature-item.js +14 -0
- package/src/components/radio/radio.css.js +18 -18
- package/src/components/radio/radio.js +1 -0
- package/src/components/tabs/tabs.css.js +21 -11
- package/src/components/tabs/tabs.js +24 -18
- package/src/components/termsOfUse/terms.css.js +6 -6
- package/src/components/termsOfUse/terms.js +0 -1
- package/src/stories/demo.stories.js +270 -0
- package/src/tokens/layout.css +1 -0
- package/src/tokens/tokens.css +412 -0
- package/src/components/highlight/highlight-s.css.js +0 -88
- package/src/components/highlight/highlight-s.js +0 -35
- package/src/components/highlight/highlight-s.stories.js +0 -22
- package/src/tokens/fonts.css +0 -166
- package/src/tokens/tokens.js +0 -281
|
@@ -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);
|