@repobit/dex-system-design 0.5.0 → 0.7.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 (58) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/package.json +4 -3
  3. package/src/assets/images/bd-header-img.jpg +0 -0
  4. package/src/assets/images/bd-header-us.jpg +0 -0
  5. package/src/components/Button/Button.js +115 -3
  6. package/src/components/Button/button.css.js +80 -43
  7. package/src/components/Button/button.stories.js +83 -7
  8. package/src/components/FAQ/faq.css.js +26 -15
  9. package/src/components/FAQ/faq.js +23 -114
  10. package/src/components/FAQ/faq.stories.js +41 -20
  11. package/src/components/Input/Input.js +2 -2
  12. package/src/components/anchor/anchor-nav.css.js +92 -0
  13. package/src/components/anchor/anchor-nav.js +121 -0
  14. package/src/components/anchor/anchor.stories.js +134 -0
  15. package/src/components/badge/badge.css.js +27 -0
  16. package/src/components/badge/badge.js +30 -0
  17. package/src/components/badge/badge.stories.js +36 -0
  18. package/src/components/carousel/carousel.css.js +35 -18
  19. package/src/components/carousel/carousel.js +149 -99
  20. package/src/components/carousel/carousel.stories.js +202 -46
  21. package/src/components/checkbox/checkbox.css.js +132 -0
  22. package/src/components/checkbox/checkbox.js +130 -0
  23. package/src/components/checkbox/checkbox.stories.js +63 -0
  24. package/src/components/divider/divider-horizontal.js +29 -0
  25. package/src/components/divider/divider-vertical.js +32 -0
  26. package/src/components/divider/divider.css.js +0 -0
  27. package/src/components/divider/divider.stories.js +77 -0
  28. package/src/components/header/header.css.js +248 -0
  29. package/src/components/header/header.js +87 -0
  30. package/src/components/header/header.stories.js +57 -0
  31. package/src/components/highlight/highlight-s.css.js +88 -0
  32. package/src/components/highlight/highlight-s.js +35 -0
  33. package/src/components/highlight/highlight-s.stories.js +22 -0
  34. package/src/components/highlight/highlight.css.js +119 -0
  35. package/src/components/highlight/highlight.js +60 -0
  36. package/src/components/highlight/highlight.stories.js +53 -0
  37. package/src/components/light-carousel/light-carousel.css.js +18 -10
  38. package/src/components/light-carousel/light-carousel.js +29 -16
  39. package/src/components/light-carousel/light-carousel.stories.js +9 -7
  40. package/src/components/pricing-cards/pricing-card.css.js +137 -2
  41. package/src/components/pricing-cards/pricing-card.js +63 -82
  42. package/src/components/pricing-cards/pricing-card.stories.js +1 -0
  43. package/src/components/radio/radio.css.js +168 -0
  44. package/src/components/radio/radio.js +222 -0
  45. package/src/components/radio/radio.stories.js +103 -0
  46. package/src/components/tabs/tabs.css.js +25 -7
  47. package/src/components/tabs/tabs.js +19 -12
  48. package/src/components/termsOfUse/terms.css.js +6 -0
  49. package/src/tokens/fonts.stories.js +73 -0
  50. package/src/tokens/spacing.stories.js +56 -0
  51. package/src/tokens/tokens-grid.stories.js +83 -0
  52. package/src/tokens/tokens.css +116 -1
  53. package/src/tokens/tokens.stories.js +67 -0
  54. package/src/tokens/typography.stories.js +69 -0
  55. package/src/tokens/tokens.js +0 -206
  56. /package/src/assets/{icons → images}/tabs-img1.png +0 -0
  57. /package/src/assets/{icons → images}/tabs-img2.png +0 -0
  58. /package/src/assets/{icons → images}/tabs-img3.png +0 -0
