@salla.sa/twilight-components
Version:
Salla Web Component
229 lines (228 loc) • 9.18 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 numericValue = parseInt(salla.helpers.digitsOnly(String(value ?? '')), 10);
if (!Number.isFinite(numericValue) || numericValue < 1) {
numericValue = 1;
}
let maxQuantity = parseInt(this.host.getAttribute('max'));
if (maxQuantity && numericValue > maxQuantity) {
numericValue = maxQuantity;
}
this.quantity = numericValue;
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: '77565ee635cdda42e956be4fea503905fe4bf199', class: "s-quantity-input" }, h("div", { key: 'f8aa9fb2200032d503cdfc65a65bc2bf94e00eb8', class: "s-quantity-input-container" }, h("button", { key: '1711c74ee9b8f212c2651f9c3a2f3e6737fbe8f4', 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: '65803c2b491b5dbb1ae79787eec6151f742b517f', name: "increment-button" })), h("input", { key: '1b16e0e0603d91b3a12c968a98575f4146f2d7b6', class: "s-quantity-input-input", ...inputAttributes, ref: (el) => this.textInput = el, onInput: (event) => this.setValue(event.target.value), inputMode: "numeric", pattern: "[0-9]*", min: "1", readOnly: this.disableInput, value: this.quantity }), h("button", { key: 'ad33507fa617ddb6ebeee842c5f1f0b3595a475b', 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: '341b8e5d941e63c13c78061d24ecd2ba64d9a7a1', 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"
}];
}
}