@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.
- package/CHANGELOG.md +18 -0
- package/package.json +2 -2
- package/src/assets/icons/Identity_protection.png +0 -0
- package/src/assets/icons/arrow_down.png +0 -0
- package/src/assets/icons/arrow_up.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 +271 -0
- package/src/tokens/colors.js +10 -10
- package/src/tokens/fonts.stories.js +5 -5
- package/src/tokens/layout.css +4 -3
- package/src/tokens/new-tokens.css +698 -0
- package/src/tokens/spacing.stories.js +1 -1
- package/src/tokens/tokens.css +1063 -0
- package/src/tokens/tokens.stories.js +3 -3
- package/src/tokens/typography.css.js +0 -4
- package/src/tokens/typography.stories.js +2 -2
- package/src/components/Input/index.js +0 -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
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { LitElement, html } from "lit";
|
|
2
|
+
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
+
import newPricingCSS from "../pricing-cards/new-pricing.css";
|
|
4
|
+
|
|
5
|
+
class PricingCard extends LitElement {
|
|
6
|
+
static properties = {
|
|
7
|
+
highlight: { type: Boolean }
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
render() {
|
|
13
|
+
return html`
|
|
14
|
+
<div class="card-wrapper">
|
|
15
|
+
${this.highlight
|
|
16
|
+
? html`<div class="highlight-banner">Best Value</div>`
|
|
17
|
+
: ""}
|
|
18
|
+
<div class="card ${this.highlight ? "highlight" : ""}">
|
|
19
|
+
<slot name="header"></slot>
|
|
20
|
+
<slot name="pricing"></slot>
|
|
21
|
+
<slot name="actions"></slot>
|
|
22
|
+
<slot name="features"></slot>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
`;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
PricingCard.styles = [tokens, newPricingCSS];
|
|
29
|
+
|
|
30
|
+
customElements.define("new-pricing-card", PricingCard);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
|
|
3
|
+
export default css`
|
|
4
|
+
.card {
|
|
5
|
+
background: white;
|
|
6
|
+
border-radius: var(--spacing-20);
|
|
7
|
+
padding: var(--spacing-32);
|
|
8
|
+
background: #fafafa;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.highlight {
|
|
12
|
+
border: 2px solid #1d7928;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.highlight-wrapper {
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.card-wrapper {
|
|
20
|
+
position: relative;
|
|
21
|
+
padding-top: 2.5rem;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.highlight-banner {
|
|
25
|
+
position: absolute;
|
|
26
|
+
top: 1rem;
|
|
27
|
+
left: 50%;
|
|
28
|
+
transform: translate(-50%, -50%);
|
|
29
|
+
background-color: #1d7928;
|
|
30
|
+
color: white;
|
|
31
|
+
font-weight: bold;
|
|
32
|
+
font-size: var(--typography-body-regular-fontSize);
|
|
33
|
+
text-align: center;
|
|
34
|
+
border-radius: 1rem 1rem 0 0;
|
|
35
|
+
z-index: 2;
|
|
36
|
+
height: 48px;
|
|
37
|
+
width: 85%;
|
|
38
|
+
max-width: 360px;
|
|
39
|
+
min-width: 200px;
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
justify-content: center;
|
|
43
|
+
font-family: var(--typography-fontFamily-sans);
|
|
44
|
+
box-sizing: border-box;
|
|
45
|
+
}
|
|
46
|
+
.actions {
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
gap: 0.5rem;
|
|
50
|
+
margin-top: 1rem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.hr-line {
|
|
54
|
+
border: none;
|
|
55
|
+
border-top: 1px solid #ccc;
|
|
56
|
+
margin: 1.5rem 0;
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LitElement, html } from 'lit';
|
|
2
|
+
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
+
import newActionsPricingCSS from "../pricing-cards/pricing-card-actions.css.js";
|
|
4
|
+
|
|
5
|
+
class PricingCardActions extends LitElement {
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
render() {
|
|
9
|
+
return html`
|
|
10
|
+
<div class="actions">
|
|
11
|
+
<bd-button label="Buy Now" kind="danger" size="md" fullWidth strong>
|
|
12
|
+
Buy Now
|
|
13
|
+
</bd-button>
|
|
14
|
+
</div>
|
|
15
|
+
`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
PricingCardActions.styles = [tokens, newActionsPricingCSS];
|
|
19
|
+
|
|
20
|
+
customElements.define('pricing-card-actions', PricingCardActions);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
|
|
3
|
+
export default css`
|
|
4
|
+
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
padding: 0px 240px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cards-row {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-wrap: wrap;
|
|
12
|
+
gap: 1rem;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
::slotted(new-pricing-card) {
|
|
16
|
+
flex: 1 1 100%;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* 2 cards */
|
|
20
|
+
:host([count="2"]) ::slotted(new-pricing-card) {
|
|
21
|
+
flex: 1 1 calc(50% - 1rem);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* 3 cards */
|
|
25
|
+
:host([count="3"]) ::slotted(new-pricing-card) {
|
|
26
|
+
flex: 1 1 calc(33.333% - 1rem);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* 4+ cards */
|
|
30
|
+
:host([count="4"]),
|
|
31
|
+
:host([count="5"]),
|
|
32
|
+
:host([count="6"]) ::slotted(new-pricing-card) {
|
|
33
|
+
flex: 1 1 calc(25% - 1rem);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@media (max-width: 768px) {
|
|
37
|
+
::slotted(new-pricing-card) {
|
|
38
|
+
flex: 1 1 100%;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { LitElement, html } from "lit";
|
|
2
|
+
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
+
import newCardsContainerPricingCSS from "../pricing-cards/pricing-card-container.css.js";
|
|
4
|
+
|
|
5
|
+
export class PricingCardsContainer extends LitElement {
|
|
6
|
+
|
|
7
|
+
static properties = {
|
|
8
|
+
count: { type: Number, reflect: true }
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
this.count = 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
firstUpdated() {
|
|
17
|
+
const cards = this.querySelectorAll("new-pricing-card");
|
|
18
|
+
this.count = cards.length;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
render() {
|
|
22
|
+
return html`
|
|
23
|
+
<div class="cards-row">
|
|
24
|
+
<slot></slot>
|
|
25
|
+
</div>
|
|
26
|
+
`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
PricingCardsContainer.styles = [tokens, newCardsContainerPricingCSS];
|
|
30
|
+
|
|
31
|
+
customElements.define("pricing-cards-container", PricingCardsContainer);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
|
|
3
|
+
export default css`
|
|
4
|
+
.card-header {
|
|
5
|
+
text-align: center;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.card-title {
|
|
9
|
+
font-size: var(--typography-heading-h4-fontSize);
|
|
10
|
+
font-family: var(--typography-fontFamily-sans);
|
|
11
|
+
font-weight: var(--typography-fontWeight-bold);
|
|
12
|
+
margin: 0;
|
|
13
|
+
text-align: left;
|
|
14
|
+
color: #000000;
|
|
15
|
+
}
|
|
16
|
+
.card-title-brand {
|
|
17
|
+
display: inline;
|
|
18
|
+
font-family: var(--typography-fontFamily-sans);
|
|
19
|
+
font-weight: var(--typography-fontWeight-bold);
|
|
20
|
+
color: #000000;
|
|
21
|
+
}
|
|
22
|
+
.plus {
|
|
23
|
+
color: var(--color-blue-600);
|
|
24
|
+
font-weight: var(--typography-fontWeight-bold);
|
|
25
|
+
font-family: var(--typography-fontFamily-sans);
|
|
26
|
+
}
|
|
27
|
+
.badge {
|
|
28
|
+
display: inline-flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
gap: 0.25rem;
|
|
31
|
+
font-weight: bold;
|
|
32
|
+
background: #e8f0fe;
|
|
33
|
+
padding: 0.25rem 0.5rem;
|
|
34
|
+
border-radius: 4px;
|
|
35
|
+
margin: 0.5rem 0;
|
|
36
|
+
font-size: 0.875rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.badge-icon {
|
|
40
|
+
height: 1rem;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.badge-subtitle {
|
|
44
|
+
font-size: var(--typography-body-regular-fontSize);
|
|
45
|
+
text-align: left;
|
|
46
|
+
font-family: var(--typography-fontFamily-sans);
|
|
47
|
+
color: #000000;
|
|
48
|
+
margin: 0;
|
|
49
|
+
margin-bottom: var(--spacing-16);
|
|
50
|
+
margin-top: -8px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.hr-line {
|
|
54
|
+
border: none;
|
|
55
|
+
border-top: 1px solid #ccc;
|
|
56
|
+
margin: 1rem 0;
|
|
57
|
+
}
|
|
58
|
+
.badge-wrapper {
|
|
59
|
+
text-align: left;
|
|
60
|
+
margin-top: var(--spacing-8);
|
|
61
|
+
margin-bottom: var(--spacing-8);
|
|
62
|
+
}
|
|
63
|
+
.badge-wrapper.multiple {
|
|
64
|
+
display: flex;
|
|
65
|
+
flex-wrap: wrap;
|
|
66
|
+
gap: var(--spacing-8);
|
|
67
|
+
margin-top: var(--spacing-8);
|
|
68
|
+
margin-bottom: var(--spacing-8);
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { LitElement, html } from "lit";
|
|
2
|
+
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
+
import newHeaderPricingCSS from "../pricing-cards/pricing-card-header.css.js";
|
|
4
|
+
|
|
5
|
+
class PricingCardHeader extends LitElement {
|
|
6
|
+
static properties = {
|
|
7
|
+
title : { type: String },
|
|
8
|
+
subtitle: { type: String },
|
|
9
|
+
badges : { type: String },
|
|
10
|
+
plus : { type: Boolean }
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
get parsedBadges() {
|
|
15
|
+
return this.badges ? this.badges.split("|").map((b) => b.trim()) : [];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
render() {
|
|
19
|
+
const [brand, ...rest] = this.title ? this.title.split(" ") : ["", ""];
|
|
20
|
+
const restOfTitle = rest.join(" ");
|
|
21
|
+
|
|
22
|
+
return html`
|
|
23
|
+
<div class="card-header">
|
|
24
|
+
<p class="card-title">
|
|
25
|
+
<span class="card-title-brand">${brand}</span>
|
|
26
|
+
</p>
|
|
27
|
+
<p class="card-title">
|
|
28
|
+
${restOfTitle}
|
|
29
|
+
${this.plus ? html` <span class="plus">Plus</span>` : ""}
|
|
30
|
+
</p>
|
|
31
|
+
${this.parsedBadges.length
|
|
32
|
+
? html`
|
|
33
|
+
<div class="badge-wrapper multiple">
|
|
34
|
+
${this.parsedBadges.map((b) => html`<bd-badge>${b}</bd-badge>`)}
|
|
35
|
+
</div>
|
|
36
|
+
`
|
|
37
|
+
: ""}
|
|
38
|
+
<p class="badge-subtitle">${this.subtitle}</p>
|
|
39
|
+
<bd-divider-horizontal></bd-divider-horizontal>
|
|
40
|
+
</div>
|
|
41
|
+
`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
PricingCardHeader.styles = [tokens, newHeaderPricingCSS];
|
|
45
|
+
|
|
46
|
+
customElements.define("pricing-card-header", PricingCardHeader);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
|
|
3
|
+
export default css`
|
|
4
|
+
.pricing {
|
|
5
|
+
text-align: left;
|
|
6
|
+
margin-top: var(--spacing-16);
|
|
7
|
+
}
|
|
8
|
+
.pricing-info {
|
|
9
|
+
display: flex;
|
|
10
|
+
gap: var(--spacing-8);
|
|
11
|
+
align-items: baseline;
|
|
12
|
+
margin-top: var(--spacing-16);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.original-price {
|
|
16
|
+
text-decoration: line-through;
|
|
17
|
+
font-family: var(--typography-fontFamily-sans);
|
|
18
|
+
color: #000000;
|
|
19
|
+
font-size: var(--typography-body-regular-fontSize);
|
|
20
|
+
margin: 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.discount {
|
|
24
|
+
color: #0b6a26;
|
|
25
|
+
font-weight: bold;
|
|
26
|
+
background: #d1fadc;
|
|
27
|
+
font-size: var(--typography-body-regular-fontSize);
|
|
28
|
+
padding: 5px;
|
|
29
|
+
border-radius: 20px;
|
|
30
|
+
font-family: var(--typography-fontFamily-sans);
|
|
31
|
+
margin: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.price {
|
|
35
|
+
font-size: var(--heading-xxlarge);
|
|
36
|
+
font-weight: var(--typography-fontWeight-bold);
|
|
37
|
+
text-align: left;
|
|
38
|
+
font-family: var(--typography-fontFamily-sans);
|
|
39
|
+
color: #000000;
|
|
40
|
+
margin: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.terms {
|
|
44
|
+
font-family: var(--typography-fontFamily-sans);
|
|
45
|
+
font-size: var(--typography-label-small-fontSize);
|
|
46
|
+
color: #000000;
|
|
47
|
+
text-align: left;
|
|
48
|
+
margin: 0;
|
|
49
|
+
margin-top: var(--spacing-8);
|
|
50
|
+
margin-bottom: var(--spacing-16);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.terms a {
|
|
54
|
+
font-family: var(--typography-fontFamily-sans);
|
|
55
|
+
font-size: var(--typography-label-small-fontSize);
|
|
56
|
+
color: #000000;
|
|
57
|
+
text-decoration: underline;
|
|
58
|
+
}
|
|
59
|
+
.toggle-group {
|
|
60
|
+
gap: var(--spacing-16);
|
|
61
|
+
display: flex;
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { LitElement, html } from "lit";
|
|
2
|
+
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
+
import newPricingPricingCSS from "../pricing-cards/pricing-card-pricing.css.js";
|
|
4
|
+
|
|
5
|
+
class PricingCardPricing extends LitElement {
|
|
6
|
+
static properties = {
|
|
7
|
+
price : { type: String }, // monthly price
|
|
8
|
+
originalPrice: { type: String, attribute: "original-price" }, // monthly original price
|
|
9
|
+
discount : { type: String }, // monthly discount text
|
|
10
|
+
billingPeriod: { type: String, state: true } // "monthly" or "yearly"
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
this.billingPeriod = "monthly";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
formatCurrency(value) {
|
|
20
|
+
if (!value || isNaN(value)) return "";
|
|
21
|
+
return `$${parseFloat(value).toFixed(2)}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Calculează valorile pentru yearly
|
|
25
|
+
get yearlyPrice() {
|
|
26
|
+
// Exemplu: 12 luni * price lunar cu 10% discount anual dummy
|
|
27
|
+
const monthlyPrice = parseFloat(this.price);
|
|
28
|
+
if (isNaN(monthlyPrice)) return "";
|
|
29
|
+
const yearly = monthlyPrice * 12 * 0.9; // 10% discount la anual
|
|
30
|
+
return yearly.toFixed(2);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get yearlyOriginalPrice() {
|
|
34
|
+
const monthlyOriginal = parseFloat(this.originalPrice);
|
|
35
|
+
if (isNaN(monthlyOriginal)) return "";
|
|
36
|
+
const yearlyOriginal = monthlyOriginal * 12;
|
|
37
|
+
return yearlyOriginal.toFixed(2);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get yearlyDiscount() {
|
|
41
|
+
// Exemplu text dummy pentru anual
|
|
42
|
+
return "Save 25%";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
render() {
|
|
46
|
+
const isMonthly = this.billingPeriod === "monthly";
|
|
47
|
+
|
|
48
|
+
const originalPrice = isMonthly
|
|
49
|
+
? this.originalPrice
|
|
50
|
+
: this.yearlyOriginalPrice;
|
|
51
|
+
const discount = isMonthly ? this.discount : this.yearlyDiscount;
|
|
52
|
+
const price = isMonthly ? this.price : this.yearlyPrice;
|
|
53
|
+
|
|
54
|
+
return html`
|
|
55
|
+
<div class="pricing">
|
|
56
|
+
<div class="toggle-group">
|
|
57
|
+
<bd-radio
|
|
58
|
+
name="billing"
|
|
59
|
+
value="monthly"
|
|
60
|
+
label="Monthly"
|
|
61
|
+
?checked=${isMonthly}
|
|
62
|
+
@change=${this.onBillingChange}
|
|
63
|
+
></bd-radio>
|
|
64
|
+
<bd-radio
|
|
65
|
+
name="billing"
|
|
66
|
+
value="yearly"
|
|
67
|
+
label="Yearly"
|
|
68
|
+
?checked=${!isMonthly}
|
|
69
|
+
@change=${this.onBillingChange}
|
|
70
|
+
></bd-radio>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div class="pricing-info">
|
|
74
|
+
${originalPrice
|
|
75
|
+
? html`<p class="original-price">
|
|
76
|
+
${this.formatCurrency(originalPrice)}
|
|
77
|
+
</p>`
|
|
78
|
+
: null}
|
|
79
|
+
<p class="discount">${discount}</p>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<p class="price">${this.formatCurrency(price)}</p>
|
|
83
|
+
|
|
84
|
+
<p class="terms">
|
|
85
|
+
First year price. Plus applicable sales tax. See
|
|
86
|
+
<a href="#">terms of use</a> below.
|
|
87
|
+
</p>
|
|
88
|
+
</div>
|
|
89
|
+
`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
onBillingChange(e) {
|
|
93
|
+
const value = e.target.value;
|
|
94
|
+
if (value === "monthly" || value === "yearly") {
|
|
95
|
+
this.billingPeriod = value;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
PricingCardPricing.styles = [tokens, newPricingPricingCSS];
|
|
100
|
+
|
|
101
|
+
customElements.define("pricing-card-pricing", PricingCardPricing);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
|
|
3
|
+
export default css`
|
|
4
|
+
.show-more-toggle {
|
|
5
|
+
display: block;
|
|
6
|
+
background: none;
|
|
7
|
+
border: none;
|
|
8
|
+
color: var(--color-blue-600);
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
font-size: var(--body-xlarge);
|
|
11
|
+
text-align: center;
|
|
12
|
+
margin: 1rem auto;
|
|
13
|
+
font-family: var(--typography-fontFamily-sans);
|
|
14
|
+
font-weight: var(--typography-fontWeight-semibold);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.feature-items {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
gap: 0.5rem;
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { LitElement, html } from 'lit';
|
|
2
|
+
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
+
import newShowMorePricingCSS from "../pricing-cards/pricing-card-show-more.css.js";
|
|
4
|
+
|
|
5
|
+
class PricingCardShowMore extends LitElement {
|
|
6
|
+
static properties = {
|
|
7
|
+
expanded: { type: Boolean }
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
this.expanded = false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
toggleFeatures() {
|
|
17
|
+
this.expanded = !this.expanded;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
render() {
|
|
21
|
+
return html`
|
|
22
|
+
<button @click="${this.toggleFeatures}" class="show-more-toggle">
|
|
23
|
+
${this.expanded ? '− Hide features' : '+ Show more features'}
|
|
24
|
+
</button>
|
|
25
|
+
${this.expanded
|
|
26
|
+
? html`<div class="feature-items"><slot></slot></div>`
|
|
27
|
+
: ''}
|
|
28
|
+
`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
PricingCardShowMore.styles = [tokens, newShowMorePricingCSS];
|
|
32
|
+
|
|
33
|
+
customElements.define('pricing-card-show-more', PricingCardShowMore);
|