@salla.sa/twilight-components
Version:
Salla Web Component
182 lines (181 loc) • 8.01 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
import { Host, h } from "@stencil/core";
import CartIcon from "../../assets/svg/cart.svg";
import anime from "animejs";
export class SallaCartSummary {
constructor() {
this.cartSummaryCount = salla.storage.get('cart.summary.count') || 0;
this.cartSummaryTotal = salla.storage.get('cart.summary.total') || 0;
this.cartLabel = salla.config.get('user.language_code') === 'ar' ? 'السلة' : 'Cart';
salla.cart.event.onUpdated((response) => {
this.cartSummaryCount = response.count || 0;
this.cartSummaryTotal = response.total || 0;
});
}
/**
* Animate product Image to cart summary
* @param image the image element to animate
*/
async animateToCart(image) {
document.querySelectorAll('.s-cart-thumb').forEach(el => el.remove());
if (!image?.src) {
salla.log('Failed to get the img element');
return;
}
let cartBtn = this.host.querySelector('#s-cart-icon'), btnOffset = cartBtn.getBoundingClientRect(), btnTop = btnOffset.top + window.scrollY, btnLeft = btnOffset.left + window.scrollX;
// get thumb position ---
let position = image.getBoundingClientRect(), width = image.offsetWidth + 'px', height = image.offsetHeight + 'px', top = position.top, left = position.left;
// create thumb img element ---
let img = document.createElement("img");
img.src = image.getAttribute('src');
img.className = "s-cart-thumb";
img.setAttribute("style", "object-fit:cover; width:" + width + '; height:' + height + '; top:' + top + 'px; left:' + left + 'px;z-index:99999999; ');
document.body.append(img);
let cartThumb = document.querySelector('.s-cart-thumb');
cartBtn.classList.remove('animated', 'rubberBand');
// start timeline ---
let cartThumbAnime = new anime.timeline();
cartThumbAnime.add({
targets: cartThumb,
width: [150, 30],
height: [150, 30],
top: [top, window.scrollY > 0 ? btnTop - window.scrollY - 40 : btnTop - 40],
left: [left, btnLeft],
borderRadius: ['20%', '50%'],
easing: 'easeOutExpo',
duration: 1200,
}, '+=200')
.add({
targets: cartThumb,
width: [30, 0],
height: [30, 0],
opacity: [1, 0],
easing: 'easeOutExpo',
top: [window.scrollY > 0 ? btnTop - window.scrollY - 40 : btnTop - 40, window.scrollY > 0 ? btnTop - window.scrollY + 10 : btnTop + 10],
left: [btnLeft, btnLeft + 10],
}, '-=500')
.add({
complete: function () {
cartBtn.classList.add('animated', 'rubberBand');
cartThumb.remove();
},
}, '-=1700');
}
/**
* Some times it renderes with main domain, something like `https://salla.sa/cart`, because salla is not loaded,
* here, we are sure it will not be rendred unless salla is ready
*/
componentWillLoad() {
return new Promise(resolve => salla.onReady(resolve));
}
/**
* Compute cart href with scope + allocation parameters.
* Uses storage (not config) so allocation_type/allocation_id set by bullet-delivery are included.
*/
getCartLink() {
let cartUrl = salla.url.get('cart');
// Prefer storage over config: storage holds allocation_type/allocation_id, config only has type+id
const scope = salla.storage.get('scope') || salla.config.get('store.scope');
if (scope && scope.id) {
try {
const url = new URL(cartUrl);
url.searchParams.set('scope', scope.id);
if (scope.allocation_type)
url.searchParams.set('allocation_type', scope.allocation_type);
if (scope.allocation_id)
url.searchParams.set('allocation_id', scope.allocation_id);
return url.toString();
}
catch (e) {
const delimiter = cartUrl.includes('?') ? '&' : '?';
const params = new URLSearchParams();
params.set('scope', String(scope.id));
if (scope.allocation_type)
params.set('allocation_type', scope.allocation_type);
if (scope.allocation_id)
params.set('allocation_id', scope.allocation_id);
return `${cartUrl}${delimiter}${params.toString()}`;
}
}
return cartUrl;
}
render() {
return (h(Host, { key: '918f027fd28cd25d653b8419f97223daaf22d428' }, h("a", { key: 'b74a2724ada356a01b915044d56dfb0f9953338e', class: "s-cart-summary-wrapper", href: this.getCartLink() }, h("div", { key: 'b9332fe1b66b895c1e9950efaa548f04eb053d46', id: "s-cart-icon" }, h("slot", { key: '2b5c1cf8dea4ca23a54beeb83cfad44538ca3ab7', name: "icon" }, h("i", { key: 'f3145ed4a994762441d925280a3234d78c378bef', class: "s-cart-summary-icon", innerHTML: CartIcon }))), h("span", { key: '26a78adf9b279019504e995216ea5373b6866876', class: "s-cart-summary-count" }, salla.helpers.number(this.cartSummaryCount)), h("p", { key: '60ad091221ed5cd3e2ac0d27ebc53ec9917ccd64', class: "s-cart-summary-content" }, this.showCartLabel && h("span", { key: '66819086b9ed7f6f21be2cd5e8baf0bc88021e40', class: "s-cart-summary-label" }, this.cartLabel), h("b", { key: 'a07c85971e50add3cdd5b51942e642d4daf19d82', class: "s-cart-summary-total", innerHTML: salla.money(this.cartSummaryTotal) })))));
}
static get is() { return "salla-cart-summary"; }
static get originalStyleUrls() {
return {
"$": ["salla-cart-summary.scss"]
};
}
static get styleUrls() {
return {
"$": ["salla-cart-summary.css"]
};
}
static get properties() {
return {
"showCartLabel": {
"type": "boolean",
"attribute": "show-cart-label",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Show cart label"
},
"getter": false,
"setter": false,
"reflect": false
}
};
}
static get states() {
return {
"cartSummaryCount": {},
"cartSummaryTotal": {},
"cartLabel": {}
};
}
static get methods() {
return {
"animateToCart": {
"complexType": {
"signature": "(image: any) => Promise<void>",
"parameters": [{
"name": "image",
"type": "any",
"docs": "the image element to animate"
}],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
},
"HTMLImageElement": {
"location": "global",
"id": "global::HTMLImageElement"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Animate product Image to cart summary",
"tags": [{
"name": "param",
"text": "image the image element to animate"
}]
}
}
};
}
static get elementRef() { return "host"; }
}