@@ -0,0 +1,77 @@
1
+ import { html } from 'lit';
2
+ import './divider-horizontal.js';
3
+ import './divider-vertical.js';
4
+
5
+ export default {
6
+ title: 'Atoms/Divider',
7
+ tags: ['autodocs'],
8
+ argTypes: {
9
+ width: {
10
+ control: 'text',
11
+ if: { arg: 'component', eq: 'horizontal' },
12
+ description: 'Width of the horizontal divider (e.g. 100%, 200px)',
13
+ },
14
+ height: {
15
+ control: 'text',
16
+ if: { arg: 'component', eq: 'vertical' },
17
+ description: 'Height of the vertical divider (e.g. 100%, 40px)',
18
+ },
19
+ thickness: {
20
+ control: 'text',
21
+ if: { arg: 'component', eq: 'vertical' },
22
+ description: 'Thickness (visual width) of the vertical divider (e.g. 1px, 4px)',
23
+ },
24
+ component: {
25
+ control: { type: 'select' },
26
+ options: ['horizontal', 'vertical'],
27
+ description: 'Which divider to render',
28
+ },
29
+ },
30
+ args: {
31
+ component: 'horizontal',
32
+ width: '100%',
33
+ height: '100px',
34
+ thickness: '1px',
35
+ },
36
+ };
37
+
38
+ const Template = ({ component, width, height, thickness }) => {
39
+ return component === 'horizontal'
40
+ ? html`<bd-divider-horizontal .width=${width}></bd-divider-horizontal>`
41
+ : html`<bd-divider-vertical .height=${height} .thickness=${thickness}></bd-divider-vertical>`;
42
+ };
43
+
44
+ export const Default = Template.bind({});
45
+ Default.args = {
46
+ component: 'horizontal',
47
+ width: '100%',
48
+ height: '100px',
49
+ thickness: '1px',
50
+ };
51
+
52
+ export const HorizontalCustomWidth = Template.bind({});
53
+ HorizontalCustomWidth.args = {
54
+ component: 'horizontal',
55
+ width: '200px',
56
+ };
57
+
58
+ export const VerticalDefault = Template.bind({});
59
+ VerticalDefault.args = {
60
+ component: 'vertical',
61
+ height: '100px',
62
+ thickness: '1px',
63
+ };
64
+
65
+ export const VerticalThick = Template.bind({});
66
+ VerticalThick.args = {
67
+ component: 'vertical',
68
+ height: '100px',
69
+ thickness: '4px',
70
+ };
71
+
72
+ export const VerticalTall = Template.bind({});
73
+ VerticalTall.args = {
74
+ component: 'vertical',
75
+ height: '200px',
76
+ thickness: '2px',
77
+ };
@@ -0,0 +1,248 @@
1
+ import { css } from "lit";
2
+
3
+ export default css`
4
+ :host {
5
+ display: block;
6
+ background: white;
7
+ --bd-accesibility-focus: var(--color-blue-500);
8
+ padding-top: 32px;
9
+ padding-bottom: 32px;
10
+ }
11
+
12
+ a:focus-visible {
13
+ outline: var(--size-2) solid var(--bd-accesibility-focus);
14
+ outline-offset: var(--size-2);
15
+ border-radius: var(--space-2xs);
16
+ }
17
+ a {
18
+ color: #000000;
19
+ }
20
+ .bd-container {
21
+ display: grid;
22
+ grid-template-columns: 1fr 1fr;
23
+ align-items: center;
24
+ gap: 30px;
25
+ padding: 0 240px;
26
+ margin: 0 auto;
27
+ align-items: stretch;
28
+ }
29
+
30
+ bd-button {
31
+ font-size: var(--heading-xxsmall) !important;
32
+ font-family: var(--font-family-sans) !important;
33
+ font-weight: var(--font-weight-sans-semibold) !important;
34
+ }
35
+ .bd-header-left,
36
+ .bd-header-right {
37
+ flex: 1;
38
+ }
39
+
40
+ .bd-header-right {
41
+ display: flex;
42
+ align-items: stretch;
43
+ justify-content: center;
44
+ width: 100%;
45
+ position: relative;
46
+ }
47
+
48
+ .bd-header-image {
49
+ width: 100%;
50
+ height: auto;
51
+ object-fit: cover;
52
+ display: block;
53
+ border-radius: var(--size-20);
54
+ position: relative;
55
+ z-index: 1;
56
+ }
57
+ .bd-product-name {
58
+ color: var(--color-blue-500);
59
+ font-family: var(--font-family-sans);
60
+ font-weight: var(--font-weight-sans-semibold);
61
+ font-size: var(--heading-large);
62
+ letter-spacing: var(--size-0);
63
+ margin-top: var(--size-16) !important;
64
+ margin-bottom: var(--size-8) !important;
65
+ }
66
+
67
+ .bd-value-prop {
68
+ font-family: var(--font-family-sans);
69
+ font-weight: var(--font-weight-sans-bold);
70
+ font-size: var(--heading-xlarge);
71
+ color: #000000;
72
+ letter-spacing: var(--size-0);
73
+ margin: var(--size-0) var(--size-0) !important;
74
+ }
75
+
76
+ .bd-description {
77
+ font-family: var(--font-family-sans);
78
+ font-weight: var(--font-weight-sans-regular);
79
+ font-size: var(--size-18);
80
+ color: #000000;
81
+ margin-top: var(--size-8) !important;
82
+ margin-bottom: var(--size-0) !important;
83
+ }
84
+
85
+ .bd-price-zone-top {
86
+ display: flex;
87
+ gap: var(--size-8);
88
+ align-items: center;
89
+ margin-top: var(--size-32);
90
+ }
91
+
92
+ .bd-full-price {
93
+ text-decoration: line-through;
94
+ color: #000000;
95
+ font-size: var(--size-18);
96
+ font-family: var(--font-family-sans);
97
+ }
98
+
99
+ .bd-discount {
100
+ background: #c3f4d4;
101
+ color: #0b6a26;
102
+ padding: var(--size-4) var(--size-14);
103
+ border-radius: var(--size-14);
104
+ font-size: var(--size-16);
105
+ font-family: var(--font-family-sans);
106
+ font-weight: var(--font-weight-sans-semibold);
107
+ }
108
+
109
+ .bd-price-zone-final {
110
+ display: block;
111
+ font-size: var(--display-large-mobile);
112
+ font-family: var(--font-family-sans);
113
+ font-weight: var(--font-weight-sans-bold);
114
+ margin-bottom: var(--size-16);
115
+ }
116
+
117
+ .bd-cta {
118
+ display: flex;
119
+ gap: var(--size-16);
120
+ }
121
+
122
+ .bd-disclaimer-top {
123
+ display: block;
124
+ margin-top: var(--size-16);
125
+ margin-bottom: var(--size-8);
126
+ font-size: var(--body-medium);
127
+ font-family: var(--font-family-sans);
128
+ font-weight: var(--font-weight-sans-regular);
129
+ color: #000000;
130
+ }
131
+ .bd-header-image-wrapper {
132
+ position: relative;
133
+ width: 100%;
134
+ height: 100%;
135
+ display: flex;
136
+ justify-content: center;
137
+ overflow: hidden;
138
+ border-radius: 20px;
139
+ }
140
+
141
+ .bd-header-image {
142
+ display: block;
143
+ width: 100%;
144
+ height: auto;
145
+ object-fit: cover;
146
+ transform: scale(1.35) translateY(-7%);
147
+ }
148
+
149
+ .bd-header-watermark {
150
+ position: absolute;
151
+ bottom: var(--size-16);
152
+ right: var(--size-16);
153
+ z-index: 2;
154
+ color: #ffffff;
155
+ font-size: var(--heading-large);
156
+ font-weight: 700;
157
+ opacity: 1;
158
+ -webkit-backdrop-filter: blur(2px);
159
+ }
160
+
161
+ .bd-header-watermark span {
162
+ color: #fff;
163
+ padding: var(--size-4) var(--size-8);
164
+ backdrop-filter: blur(2px);
165
+ -webkit-backdrop-filter: blur(2px);
166
+ border-radius: var(--size-4);
167
+ font-family: var(--font-family-sans);
168
+ font-weight: var(--font-weight-sans-bold);
169
+ }
170
+ .bd-disclaimer-bottom {
171
+ display: block;
172
+ font-size: var(--body-medium);
173
+ font-family: var(--font-family-sans);
174
+ font-weight: var(--font-weight-sans-regular);
175
+ color: #000000;
176
+ margin-bottom: var(--size-16);
177
+ }
178
+ ::slotted([slot="right"]) {
179
+ border-radius: var(--size-20);
180
+ overflow: hidden;
181
+ max-width: 100%;
182
+ height: auto;
183
+ }
184
+
185
+ ::slotted([slot="extra-content"]) {
186
+ margin-top: 1em;
187
+ display: block;
188
+ }
189
+
190
+ @media (max-width: 1024px) {
191
+ .bd-container {
192
+ flex-direction: column;
193
+ padding: 0 4em;
194
+ gap: 2em;
195
+ }
196
+
197
+ .bd-header-left,
198
+ .bd-header-right {
199
+ width: 100%;
200
+ }
201
+
202
+ .bd-cta {
203
+ flex-direction: column;
204
+ align-items: flex-start;
205
+ }
206
+
207
+ ::slotted([slot="right"]) {
208
+ max-width: 100%;
209
+ }
210
+ }
211
+
212
+ @media (max-width: 768px) {
213
+ .bd-container {
214
+ padding: 0 2em;
215
+ text-align: center;
216
+ }
217
+
218
+ .bd-product-name,
219
+ .bd-value-prop,
220
+ .bd-description,
221
+ .bd-price-zone-top,
222
+ .bd-price-zone-final,
223
+ .bd-disclaimer {
224
+ text-align: center;
225
+ }
226
+
227
+ .bd-cta {
228
+ flex-direction: column;
229
+ align-items: center;
230
+ }
231
+
232
+ .bd-header-right {
233
+ display: flex;
234
+ justify-content: center;
235
+ }
236
+
237
+ ::slotted([slot="right"]) {
238
+ max-width: 100%;
239
+ }
240
+ }
241
+
242
+ @media (max-width: 480px) {
243
+ .bd-header-image {
244
+ max-width: 90%;
245
+ max-height: 200px;
246
+ }
247
+ }
248
+ `;
@@ -0,0 +1,87 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import headerCSS from "../header/header.css.js";
3
+
4
+ class Header extends LitElement {
5
+ static properties = {
6
+ productName: { type: String, attribute: "product-name" },
7
+ valueProp: { type: String, attribute: "value-prop" },
8
+ description: { type: String },
9
+ fullPrice: { type: String, attribute: "full-price" },
10
+ discount: { type: String },
11
+ finalPrice: { type: String, attribute: "final-price" },
12
+ };
13
+
14
+ constructor() {
15
+ super();
16
+ this.productName = "";
17
+ this.valueProp = "";
18
+ this.description = "";
19
+ this.fullPrice = "";
20
+ this.discount = "";
21
+ this.finalPrice = "";
22
+ }
23
+
24
+ render() {
25
+ return html`
26
+ <div class="bd-container">
27
+ <div class="bd-header-left">
28
+ <h2 class="bd-product-name">${this.productName}</h2>
29
+ <h3 class="bd-value-prop">${this.valueProp}</h3>
30
+ <p class="bd-description">${this.description}</p>
31
+
32
+ <div class="bd-price-zone-top">
33
+ <span class="bd-full-price">${this.fullPrice}</span>
34
+ <span class="bd-discount">${this.discount}</span>
35
+ </div>
36
+
37
+ <span class="bd-price-zone-final">${this.finalPrice}</span>
38
+
39
+ <div class="bd-cta">
40
+ <bd-button
41
+ label="Buy now"
42
+ kind="danger"
43
+ size="md"
44
+ part="buy-button"
45
+ font-size="18px"
46
+ font-weight="600"
47
+ >Buy now</bd-button
48
+ >
49
+ <bd-button
50
+ label="View more plans"
51
+ kind="primary-outline"
52
+ size="md"
53
+ font-size="18px"
54
+ font-weight="600"
55
+ >
56
+ View more plans
57
+ </bd-button>
58
+ </div>
59
+
60
+ <small class="bd-disclaimer-top">
61
+ Protection for 1 account & 5 PCs, Macs, tablets, or smartphones.
62
+ Windows® | macOS® | Android™ | iOS®
63
+ </small>
64
+ <small class="bd-disclaimer-bottom">
65
+ First year price. Sales tax included. See
66
+ <a href="#" tabindex="0">Terms of Use</a> below.
67
+ </small>
68
+ </div>
69
+
70
+ <div class="bd-header-right">
71
+ <div class="bd-header-image-wrapper">
72
+ <img
73
+ class="bd-header-image"
74
+ src="images/bd-header-us.jpg"
75
+ alt="Security illustration"
76
+ />
77
+ <div class="bd-header-watermark"><span>Trusted. Always.</span></div>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ `;
82
+ }
83
+ }
84
+
85
+ Header.styles = [headerCSS];
86
+
87
+ customElements.define("bd-header", Header);
@@ -0,0 +1,57 @@
1
+ import { html } from 'lit';
2
+ import './header.js';
3
+
4
+ export default {
5
+ title: 'Sections/Header',
6
+ component: 'bd-header',
7
+ argTypes: {
8
+ productName: { control: 'text' },
9
+ valueProp: { control: 'text' },
10
+ description: { control: 'text' },
11
+ fullPrice: { control: 'text' },
12
+ discount: { control: 'text' },
13
+ finalPrice: { control: 'text' },
14
+ },
15
+ };
16
+
17
+ const Template = (args) => html`
18
+ <bd-header
19
+ .productName=${args.productName}
20
+ .valueProp=${args.valueProp}
21
+ .description=${args.description}
22
+ .fullPrice=${args.fullPrice}
23
+ .discount=${args.discount}
24
+ .finalPrice=${args.finalPrice}
25
+ >
26
+ </bd-header>
27
+ `;
28
+
29
+ export const Default = Template.bind({});
30
+ Default.args = {
31
+ productName: 'Bitdefender Ultimate Security',
32
+ valueProp: 'Complete Security, Advanced Privacy, and Identity Protection',
33
+ description: 'All in one plan to incorporate multi-awarded device protection, solid password management, unlimited VPN traffic & personalized protection for your online identity.',
34
+ fullPrice: '$139.99',
35
+ discount: 'Save 44%',
36
+ finalPrice: '$79.99*',
37
+ };
38
+
39
+ export const WithCustomImage = Template.bind({});
40
+ WithCustomImage.args = {
41
+ productName: 'Bitdefender Ultimate Security',
42
+ valueProp: 'Complete Security, Advanced Privacy, and Identity Protection',
43
+ description: 'All in one plan to incorporate multi-awarded device protection, solid password management, unlimited VPN traffic & personalized protection for your online identity.',
44
+ fullPrice: '$139.99',
45
+ discount: 'Save 44%',
46
+ finalPrice: '$79.99*',
47
+ };
48
+
49
+ export const WithDiscountedPrice = Template.bind({});
50
+ WithDiscountedPrice.args = {
51
+ productName: 'Bitdefender Premium Security',
52
+ valueProp: 'Advanced Security, Privacy & Identity Protection',
53
+ description: 'Comprehensive security for all your devices with enhanced features and privacy options.',
54
+ fullPrice: '$199.99',
55
+ discount: 'Save 35%',
56
+ finalPrice: '$129.99*',
57
+ };
@@ -0,0 +1,88 @@
1
+ import { css } from 'lit';
2
+
3
+ export const highlightTextStyles = css`
4
+ :host {
5
+ --base-font-size: 32px;
6
+ --deco-height-multiplier: 1.4375; /* 46px / 32px */
7
+ --rect-height-multiplier: 1.1875; /* 38px / 32px */
8
+ --ellipse-size-multiplier: 0.25; /* 8px / 32px */
9
+
10
+ --deco-height: calc(var(--base-font-size) * var(--deco-height-multiplier));
11
+ --rect-height: calc(var(--base-font-size) * var(--rect-height-multiplier));
12
+ --ellipse-size: calc(var(--base-font-size) * var(--ellipse-size-multiplier));
13
+
14
+ display: inline-block;
15
+ font-family: 'IBM Plex Sans', sans-serif;
16
+ font-weight: 700;
17
+ font-size: var(--base-font-size);
18
+ line-height: 1.3;
19
+ color: #000;
20
+ text-align: center;
21
+ }
22
+
23
+ .highlight {
24
+ background: none;
25
+ color: #000;
26
+ display: inline-block;
27
+ font: inherit;
28
+ font-weight: inherit;
29
+ font-size: inherit;
30
+ line-height: inherit;
31
+ position: relative;
32
+ vertical-align: middle;
33
+ top: -4px;
34
+ }
35
+
36
+ .highlight-bg {
37
+ background: #F1F7FE;
38
+ display: inline-block;
39
+ position: relative;
40
+ padding: 0 4px;
41
+ margin-left: 4px;
42
+ margin-right: 4px;
43
+ z-index: 1;
44
+ }
45
+
46
+ .highlight-deco {
47
+ position: absolute;
48
+ top: 0;
49
+ width: var(--ellipse-size);
50
+ height: var(--deco-height);
51
+ display: flex;
52
+ flex-direction: column;
53
+ align-items: center;
54
+ justify-content: flex-start;
55
+ pointer-events: none;
56
+ z-index: 2;
57
+ }
58
+
59
+ .highlight-deco.left {
60
+ left: -3px;
61
+ top: -4px;
62
+ }
63
+
64
+ .highlight-deco.right {
65
+ right: -3px;
66
+ }
67
+
68
+ .highlight-svg-ellipse-top,
69
+ .highlight-svg-ellipse-bottom {
70
+ width: var(--ellipse-size);
71
+ height: var(--ellipse-size);
72
+ fill: #006DFF;
73
+ display: block;
74
+ }
75
+
76
+ .highlight-svg-rect {
77
+ width: calc(var(--ellipse-size) * 0.25); /* 2px when ellipse is 8px */
78
+ height: var(--rect-height);
79
+ fill: #006DFF;
80
+ display: block;
81
+ }
82
+
83
+ @media (max-width: 600px) {
84
+ :host {
85
+ --base-font-size: 20px;
86
+ }
87
+ }
88
+ `;
@@ -0,0 +1,35 @@
1
+ import { LitElement, html } from 'lit';
2
+ import { highlightTextStyles } from './highlight-s.css.js';
3
+
4
+ export class HighlightText extends LitElement {
5
+ static styles = highlightTextStyles;
6
+
7
+ render() {
8
+ return html`
9
+ <span class="highlight">
10
+ <span class="highlight-bg">
11
+ <span class="highlight-deco left">
12
+ <svg class="highlight-svg-ellipse-top" viewBox="0 0 8 8">
13
+ <ellipse cx="4" cy="4" rx="4" ry="4" />
14
+ </svg>
15
+ <svg class="highlight-svg-rect" viewBox="0 0 2 42">
16
+ <rect x="0" y="0" width="2" height="42" />
17
+ </svg>
18
+ </span>
19
+ <slot></slot>
20
+ <span class="highlight-deco right">
21
+ <svg class="highlight-svg-rect" viewBox="0 0 2 42">
22
+ <rect x="0" y="0" width="2" height="42" />
23
+ </svg>
24
+ <svg class="highlight-svg-ellipse-bottom" viewBox="0 0 8 8">
25
+ <ellipse cx="4" cy="4" rx="4" ry="4" />
26
+ </svg>
27
+ </span>
28
+ </span>
29
+ </span>
30
+ `;
31
+ }
32
+
33
+ }
34
+
35
+ customElements.define('highlight-text-s', HighlightText);
@@ -0,0 +1,22 @@
1
+ import { html } from 'lit';
2
+ import './highlight-s.js';
3
+
4
+ export default {
5
+ title: 'Components/HighlightText',
6
+ component: 'highlight-text-s',
7
+ };
8
+
9
+ const Template = ({ beforeText, highlightText, afterText }) => html`
10
+ <h1>
11
+ ${beforeText}
12
+ <highlight-text-s>${highlightText}</highlight-text-s>
13
+ ${afterText}
14
+ </h1>
15
+ `;
16
+
17
+ export const InlineText = Template.bind({});
18
+ InlineText.args = {
19
+ beforeText: 'Introducing ',
20
+ highlightText: 'the next generation',
21
+ afterText: ' of digital security: your personalized shield for a worry-free online experience.',
22
+ };