UNPKG

vj-pricing-model

Version:

Pricing model Vanilla JavaScript Web Component

237 lines (209 loc) 5.47 kB
const template = document.createElement('template'); template.innerHTML = ` <main class="container"> <div class="package"> <div class="pkg-info item"> <span class="package-name"></span> <!-- <slot name="package-name"></slot> --> </div> <div class="price item"> <div> <span class="money-symbol"></span> <span class="money-value"></span> </div> <div class="term">Per Month</div> </div> <!-- <div class="name item"></div> --> <div class="feature item"> <ul class="feature-list"></ul> </div> <div class="action item"> <button class="btn">Select</button> </div> </div> </main> <style> .container { --border-color: #ddd; font-family: 'Open Sans', sans-serif; } .package { border: 1px solid var(--border-color); display: flex; flex-direction: column; justify-content: space-between; align-items: center; } .item { width: 100%; } .pkg-info { font-family: 'Open Sans', sans-serif; font-size: 24px; font-weight: bold; padding: 15px 0; text-align: center; text-transform: uppercase; } .price { background-color: #ddd; padding: 15% 0; text-align: center; font-size: 3.5em; } .price .term { font-size: 18px; font-weight: bold; } .feature > .feature-list { list-style-type : none; padding: 10px; } .feature > .feature-list > li { margin: 10px; text-align: center; } .action { width: 100%; } .action .btn { font-family: 'Open Sans', sans-serif; font-size: 18px; text-transform: capitalize; margin: 5px 0; padding:10px; width: 100%; box-shadow: 0 0 0 3px rgba(54,54,54,0.03); border: none; } .btn { position: relative; cursor: pointer; margin: 0 auto; transition: all 0.4s ease-in; } //start click effect .btn:before { content: ''; background-color: aliceblue; border-radius: 50%; display: block; position: absolute; top: 0; right: 0; bottom: 0; left: 0; transform: scale(0.001, 0.001); } &:focus { outline: 0; color: #fff; &:before { animation: click_effect 0.8s ease-out; } } @keyframes click_effect { 50% { transform: scale(1.5, 1.5); opacity: 0; } 99% { transform: scale(0.001, 0.001); opacity: 0; } 100% { transform: scale(0.001, 0.001); opacity: 1; } } /* Media Queries */ @media only screen and (max-width: 767px) { } </style> `; class PricingItemComponent extends HTMLElement { constructor() { super(); this._shadowRoot = this.attachShadow({ mode: 'open' }); } connectedCallback() { // Shadow DOM this._shadowRoot.appendChild(template.content.cloneNode(true)); // element references this.$pkgName = this._shadowRoot.querySelector('.pkg-info .package-name'); this.$priceElement = this._shadowRoot.querySelector('.price'); this.$moneySymbol = this._shadowRoot.querySelector('.price .money-symbol'); this.$moneyValue = this._shadowRoot.querySelector('.price .money-value'); this.$features = this._shadowRoot.querySelector('.feature-list'); this.$cta = this._shadowRoot.querySelector('.action .btn'); this.$cta.addEventListener('click', this.selectPricing.bind(this)); // this.updatePriceItem = this.updatePriceItem.bind(this); if (this._data && Object.keys(this._data).length) this.updatePriceItem(); } static get observedAttributes() { return ['data']; } attributeChangedCallback(name, oldVal, newVal) { if (name === 'data' && newVal) { this._data = JSON.parse(newVal); } } selectPricing() { try { this.dispatchEvent(new CustomEvent('item-selected', { detail: { pkgName: this._data.package_name } })); } catch (error) { throw error; } } addFeatureItem(content) { try { if (content) { const li = document.createElement('li'); li.textContent = content; return li; } } catch (error) { throw error; } } updatePriceItem() { try { if (this._data) { const { package_name, price: { symbol, value }, features, call_to_action: { text, color, bgColor } } = this._data; if (package_name) { this.$pkgName.textContent = package_name; } this.$priceElement.style.color = bgColor; if (symbol) { this.$moneySymbol.textContent = symbol; } if (value) { this.$moneyValue.textContent = value; } if (text) { this.$cta.textContent = text; } if (color) { this.$cta.style.color = color; } if (bgColor) { this.$cta.style.backgroundColor = bgColor; } if (features && features.length) { for (const content of features) { this.$features.appendChild(this.addFeatureItem(content)); } } } } catch (error) { throw error; } } } customElements.define('vj-pricing-item', PricingItemComponent); export default PricingItemComponent;