@salla.sa/twilight-components
Version:
Salla Web Component
189 lines (185 loc) • 10.7 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
import { K as KeyBoardArrowLeftIcon, a as KeyBoardArrowRightIcon } from './keyboard_arrow_right.js';
import { d as defineCustomElement$1 } from './salla-slider2.js';
const sallaMultipleBundleProductSliderCss = "";
const SallaMultipleBundleProductSlider = /*@__PURE__*/ proxyCustomElement(class SallaMultipleBundleProductSlider extends HTMLElement {
constructor() {
super();
this.__registerHost();
this.productSelected = createEvent(this, "productSelected", 7);
this.productOptionsSelected = createEvent(this, "productOptionsSelected", 7);
/** A dictionary tracking which product IDs are currently selected per section. */
this.selectedProducts = {};
/** When true, the selected product cannot be deselected (single-product section with min = 1). */
this.isSelectionLocked = false;
/** Maximum selectable products for this section (empty max → all products in section). */
this.selectionLimit = 0;
this.savedOptionsByInstance = {};
this.handleProductClick = (product, productIndex) => {
const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
const checkbox = this.getCheckbox(this.section.id, productIndex);
if (isChecked && this.isSelectionLocked) {
if (checkbox) {
checkbox.checked = true;
}
return;
}
if (!isChecked && this.isMaxSelectionReached() && this.selectionLimit !== 1) {
return;
}
// max = 1: parent replaces selection and syncs all checkboxes in the section
if (this.selectionLimit === 1 && !isChecked) {
this.productSelected.emit({
product,
sectionId: this.section.id,
});
return;
}
if (!checkbox)
return;
const willBeChecked = !checkbox.checked;
if (!willBeChecked) {
this.dispatchClearOptionsEvent(product, productIndex);
this.clearSavedOptionsState(this.section.id, productIndex);
}
checkbox.checked = willBeChecked;
requestAnimationFrame(() => {
const changeEvent = new window.Event('change', { bubbles: true });
checkbox.dispatchEvent(changeEvent);
});
this.productSelected.emit({
product,
sectionId: this.section.id,
});
};
this.handleOptionsClick = (product) => {
const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
if (!isChecked && this.isMaxSelectionReached() && this.selectionLimit !== 1) {
return;
}
this.productOptionsSelected.emit({
product,
sectionId: this.section.id,
});
};
}
getSelectedCount() {
return this.selectedProducts[this.section?.id]?.size ?? 0;
}
isMaxSelectionReached() {
return this.selectionLimit > 1 && this.getSelectedCount() >= this.selectionLimit;
}
isProductSelectionDisabled(product, isChecked) {
if (product.quantity === 0) {
return true;
}
return !isChecked && this.isMaxSelectionReached();
}
getProductInstanceKey(sectionId, productIndex) {
return `${sectionId}::${productIndex}`;
}
dispatchClearOptionsEvent(product, productIndex) {
salla.event.dispatch('multiple-bundle-product-modal::clear-options', {
productId: product.id,
sectionId: this.section.id,
sectionIndex: this.sectionIndex,
productIndex,
});
}
handleOptionsSaved(event) {
const detail = event.detail;
if (!detail)
return;
const { sectionId, productIndex, selectedOptions } = detail;
if (sectionId == null || sectionId !== this.section?.id)
return;
if (productIndex == null || Number.isNaN(productIndex))
return;
const key = this.getProductInstanceKey(sectionId, productIndex);
const hasOptions = !!selectedOptions?.length;
if (hasOptions) {
this.savedOptionsByInstance = {
...this.savedOptionsByInstance,
[key]: true,
};
}
else if (this.savedOptionsByInstance[key]) {
const updatedState = { ...this.savedOptionsByInstance };
delete updatedState[key];
this.savedOptionsByInstance = updatedState;
}
}
clearSavedOptionsState(sectionId, productIndex) {
const key = this.getProductInstanceKey(sectionId, productIndex);
if (!this.savedOptionsByInstance[key])
return;
const updatedState = { ...this.savedOptionsByInstance };
delete updatedState[key];
this.savedOptionsByInstance = updatedState;
}
generateEventName(sectionId, productIndex) {
return `bundle[${sectionId}][${productIndex}][id]`;
}
getCheckbox(sectionId, productIndex) {
const name = this.generateEventName(sectionId, productIndex);
return this.host.querySelector(`input.s-multiple-bundle-product-checkbox[name="${name}"]`);
}
preventLockedDeselect(event, isChecked) {
if (!this.isSelectionLocked || !isChecked) {
return;
}
event.preventDefault();
event.stopPropagation();
const checkbox = event.target;
if (checkbox?.type === 'checkbox') {
checkbox.checked = true;
}
}
render() {
return (h(Host, { key: 'd52eb26454606df2526fa4c086110a54f7466644' }, h("salla-slider", { key: '1aa1fce5943c3721a8e4f762171c864d9097bb28', type: "carousel", controlsOuter: false, showControls: false, id: `accordion-multiple-bundle-product-${this.section.id}`, pagination: true, class: "s-multiple-bundle-product-wrapper-slider", sliderConfig: { spaceBetween: 0 } }, h("div", { key: '9342381bc43389bae48b906a1ab23a4f3cf8d00a', slot: "items" }, this?.section?.products?.map((product, productIndex) => {
const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
const isLocked = isChecked && this.isSelectionLocked;
const isDisabled = this.isProductSelectionDisabled(product, isChecked);
const hasSavedOptions = this.savedOptionsByInstance[this.getProductInstanceKey(this.section.id, productIndex)];
const optionsButtonLabel = hasSavedOptions
? salla.lang.getWithDefault('pages.products.edit_selected_options', 'تعديل الخيارات')
: salla.lang.get('pages.products.choose_from_options');
let optionsArrowIcon = salla.config.get('theme.is_rtl', true)
? KeyBoardArrowLeftIcon
: KeyBoardArrowRightIcon;
return (h("div", { class: `s-multiple-bundle-product-slide-one-third${isDisabled ? ' s-multiple-bundle-product-slide-one-third-disabled' : ''}`, key: product.id }, h("div", { class: "s-multiple-bundle-product-card" }, h("div", { class: "s-multiple-bundle-product-image-wrapper", onClick: () => this.handleProductClick(product, productIndex) }, h("input", { id: this.generateEventName(this.section.id, productIndex), type: "checkbox", class: "s-multiple-bundle-product-checkbox", checked: isChecked, "data-selection-locked": isLocked ? 'true' : undefined, name: this.generateEventName(this.section.id, productIndex), value: product.id, onClick: event => this.preventLockedDeselect(event, isChecked), onChange: event => this.preventLockedDeselect(event, isChecked) }), h("img", { src: product.image.url || salla.url.cdn('images/s-empty.png'), loading: "lazy", alt: product.image.alt || product.name, class: "s-multiple-bundle-product-image" })), h("div", { class: "s-multiple-bundle-product-content-wrapper" }, h("div", { class: "s-multiple-bundle-product-content" }, h("div", { class: "s-multiple-bundle-product-details" }, h("div", { class: "s-multiple-bundle-product-title-wrapper" }, h("h2", { class: "s-multiple-bundle-product-title" }, h("a", { href: product?.url || '#', target: "_blank", rel: "noopener noreferrer" }, product.name))), h("div", { class: "s-multiple-bundle-product-price-wrapper" }, h("span", { class: "s-multiple-bundle-product-price" }, h("span", { innerHTML: salla.money(product.price) })), product.sale_price > 0 && (h("span", { class: "s-multiple-bundle-product-price-discount" }, h("span", { innerHTML: salla.money(product.regular_price) }))))), product.quantity_in_group > 0 && product.quantity !== 0 && (h("span", { class: "s-multiple-bundle-product-badge" }, salla.lang.get('pages.products.pieces'), h("span", null, product.quantity_in_group))), product.quantity === 0 && (h("span", { class: "s-multiple-bundle-product-badge" }, salla.lang.get('pages.products.quantity_in_group_finished')))), product.options?.length > 0 && (h("button", { class: "s-multiple-bundle-product-button", onClick: () => this.handleOptionsClick(product), type: "button" }, optionsButtonLabel, h("span", { class: "s-multiple-bundle-product-button-icon", innerHTML: optionsArrowIcon })))))));
})))));
}
get host() { return this; }
static get style() { return sallaMultipleBundleProductSliderCss; }
}, [0, "salla-multiple-bundle-product-slider", {
"section": [16],
"sectionIndex": [2, "section-index"],
"selectedProducts": [16, "selected-products"],
"isSelectionLocked": [4, "is-selection-locked"],
"selectionLimit": [2, "selection-limit"],
"savedOptionsByInstance": [32]
}, [[4, "optionsSaved", "handleOptionsSaved"]]]);
function defineCustomElement() {
if (typeof customElements === "undefined") {
return;
}
const components = ["salla-multiple-bundle-product-slider", "salla-slider"];
components.forEach(tagName => { switch (tagName) {
case "salla-multiple-bundle-product-slider":
if (!customElements.get(tagName)) {
customElements.define(tagName, SallaMultipleBundleProductSlider);
}
break;
case "salla-slider":
if (!customElements.get(tagName)) {
defineCustomElement$1();
}
break;
} });
}
defineCustomElement();
export { SallaMultipleBundleProductSlider as S, defineCustomElement as d };