@salla.sa/twilight-components
Version:
Salla Web Component
228 lines (227 loc) • 8.98 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
import { Host, h } from "@stencil/core";
import Add from "../../assets/svg/add.svg";
import Minus from "../../assets/svg/minus.svg";
import Helper from "../../Helpers/Helper";
export class SallaQuantityInput {
constructor() {
/**
* Based on store setting: store.settings.product.manual_quantity
*/
this.disableInput = false;
this.hostAttributes = {};
this.hasIncrementSlot = false;
this.hasDecrementSlot = false;
this.didLoaded = false;
this.quantity = 1;
this.fireChangeEvent = true;
}
/**
* Workaround to fire change event for the input.
*/
watchPropHandler() {
if (!this.didLoaded) {
return;
}
if (!this.fireChangeEvent) {
this.fireChangeEvent = true;
return;
}
Helper.debounce(() => {
salla.document.event.fireEvent(this.textInput, 'change', {
bubbles: true,
detail: { productId: this.cartItemId, quantity: this.quantity }
});
});
}
async componentWillLoad() {
await salla.onReady();
this.disableInput = !salla.config.get('store.settings.product.manual_quantity');
this.quantity = parseInt(this.host.getAttribute('value')) || 1;
this.hasIncrementSlot = !!this.host.querySelector('[slot="increment-button"]');
this.hasDecrementSlot = !!this.host.querySelector('[slot="decrement-button"]');
}
componentDidLoad() {
this.didLoaded = true;
this.textInput.addEventListener('input', (event) => salla.helpers.inputDigitsOnly(event.target));
}
getInputAttributes() {
for (let i = 0; i < this.host.attributes.length; i++) {
if (!['id', 'value', 'min', 'class'].includes(this.host.attributes[i].name)) {
this.hostAttributes[this.host.attributes[i].name] = this.host.attributes[i].value;
}
}
return this.hostAttributes;
}
/**
* decrease quantity by one.
* @return HTMLSallaQuantityInputElement
*/
async decrease() {
return this.setValue(this.quantity - 1);
}
/**
* increase quantity by one.
* @return HTMLSallaQuantityInputElement
*/
async increase() {
return this.setValue(Number(this.quantity) + 1);
}
/**
* set quantity by one.
* @return HTMLSallaQuantityInputElement
*/
async setValue(value, fireChangeEvent = true) {
this.fireChangeEvent = fireChangeEvent;
let maxQuantity = parseInt(this.host.getAttribute('max'));
if (maxQuantity && value > maxQuantity) {
value = maxQuantity;
}
if (value <= 1) {
value = 1;
}
this.quantity = value;
return this.host;
}
render() {
const inputAttributes = this.getInputAttributes();
if (!inputAttributes['aria-label'] && !inputAttributes['aria-labelledby']) {
inputAttributes['aria-label'] = salla.lang.getWithDefault('common.elements.quantity', 'Quantity');
}
return (h(Host, { key: 'c9b83e158f990a40a69100bcc7880bc208433de1', class: "s-quantity-input" }, h("div", { key: '74ee814b486365c28950a675f0e75ed78fad1549', class: "s-quantity-input-container" }, h("button", { key: 'a78de04f1ca0efc4b20d3fc4acdb1d881bf31501', onClick: () => this.increase(), class: "s-quantity-input-increase-button s-quantity-input-button", type: "button", "aria-label": salla.lang.getWithDefault('common.elements.increase_quantity', 'Increase quantity') }, !this.hasIncrementSlot ? h("span", { innerHTML: Add }) : '', h("slot", { key: 'd1222cf3e005c8fbf1d38e42589e5abac08b99bf', name: "increment-button" })), h("input", { key: 'b2402558907f7e0e15bf622b1524a5649d74fe8d', class: "s-quantity-input-input", ...inputAttributes, ref: (el) => this.textInput = el, onInput: (event) => this.setValue(event.target.value), min: "1", readOnly: this.disableInput, value: this.quantity }), h("button", { key: '578d4ff2f4c4d6b778d052a2eed68f9abcc8625b', class: "s-quantity-input-decrease-button s-quantity-input-button", onClick: () => this.decrease(), type: "button", "aria-label": salla.lang.getWithDefault('common.elements.decrease_quantity', 'Decrease quantity') }, !this.hasDecrementSlot ? h("span", { innerHTML: Minus }) : '', h("slot", { key: 'e8540cb6aae1027d76736069f2372ba18903bd25', name: "decrement-button" })))));
}
static get is() { return "salla-quantity-input"; }
static get originalStyleUrls() {
return {
"$": ["salla-quantity-input.scss"]
};
}
static get styleUrls() {
return {
"$": ["salla-quantity-input.css"]
};
}
static get properties() {
return {
"cartItemId": {
"type": "any",
"attribute": "cart-item-id",
"mutable": false,
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Cart Item Id"
},
"getter": false,
"setter": false,
"reflect": false
}
};
}
static get states() {
return {
"disableInput": {},
"quantity": {},
"fireChangeEvent": {}
};
}
static get methods() {
return {
"decrease": {
"complexType": {
"signature": "() => Promise<HTMLElement>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
},
"HTMLElement": {
"location": "global",
"id": "global::HTMLElement"
}
},
"return": "Promise<HTMLElement>"
},
"docs": {
"text": "decrease quantity by one.",
"tags": [{
"name": "return",
"text": "HTMLSallaQuantityInputElement"
}]
}
},
"increase": {
"complexType": {
"signature": "() => Promise<HTMLElement>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
},
"HTMLElement": {
"location": "global",
"id": "global::HTMLElement"
}
},
"return": "Promise<HTMLElement>"
},
"docs": {
"text": "increase quantity by one.",
"tags": [{
"name": "return",
"text": "HTMLSallaQuantityInputElement"
}]
}
},
"setValue": {
"complexType": {
"signature": "(value: any, fireChangeEvent?: boolean) => Promise<HTMLElement>",
"parameters": [{
"name": "value",
"type": "any",
"docs": ""
}, {
"name": "fireChangeEvent",
"type": "boolean",
"docs": ""
}],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
},
"HTMLElement": {
"location": "global",
"id": "global::HTMLElement"
}
},
"return": "Promise<HTMLElement>"
},
"docs": {
"text": "set quantity by one.",
"tags": [{
"name": "return",
"text": "HTMLSallaQuantityInputElement"
}]
}
}
};
}
static get elementRef() { return "host"; }
static get watchers() {
return [{
"propName": "quantity",
"methodName": "watchPropHandler"
}];
}
}