@repobit/dex-system-design 0.5.0 → 0.6.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 +9 -0
- package/package.json +4 -3
- package/src/assets/images/bd-header-img.jpg +0 -0
- package/src/assets/images/bd-header-us.jpg +0 -0
- package/src/components/Button/Button.js +115 -3
- package/src/components/Button/button.css.js +80 -43
- package/src/components/Button/button.stories.js +83 -7
- package/src/components/FAQ/faq.css.js +27 -16
- package/src/components/FAQ/faq.js +23 -114
- package/src/components/FAQ/faq.stories.js +41 -20
- package/src/components/Input/Input.js +2 -2
- package/src/components/Input/input.css.js +1 -1
- package/src/components/anchor/anchor-nav.css.js +92 -0
- package/src/components/anchor/anchor-nav.js +121 -0
- package/src/components/anchor/anchor.stories.js +134 -0
- package/src/components/badge/badge.css.js +27 -0
- package/src/components/badge/badge.js +30 -0
- package/src/components/badge/badge.stories.js +36 -0
- package/src/components/carousel/carousel.css.js +36 -19
- package/src/components/carousel/carousel.js +149 -99
- package/src/components/carousel/carousel.stories.js +202 -46
- package/src/components/checkbox/checkbox.css.js +132 -0
- package/src/components/checkbox/checkbox.js +130 -0
- package/src/components/checkbox/checkbox.stories.js +63 -0
- package/src/components/divider/divider-horizontal.js +29 -0
- package/src/components/divider/divider-vertical.js +32 -0
- package/src/components/divider/divider.css.js +0 -0
- package/src/components/divider/divider.stories.js +77 -0
- package/src/components/header/header.css.js +248 -0
- package/src/components/header/header.js +87 -0
- package/src/components/header/header.stories.js +57 -0
- package/src/components/highlight/highlight-s.css.js +88 -0
- package/src/components/highlight/highlight-s.js +35 -0
- package/src/components/highlight/highlight-s.stories.js +22 -0
- package/src/components/highlight/highlight.css.js +119 -0
- package/src/components/highlight/highlight.js +60 -0
- package/src/components/highlight/highlight.stories.js +53 -0
- package/src/components/light-carousel/light-carousel.css.js +18 -10
- package/src/components/light-carousel/light-carousel.js +29 -16
- package/src/components/light-carousel/light-carousel.stories.js +9 -7
- package/src/components/paragraph/paragraph.css.js +1 -1
- package/src/components/pricing-cards/pricing-card.css.js +138 -3
- package/src/components/pricing-cards/pricing-card.js +63 -82
- package/src/components/pricing-cards/pricing-card.stories.js +1 -0
- package/src/components/radio/radio.css.js +168 -0
- package/src/components/radio/radio.js +222 -0
- package/src/components/radio/radio.stories.js +103 -0
- package/src/components/tabs/tabs.css.js +26 -8
- package/src/components/tabs/tabs.js +19 -12
- package/src/components/termsOfUse/terms.css.js +7 -1
- package/src/tokens/fonts.stories.js +73 -0
- package/src/tokens/spacing.stories.js +56 -0
- package/src/tokens/tokens-grid.stories.js +83 -0
- package/src/tokens/tokens.css +116 -1
- package/src/tokens/tokens.stories.js +67 -0
- package/src/tokens/typography.stories.js +69 -0
- package/src/tokens/tokens.js +0 -206
- /package/src/assets/{icons → images}/tabs-img1.png +0 -0
- /package/src/assets/{icons → images}/tabs-img2.png +0 -0
- /package/src/assets/{icons → images}/tabs-img3.png +0 -0
|
@@ -10,111 +10,8 @@ class FaqSection extends LitElement {
|
|
|
10
10
|
|
|
11
11
|
constructor() {
|
|
12
12
|
super();
|
|
13
|
-
// this.title = "Questions? Answers.";
|
|
14
|
-
|
|
15
|
-
// this.faqs = [
|
|
16
|
-
// {
|
|
17
|
-
// question:
|
|
18
|
-
// "How does Bitdefender Internet Security protect me against cyber threats?",
|
|
19
|
-
// answer: `
|
|
20
|
-
// <p>Bitdefender Internet Security provides the best protection in the industry, as proven by the last 10 years of independent test scores.</p>
|
|
21
|
-
// <p>Bitdefender Internet Security has won the Product of The Year award from AV-Comparatives.</p>
|
|
22
|
-
// <p>You get a wealth of advanced security and privacy features for Windows - plus many bonus features, including secure VPN, Firewall and Parental Control.</p>
|
|
23
|
-
// `,
|
|
24
|
-
// open: false,
|
|
25
|
-
// },
|
|
26
|
-
// {
|
|
27
|
-
// question:
|
|
28
|
-
// "Does Bitdefender Internet Security protect me against ransomware?",
|
|
29
|
-
// answer: `
|
|
30
|
-
// <p>Bitdefender Internet Security offers unbeatable ransomware protection that keeps your documents, pictures and videos safe from all known and emerging cyber threats.</p>
|
|
31
|
-
// <p>This security solution can identify even the latest ransomware families through the use of multiple layers of protection.</p>
|
|
32
|
-
// `,
|
|
33
|
-
// open: false,
|
|
34
|
-
// },
|
|
35
|
-
// {
|
|
36
|
-
// question:
|
|
37
|
-
// "What type of devices and operating systems does Bitdefender Internet Security cover?",
|
|
38
|
-
// answer: `
|
|
39
|
-
// <p>Bitdefender Internet Security is a security software designed especially for Windows PCs.</p>
|
|
40
|
-
// `,
|
|
41
|
-
// open: false,
|
|
42
|
-
// },
|
|
43
|
-
// {
|
|
44
|
-
// question: "Why do I need Bitdefender Internet Security on Windows 10?",
|
|
45
|
-
// answer: `
|
|
46
|
-
// <p>Windows 10 lets you run the security program of your choosing, and Bitdefender Internet Security is the perfect option if you need the best protection available today.</p>
|
|
47
|
-
// `,
|
|
48
|
-
// open: false,
|
|
49
|
-
// },
|
|
50
|
-
// {
|
|
51
|
-
// question:
|
|
52
|
-
// "How does Bitdefender Internet Security compare to other Bitdefender security products?",
|
|
53
|
-
// answer: `
|
|
54
|
-
// <p>Bitdefender Internet Security is a security software designed especially for Windows PCs.</p>
|
|
55
|
-
// <p>Need security for all operating systems? Bitdefender Total Security offers cross-platform protection that covers Windows PCs, Macs, Smartphones and Tablets running Android or iOS for up to 10 devices.</p>
|
|
56
|
-
// <p>Need more devices? Bitdefender Family Pack includes Bitdefender Total Security for up to 15 devices.</p>
|
|
57
|
-
// <p>Need unlimited VPN traffic? Bitdefender Premium Security includes Bitdefender Total Security, Bitdefender Premium VPN for Unlimited Traffic & Premium Support.</p>
|
|
58
|
-
// `,
|
|
59
|
-
// open: false,
|
|
60
|
-
// },
|
|
61
|
-
// {
|
|
62
|
-
// question:
|
|
63
|
-
// "Do I get a VPN with my Bitdefender Internet Security subscription?",
|
|
64
|
-
// answer: `
|
|
65
|
-
// <p>Bitdefender Internet Security comes with a basic version of Bitdefender VPN that includes a generous amount of traffic (200 MB/ day, a total of 6GB/ month), free of charge.</p>
|
|
66
|
-
// <p>If you need unlimited traffic, add Bitdefender Premium VPN to your Bitdefender subscription.</p>
|
|
67
|
-
|
|
68
|
-
// `,
|
|
69
|
-
// open: false,
|
|
70
|
-
// },
|
|
71
|
-
// {
|
|
72
|
-
// question: "Can I try Bitdefender Internet Security before buying?",
|
|
73
|
-
// answer: `
|
|
74
|
-
// <p>You can always try before you buy. Download your free 30-day full trial version of Bitdefender Internet Security and test the complete package, no credit card required.</p>
|
|
75
|
-
// `,
|
|
76
|
-
// open: false,
|
|
77
|
-
// },
|
|
78
|
-
// {
|
|
79
|
-
// question: "How do I activate Bitdefender Internet Security?",
|
|
80
|
-
// answer: `
|
|
81
|
-
// <p>Just go to your email after your purchase and follow the steps to create a Bitdefender Central Account and activate your subscription. Once your subscription is active in your Bitdefender Account, you can start installing & protecting your devices.</p>
|
|
82
|
-
// `,
|
|
83
|
-
// open: false,
|
|
84
|
-
// },
|
|
85
|
-
// {
|
|
86
|
-
// question:
|
|
87
|
-
// "I changed my computer. How do I reinstall Bitdefender Internet Security?",
|
|
88
|
-
// answer: `
|
|
89
|
-
// <p>Log in to your Bitdefender Central account, go to My Devices and start installing Bitdefender on your new device. If the old computer is no longer in use, you will not need an additional slot on your subscription.</p>
|
|
90
|
-
// `,
|
|
91
|
-
// open: false,
|
|
92
|
-
// },
|
|
93
|
-
// {
|
|
94
|
-
// question: "Do I have to renew Bitdefender Internet Security?",
|
|
95
|
-
// answer: `
|
|
96
|
-
// <p>To help you stay protected, Bitdefender Internet Security can be purchased as a subscription that will automatically renew if you enrolled at the time of purchase.</p>
|
|
97
|
-
// <p>You can check and modify the status any time in your Central Account (My Subscriptions -> My Payments) if you activated the subscription on the same email address used for purchase.</p>
|
|
98
|
-
// <p>If you purchased Bitdefender Internet Security, you can choose to renew early or purchase for another year (or upgrade) close to the expiration date, depending on the time left on your subscription.</p>
|
|
99
|
-
// <p>In any case, starting 30 days before your expiration date, you will receive emails informing you that your subscription is about to expire and describing the next steps.</p>
|
|
100
|
-
|
|
101
|
-
// `,
|
|
102
|
-
// open: false,
|
|
103
|
-
// },
|
|
104
|
-
// {
|
|
105
|
-
// question: "I have not received the activation code. What should I do?",
|
|
106
|
-
// answer: `
|
|
107
|
-
// <p>Confirmation emails are typically received shortly after an order is placed. Make sure you also check your Promotions and Spam folders if your email client categorizes emails automatically. For more information, check this <a class="bd-link-noline" href="https://www.bitdefender.com/consumer/support/answer/94956/?adobe_mc=MCMID%3D63411747395182077784244429321314993670%7CMCORGID%3D0E920C0F53DA9E9B0A490D45%2540AdobeOrg%7CTS%3D1738663533" title="Support article.">Support article.</a></p>
|
|
108
|
-
// <p>More helpful articles and video tutorials are also available in <a class="bd-link-noline" href="https://www.bitdefender.com/consumer/support/?adobe_mc=MCMID%3D63411747395182077784244429321314993670%7CMCORGID%3D0E920C0F53DA9E9B0A490D45%2540AdobeOrg%7CTS%3D1738663533" title="Bitdefender Support Center.">Bitdefender Support Center.</a></p>
|
|
109
|
-
// `,
|
|
110
|
-
// open: false,
|
|
111
|
-
// },
|
|
112
|
-
// ];
|
|
113
13
|
}
|
|
114
14
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
15
|
render() {
|
|
119
16
|
return html`
|
|
120
17
|
<div class="bd-faq-container">
|
|
@@ -125,8 +22,8 @@ class FaqSection extends LitElement {
|
|
|
125
22
|
</div>
|
|
126
23
|
`;
|
|
127
24
|
}
|
|
128
|
-
|
|
129
25
|
}
|
|
26
|
+
|
|
130
27
|
class FaqSectionItem extends LitElement {
|
|
131
28
|
static properties = {
|
|
132
29
|
title: { type: String },
|
|
@@ -137,38 +34,50 @@ class FaqSectionItem extends LitElement {
|
|
|
137
34
|
super();
|
|
138
35
|
this.title = "";
|
|
139
36
|
this.open = false;
|
|
37
|
+
this.id = `faq-${Math.random().toString(36).substr(2, 9)}`;
|
|
140
38
|
}
|
|
141
39
|
|
|
142
|
-
|
|
143
|
-
|
|
144
40
|
toggleItem() {
|
|
145
41
|
this.open = !this.open;
|
|
42
|
+
this.requestUpdate();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
handleKeyDown(event) {
|
|
46
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
this.toggleItem();
|
|
49
|
+
}
|
|
146
50
|
}
|
|
147
51
|
|
|
148
52
|
render() {
|
|
149
53
|
return html`
|
|
150
54
|
<div
|
|
151
55
|
class="bd-faq-item ${this.open ? "open" : ""}"
|
|
56
|
+
role="button"
|
|
57
|
+
aria-expanded="${this.open}"
|
|
58
|
+
aria-controls="${this.id}"
|
|
59
|
+
tabindex="0"
|
|
152
60
|
@click=${this.toggleItem}
|
|
61
|
+
@keydown=${this.handleKeyDown}
|
|
153
62
|
>
|
|
154
63
|
<div class="bd-question">
|
|
155
64
|
<span class="bd-icon">${this.open ? "−" : "+"}</span>
|
|
156
65
|
<span class="bd-question-text">${this.title}</span>
|
|
157
66
|
</div>
|
|
158
67
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
68
|
+
<div
|
|
69
|
+
id="${this.id}"
|
|
70
|
+
class="bd-answer"
|
|
71
|
+
role="region"
|
|
72
|
+
aria-labelledby="${this.id}"
|
|
73
|
+
>
|
|
74
|
+
<slot></slot>
|
|
75
|
+
</div>
|
|
166
76
|
</div>
|
|
167
77
|
`;
|
|
168
78
|
}
|
|
169
79
|
}
|
|
170
80
|
|
|
171
|
-
|
|
172
81
|
FaqSection.styles = [faqCSS];
|
|
173
82
|
FaqSectionItem.styles = [faqCSS];
|
|
174
83
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
|
-
import './faq.js';
|
|
2
|
+
import './faq.js';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
5
|
title: 'Components/FAQ Section',
|
|
@@ -7,34 +7,46 @@ export default {
|
|
|
7
7
|
tags: ['autodocs'],
|
|
8
8
|
argTypes: {
|
|
9
9
|
title: { control: 'text' },
|
|
10
|
+
|
|
11
|
+
item1Title: { control: 'text', name: 'Item 1 Title' },
|
|
12
|
+
item1Content: {
|
|
13
|
+
control: 'text',
|
|
14
|
+
name: 'Item 1 Content (separate paragraphs with \\n\\n)',
|
|
15
|
+
defaultValue: 'Paragraph 1\n\nParagraph 2\n\nParagraph 3'
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
item2Title: { control: 'text', name: 'Item 2 Title' },
|
|
19
|
+
item2Content: {
|
|
20
|
+
control: 'text',
|
|
21
|
+
name: 'Item 2 Content (separate paragraphs with \\n\\n)',
|
|
22
|
+
defaultValue: 'Paragraph 1\n\nParagraph 2'
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
item3Title: { control: 'text', name: 'Item 3 Title' },
|
|
26
|
+
item3Content: {
|
|
27
|
+
control: 'text',
|
|
28
|
+
name: 'Item 3 Content (separate paragraphs with \\n\\n)',
|
|
29
|
+
defaultValue: 'Paragraph 1\n\nParagraph 2\n\nParagraph 3'
|
|
30
|
+
},
|
|
10
31
|
},
|
|
11
32
|
};
|
|
12
33
|
|
|
34
|
+
const renderParagraphs = (text) => {
|
|
35
|
+
return text.split('\n\n').map(paragraph => html`<p>${paragraph}</p>`);
|
|
36
|
+
};
|
|
37
|
+
|
|
13
38
|
const Template = (args) => html`
|
|
14
39
|
<bd-faq-section title="${args.title}">
|
|
15
|
-
<bd-faq-section-item
|
|
16
|
-
|
|
17
|
-
>
|
|
18
|
-
<p>Bitdefender Internet Security provides the best protection...</p>
|
|
19
|
-
<p>Bitdefender Internet Security provides the best protection...</p>
|
|
20
|
-
<p>Bitdefender Internet Security provides the best protection...</p>
|
|
40
|
+
<bd-faq-section-item title="${args.item1Title}">
|
|
41
|
+
${renderParagraphs(args.item1Content)}
|
|
21
42
|
</bd-faq-section-item>
|
|
22
43
|
|
|
23
|
-
<bd-faq-section-item
|
|
24
|
-
|
|
25
|
-
>
|
|
26
|
-
<p>
|
|
27
|
-
Yes! Bitdefender Internet Security offers unbeatable ransomware
|
|
28
|
-
protection...
|
|
29
|
-
</p>
|
|
44
|
+
<bd-faq-section-item title="${args.item2Title}">
|
|
45
|
+
${renderParagraphs(args.item2Content)}
|
|
30
46
|
</bd-faq-section-item>
|
|
31
47
|
|
|
32
|
-
<bd-faq-section-item
|
|
33
|
-
|
|
34
|
-
>
|
|
35
|
-
<p>
|
|
36
|
-
Bitdefender Internet Security includes a basic VPN with 200MB per day.
|
|
37
|
-
</p>
|
|
48
|
+
<bd-faq-section-item title="${args.item3Title}">
|
|
49
|
+
${renderParagraphs(args.item3Content)}
|
|
38
50
|
</bd-faq-section-item>
|
|
39
51
|
</bd-faq-section>
|
|
40
52
|
`;
|
|
@@ -42,4 +54,13 @@ const Template = (args) => html`
|
|
|
42
54
|
export const Default = Template.bind({});
|
|
43
55
|
Default.args = {
|
|
44
56
|
title: 'Questions? Answers.',
|
|
57
|
+
|
|
58
|
+
item1Title: 'How does Bitdefender Internet Security protect me?',
|
|
59
|
+
item1Content: 'Bitdefender Internet Security provides the best protection...\n\nBitdefender Internet Security provides the best protection...\n\nBitdefender Internet Security provides the best protection...',
|
|
60
|
+
|
|
61
|
+
item2Title: 'Does Bitdefender protect me against ransomware?',
|
|
62
|
+
item2Content: 'Yes! Bitdefender Internet Security offers unbeatable ransomware protection...\n\nIt detects ransomware threats in real-time.',
|
|
63
|
+
|
|
64
|
+
item3Title: 'Do I get a VPN with Bitdefender Internet Security?',
|
|
65
|
+
item3Content: 'Bitdefender Internet Security includes a basic VPN with 200MB per day.\n\nYou can upgrade for unlimited VPN usage.\n\nThe VPN protects your online privacy.',
|
|
45
66
|
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
|
|
3
|
+
export const anchorNavStyles = css`
|
|
4
|
+
:host {
|
|
5
|
+
padding: var(--size-0) 15em;
|
|
6
|
+
margin: var(--size-0) auto;
|
|
7
|
+
--bd-accesibility-focus: var(--color-blue-500);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.bd-container {
|
|
11
|
+
flex-wrap: wrap;
|
|
12
|
+
justify-content: space-between;
|
|
13
|
+
gap: 2.5em;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
a:focus-visible {
|
|
17
|
+
outline: var(--size-2) solid var(--bd-accesibility-focus);
|
|
18
|
+
outline-offset: var(--size-2);
|
|
19
|
+
border-radius: var(--space-2xs);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
nav {
|
|
23
|
+
position: -webkit-sticky;
|
|
24
|
+
position: sticky;
|
|
25
|
+
top: 0;
|
|
26
|
+
z-index: 1000;
|
|
27
|
+
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
|
|
28
|
+
display: flex;
|
|
29
|
+
justify-content: space-between;
|
|
30
|
+
align-items: center;
|
|
31
|
+
border-top: 1px solid #f0f0f0;
|
|
32
|
+
border-bottom: 1px solid #f0f0f0;
|
|
33
|
+
padding: var(--size-10) 15em;
|
|
34
|
+
width: 100%;
|
|
35
|
+
box-sizing: border-box;
|
|
36
|
+
background: white;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.bd-container {
|
|
40
|
+
padding: 50px; /* Adăugăm o umplutură suplimentară pentru a putea vedea mai clar efectul */
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
[id$="-section"] {
|
|
45
|
+
scroll-margin-top: 120px; /* Ajustează această valoare dacă este necesar */
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.anchor-links {
|
|
49
|
+
position: relative;
|
|
50
|
+
display: flex;
|
|
51
|
+
gap: var(--size-32);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
a {
|
|
55
|
+
position: relative;
|
|
56
|
+
text-decoration: none;
|
|
57
|
+
color: black;
|
|
58
|
+
font-weight: 600;
|
|
59
|
+
padding: var(--size-10) var(--size-0);
|
|
60
|
+
display: inline-block;
|
|
61
|
+
font-size: 16px !important;
|
|
62
|
+
font-family: var(--font-family-sans) !important;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
a::after {
|
|
66
|
+
content: "";
|
|
67
|
+
position: absolute;
|
|
68
|
+
left: var(--size-0);
|
|
69
|
+
bottom: -14px;
|
|
70
|
+
width: 0%;
|
|
71
|
+
height: 3px;
|
|
72
|
+
background-color: #006dff;
|
|
73
|
+
transition: width 0.3s ease;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
a.active::after {
|
|
77
|
+
width: 100%;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
export const anchorNavItemStyles = css`
|
|
83
|
+
:host {
|
|
84
|
+
display: none;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:host([active]) {
|
|
88
|
+
display: block;
|
|
89
|
+
padding: var(--size-0) 15em;
|
|
90
|
+
margin: var(--size-0) auto;
|
|
91
|
+
}
|
|
92
|
+
`;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { LitElement, html, css } from "lit";
|
|
2
|
+
import { anchorNavStyles, anchorNavItemStyles } from "./anchor-nav.css.js";
|
|
3
|
+
|
|
4
|
+
// BdAnchorNavItem
|
|
5
|
+
class BdAnchorNavItem extends HTMLElement {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
this.attachShadow({ mode: "open" });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
connectedCallback() {
|
|
12
|
+
this.render();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
render() {
|
|
16
|
+
this.shadowRoot.innerHTML = `
|
|
17
|
+
<nav>
|
|
18
|
+
<slot></slot>
|
|
19
|
+
</nav>
|
|
20
|
+
`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class BdAnchorNav extends LitElement {
|
|
26
|
+
static styles = anchorNavStyles;
|
|
27
|
+
|
|
28
|
+
constructor() {
|
|
29
|
+
super();
|
|
30
|
+
this.activeId = "";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
firstUpdated() {
|
|
34
|
+
const firstItem = this.querySelector("bd-anchor-nav-item");
|
|
35
|
+
if (firstItem) {
|
|
36
|
+
this.activeId = firstItem.id;
|
|
37
|
+
this.requestUpdate();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
handleClick(event, id) {
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
this.activeId = id;
|
|
44
|
+
|
|
45
|
+
const sectionEl = document.querySelector(`#${id}-section`);
|
|
46
|
+
if (sectionEl) {
|
|
47
|
+
const offset = 120;
|
|
48
|
+
const rect = sectionEl.getBoundingClientRect();
|
|
49
|
+
const scrollTop = window.pageYOffset;
|
|
50
|
+
const elementY = rect.top + scrollTop;
|
|
51
|
+
const offsetY = elementY - offset;
|
|
52
|
+
|
|
53
|
+
window.scrollTo({
|
|
54
|
+
top: offsetY,
|
|
55
|
+
behavior: "smooth"
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.requestUpdate();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
scrollToPricing(event) {
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
const pricingSection = document.querySelector("#section-pricing");
|
|
67
|
+
if (pricingSection) {
|
|
68
|
+
const offset = 120;
|
|
69
|
+
const elementY = pricingSection.getBoundingClientRect().top + window.pageYOffset;
|
|
70
|
+
const offsetY = elementY - offset;
|
|
71
|
+
|
|
72
|
+
window.scrollTo({
|
|
73
|
+
top: offsetY,
|
|
74
|
+
behavior: "smooth"
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
render() {
|
|
80
|
+
const items = Array.from(this.children).filter(
|
|
81
|
+
(el) => el.tagName === "BD-ANCHOR-NAV-ITEM"
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
return html`
|
|
85
|
+
<nav>
|
|
86
|
+
<div class="anchor-links">
|
|
87
|
+
${items.map((item, index) => {
|
|
88
|
+
const id = `anchor-${index + 1}`;
|
|
89
|
+
return html`
|
|
90
|
+
<a
|
|
91
|
+
href="#${id}"
|
|
92
|
+
class="${this.activeId === id ? "active" : ""}"
|
|
93
|
+
@click=${(e) => this.handleClick(e, id)}
|
|
94
|
+
|
|
95
|
+
>
|
|
96
|
+
${item.getAttribute("title")}
|
|
97
|
+
</a>
|
|
98
|
+
`;
|
|
99
|
+
})}
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<div class="bd-cta">
|
|
103
|
+
<bd-button
|
|
104
|
+
label="Buy now"
|
|
105
|
+
kind="danger"
|
|
106
|
+
size="md"
|
|
107
|
+
part="buy-button"
|
|
108
|
+
font-size="18px"
|
|
109
|
+
font-weight="600"
|
|
110
|
+
@click=${(e) => this.scrollToPricing(e)}
|
|
111
|
+
>
|
|
112
|
+
Buy now
|
|
113
|
+
</bd-button>
|
|
114
|
+
</div>
|
|
115
|
+
</nav>
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
customElements.define("bd-anchor-nav-item", BdAnchorNavItem);
|
|
121
|
+
customElements.define("bd-anchor-nav", BdAnchorNav);
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import '../anchor/anchor-nav.js';
|
|
3
|
+
import '../pricing-cards/pricing-card.js';
|
|
4
|
+
import '../tabs/tabs.js';
|
|
5
|
+
import '../FAQ/faq.js';
|
|
6
|
+
import '../carousel/carousel.js';
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
title: 'Navigation/Navbar',
|
|
10
|
+
component: 'bd-anchor-nav',
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component: `
|
|
15
|
+
**bd-anchor-nav** este o componentă de navigare care oferă linkuri către secțiuni din pagină cu scroll lin.
|
|
16
|
+
Folosește elemente \`<bd-anchor-nav-item>\` pentru fiecare link, ce trebuie să aibă \`title\` și \`id\`.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
### Cum se folosește
|
|
21
|
+
|
|
22
|
+
\`\`\`html
|
|
23
|
+
<bd-anchor-nav>
|
|
24
|
+
<bd-anchor-nav-item title="Anchor 1" id="anchor-1"></bd-anchor-nav-item>
|
|
25
|
+
<bd-anchor-nav-item title="Anchor 2" id="anchor-2"></bd-anchor-nav-item>
|
|
26
|
+
<bd-anchor-nav-item title="Anchor 3" id="anchor-3"></bd-anchor-nav-item>
|
|
27
|
+
</bd-anchor-nav>
|
|
28
|
+
|
|
29
|
+
<section id="anchor-1-section">Conținut secțiune 1</section>
|
|
30
|
+
<section id="anchor-2-section">Conținut secțiune 2</section>
|
|
31
|
+
<section id="anchor-3-section">Conținut secțiune 3</section>
|
|
32
|
+
\`\`\`
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
### Ce conține demo-ul din acest story
|
|
37
|
+
|
|
38
|
+
- Navbar cu 3 ancore
|
|
39
|
+
- Secțiuni cu FAQ, Tabs și Carousel pentru testarea scroll-ului și layout-ului
|
|
40
|
+
- Secțiune de pricing la final
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
### Alte componente utilizate
|
|
45
|
+
|
|
46
|
+
- \`bd-faq-section\`, \`bd-faq-section-item\`
|
|
47
|
+
- \`bd-tabs-component\`
|
|
48
|
+
- \`bd-carousel-section\`, \`bd-carousel-item\`
|
|
49
|
+
- \`bd-pricing-container\`
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
`,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const Template = (args) => html`
|
|
59
|
+
<bd-anchor-nav>
|
|
60
|
+
<bd-anchor-nav-item title="Anchor 1" id="anchor-1"></bd-anchor-nav-item>
|
|
61
|
+
<bd-anchor-nav-item title="Anchor 2" id="anchor-2"></bd-anchor-nav-item>
|
|
62
|
+
<bd-anchor-nav-item title="Anchor 3" id="anchor-3"></bd-anchor-nav-item>
|
|
63
|
+
</bd-anchor-nav>
|
|
64
|
+
|
|
65
|
+
<bd-container>
|
|
66
|
+
<section id="anchor-1-section" style="height: 800px;">
|
|
67
|
+
<hr />
|
|
68
|
+
<bd-faq-section title="Questions? Answers." id="anchor-1-section">
|
|
69
|
+
<bd-faq-section-item title="How does Bitdefender Internet Security protect me?">
|
|
70
|
+
<p>Bitdefender Internet Security provides the best protection...</p>
|
|
71
|
+
<p>Bitdefender Internet Security provides the best protection...</p>
|
|
72
|
+
<p>Bitdefender Internet Security provides the best protection...</p>
|
|
73
|
+
</bd-faq-section-item>
|
|
74
|
+
|
|
75
|
+
<bd-faq-section-item title="Does Bitdefender protect me against ransomware?">
|
|
76
|
+
<p>
|
|
77
|
+
Yes! Bitdefender Internet Security offers unbeatable ransomware
|
|
78
|
+
protection...
|
|
79
|
+
</p>
|
|
80
|
+
</bd-faq-section-item>
|
|
81
|
+
|
|
82
|
+
<bd-faq-section-item title="Do I get a VPN with Bitdefender Internet Security?">
|
|
83
|
+
<p>
|
|
84
|
+
Bitdefender Internet Security includes a basic VPN with 200MB per day.
|
|
85
|
+
</p>
|
|
86
|
+
</bd-faq-section-item>
|
|
87
|
+
</bd-faq-section>
|
|
88
|
+
</section>
|
|
89
|
+
|
|
90
|
+
<section id="anchor-2-section" style="height: 800px;">
|
|
91
|
+
<hr />
|
|
92
|
+
<div class="tabs">
|
|
93
|
+
<bd-tabs-component id="anchor-2-section"></bd-tabs-component>
|
|
94
|
+
</div>
|
|
95
|
+
</section>
|
|
96
|
+
|
|
97
|
+
<section id="anchor-3-section" style="height: 800px;">
|
|
98
|
+
<hr />
|
|
99
|
+
<bd-carousel-section title="Need help? We've got answers!" id="anchor-3-section">
|
|
100
|
+
<bd-carousel-item
|
|
101
|
+
title="Scam Copilot Bot"
|
|
102
|
+
subTitle="Specialized AI chatbot that helps you identify suspicious online interactions so you don’t become a victim"
|
|
103
|
+
modalText="Specialized AI chatbot that helps you identify suspicious online interactions so you don’t become a victim"
|
|
104
|
+
icon="src/assets/icons/light-carousel-img1.png"
|
|
105
|
+
>
|
|
106
|
+
<h3>Scam Copilot Bot</h3>
|
|
107
|
+
<p>
|
|
108
|
+
Specialized AI chatbot that helps you identify suspicious online
|
|
109
|
+
interactions so you don’t become a victim.
|
|
110
|
+
</p>
|
|
111
|
+
<p>
|
|
112
|
+
Specialized AI chatbot that helps you identify suspicious online
|
|
113
|
+
interactions so you don’t become a victim.
|
|
114
|
+
</p>
|
|
115
|
+
<p>
|
|
116
|
+
Specialized AI chatbot that helps you identify suspicious online
|
|
117
|
+
interactions so you don’t become a victim.
|
|
118
|
+
</p>
|
|
119
|
+
<h6>Testare Scam Copilot</h6>
|
|
120
|
+
</bd-carousel-item>
|
|
121
|
+
|
|
122
|
+
<!-- alte bd-carousel-item-uri identic cu cele din codul tău -->
|
|
123
|
+
|
|
124
|
+
</bd-carousel-section>
|
|
125
|
+
</section>
|
|
126
|
+
|
|
127
|
+
<section id="section-pricing" style="height: 800px;">
|
|
128
|
+
<bd-pricing-container id="section-pricing"></bd-pricing-container>
|
|
129
|
+
</section>
|
|
130
|
+
</bd-container>
|
|
131
|
+
`;
|
|
132
|
+
|
|
133
|
+
export const Default = Template.bind({});
|
|
134
|
+
Default.args = {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
|
|
3
|
+
export default css`
|
|
4
|
+
:host {
|
|
5
|
+
--badge-background-default: #026DFF;
|
|
6
|
+
--badge-font-weight: 700;
|
|
7
|
+
--badge-font-family: var(--font-family-sans, sans-serif);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.badge {
|
|
11
|
+
display: inline-block;
|
|
12
|
+
background-color: var(--color-blue-500);
|
|
13
|
+
color: var(--color-neutral-0);
|
|
14
|
+
border-radius: var(--size-20);
|
|
15
|
+
font-size: var(--caption-small);
|
|
16
|
+
font-weight: var(--badge-font-weight);
|
|
17
|
+
font-family: var(--badge-font-family);
|
|
18
|
+
line-height: var(--size-20);
|
|
19
|
+
padding: 0 var(--size-12);
|
|
20
|
+
white-space: nowrap;
|
|
21
|
+
user-select: none;
|
|
22
|
+
vertical-align: middle;
|
|
23
|
+
box-sizing: border-box;
|
|
24
|
+
bottom: var(--size-4);
|
|
25
|
+
position: relative
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { LitElement, html, css } from 'lit';
|
|
2
|
+
import badgeCSS from './badge.css.js';
|
|
3
|
+
|
|
4
|
+
export class BdBadge extends LitElement {
|
|
5
|
+
static properties = {
|
|
6
|
+
text: { type: String },
|
|
7
|
+
color: { type: String },
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
constructor() {
|
|
13
|
+
super();
|
|
14
|
+
this.text = 'Badge';
|
|
15
|
+
this.color = '#026DFF';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
updated(changed) {
|
|
19
|
+
if (changed.has('color')) {
|
|
20
|
+
this.style.setProperty('--badge-bg', this.color);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
render() {
|
|
25
|
+
return html`<span class="badge">${this.text}</span>`;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
BdBadge.styles = [badgeCSS];
|
|
29
|
+
|
|
30
|
+
customElements.define('bd-badge', BdBadge);
|