@salla.sa/twilight-components
Version:
Salla Web Component
261 lines (256 loc) • 11.4 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
import { F as FilterOptionTypes, d as defineCustomElement$4 } from './salla-filters-widget2.js';
import { H as Helper } from './Helper.js';
import { d as defineCustomElement$5 } from './salla-button2.js';
import { d as defineCustomElement$3 } from './salla-price-range2.js';
import { d as defineCustomElement$2 } from './salla-rating-stars2.js';
const sallaFiltersCss = ":host{display:block}.s-rating-stars-small{line-height:12px}.s-filters-radio{background-image:none !important}";
const SallaFilters$1 = /*@__PURE__*/ proxyCustomElement(class SallaFilters extends HTMLElement {
constructor() {
super();
this.__registerHost();
this.changed = createEvent(this, "changed", 7);
this.isReady = false; //to avoid triggering the changed event
this.filtersData = {};
salla.event.on('filters::hidden', () => this.host.style.display = 'none');
salla.lang.onLoaded(() => {
this.apply = salla.lang.get('pages.checkout.apply');
this.reset = salla.lang.get('pages.categories.filters_reset');
});
salla.event.on('filters::fetched', ({ filters }) => {
this.host.style.display = '';
let freshFilterData = {};
this.filters = filters
.map((filter) => {
filter.label = {
category_id: salla.lang.get('common.titles.categories'),
brand_id: salla.lang.get('common.titles.brands'),
rating: salla.lang.get('pages.categories.filter_rating'),
price: salla.lang.get('pages.categories.filter_price'),
}[filter.key] || filter.label;
// filter.type = FilterOptionTypes.VALUES;
if (filter.key == 'rating') {
filter.type = FilterOptionTypes.VALUES;
//@ts-ignore
let { max, min } = filter.values;
//@ts-ignore
filter.values = [5, 4, 3, 2, 1].filter(stars => stars >= min || stars <= max);
}
if (this.filtersData.variants && filter.type == FilterOptionTypes.VARIANTS) {
freshFilterData.variants = this.filtersData.variants;
}
if (this.filtersData[filter.key] && filter.type !== FilterOptionTypes.VARIANTS) {
freshFilterData[filter.key] = this.filtersData[filter.key];
}
let searchParams = new URLSearchParams(window.location.search);
let hasFilters = false;
for (let key of searchParams.keys()) {
if (key.includes('filters')) {
hasFilters = true;
break; // No need to continue checking once a match is found
}
}
if (salla.config.get('page.slug') == "product.index" && Object.keys(freshFilterData).length == 0 && !hasFilters) {
// Append the current category to the url if there are no pre-selected filters
let currentUrl = window.location.href;
let filterValue = salla.config.get('page.id');
let separator = currentUrl.indexOf('?') !== -1 ? '&' : '?';
let newUrl = currentUrl + separator + 'filters[category_id]=' + filterValue;
freshFilterData.category_id = filterValue;
window.history.pushState({ path: newUrl }, '', newUrl);
}
return filter;
});
this.filtersData = freshFilterData;
this.host.childNodes.forEach(async (widget) => widget.setWidgetHeight && await widget.setWidgetHeight());
});
}
async componentWillLoad() {
try {
const searchParams = new URLSearchParams(window.location.search);
this.filtersData = await Helper.extractFiltersFromUrl(searchParams);
}
catch (e) {
console.warn('failed to get filters from URL', e.message);
}
}
/**
* Method to get filter data.
*/
async getFilters() {
return this.filtersData;
}
/**
* Apply filter action.
*/
async applyFilters() {
if (!this.isReady) {
return;
}
let hasFilters = Object.keys(this.filtersData).length > 0;
setTimeout(() => {
var _a;
if (hasFilters) {
let url = new URL(window.location.href);
for (const [key] of url.searchParams.entries()) {
if (key.startsWith("filters")) {
url.searchParams.delete(key);
}
}
let encodedFilterValues = this.encodeFilters(this.filtersData);
let sanitizedFilterValues = url.search.split("&").filter(item => !item.includes('filters')).join("&");
if (sanitizedFilterValues) {
url.search = url.search.split("&filters")[0] + "&" + encodedFilterValues;
}
else {
url.search = `?${encodedFilterValues}`;
}
window.history.pushState({}, '', url.href);
}
else {
let url = new URL(window.location.href);
(_a = url.searchParams) === null || _a === void 0 ? void 0 : _a.delete('filters');
window.history.pushState({}, '', url.toString());
}
salla.event.emit('salla-filters::changed', this.filtersData);
this.changed.emit(this.filtersData);
}, 300);
}
encodeFilters(filters, parentKey = 'filters') {
const encodedFilters = [];
for (const key in filters) {
if (Object.prototype.hasOwnProperty.call(filters, key)) {
const value = filters[key];
const fullKey = parentKey ? `${parentKey}[${key}]` : key;
if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
encodedFilters.push(`${fullKey}[${i}]=${value[i]}`);
}
}
else if (typeof value === 'object' && value !== null) {
encodedFilters.push(this.encodeFilters(value, fullKey));
}
else {
// const encodedKey = encodeURIComponent(fullKey);
// const encodedValue = encodeURIComponent(value);
let result = `${fullKey}=${value}`;
encodedFilters.push(result);
}
}
}
return encodedFilters.join('&');
}
;
/**
* Reset selected filters.
*/
async resetFilters() {
this.removeFiltersQueryParams();
this.filtersData = {};
this.host.childNodes.forEach((widget) => widget.reset && widget.reset());
salla.event.emit('salla-filters::reset');
return this.applyFilters();
}
removeFiltersQueryParams() {
const searchParams = new URLSearchParams(window.location.search);
const newUrl = Array.from(searchParams.keys())
.filter(key => !key.startsWith('filters['))
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(searchParams.get(key))}`)
.join('&');
const finalUrl = newUrl ? `${window.location.pathname}?${newUrl}` : window.location.pathname;
window.history.pushState({}, '', finalUrl);
}
/**
* @param {{target:HTMLInputElement}} event
* @param option
* @param value
* @private
*/
handleOptionChange(event, option, value) {
if (option.type === FilterOptionTypes.RANGE) {
this.filtersData[option.key] = value;
}
let isChecked = event.target.checked;
if (option.type === FilterOptionTypes.VARIANTS) {
this.filtersData.variants = this.filtersData.variants || {};
isChecked && (this.filtersData.variants[option.key] = value);
isChecked || (delete this.filtersData.variants[option.key]);
}
else if (event.target.type == "radio") {
isChecked && (this.filtersData[option.key] = value);
isChecked || (delete this.filtersData[option.key]);
}
//it's checkbox
// add if condition to avoid error when the filter is not existed in the filtersData
else if (event.target.type == "checkbox") {
this.filtersData[option.key] = this.filtersData[option.key] || [];
if (isChecked) {
this.filtersData[option.key].push(value);
}
this.filtersData[option.key] = this.filtersData[option.key].filter(val => val != value);
}
this.applyFilters();
}
render() {
var _a, _b;
return h(Host, { key: '80fda46c33daf06c6a22d567d13375351db4e3cb' }, (_a = this.filters) === null || _a === void 0 ? void 0 :
_a.map(option => h("salla-filters-widget", { option: option, filtersData: this.filtersData, onChanged: ({ detail: { event, option, value } }) => {
this.handleOptionChange(event, option, value);
} })), ((_b = this.filters) === null || _b === void 0 ? void 0 : _b.length) ? h("div", { class: "s-filters-footer" }, h("salla-button", { color: 'gray', fill: 'outline', onClick: () => this.resetFilters() }, this.reset)) : '');
}
componentDidLoad() {
this.isReady = true;
}
get host() { return this; }
static get style() { return sallaFiltersCss; }
}, [0, "salla-filters", {
"filters": [1040],
"isSidebarOpen": [32],
"filtersData": [32],
"apply": [32],
"reset": [32],
"getFilters": [64],
"applyFilters": [64],
"resetFilters": [64]
}]);
function defineCustomElement$1() {
if (typeof customElements === "undefined") {
return;
}
const components = ["salla-filters", "salla-button", "salla-filters-widget", "salla-price-range", "salla-rating-stars"];
components.forEach(tagName => { switch (tagName) {
case "salla-filters":
if (!customElements.get(tagName)) {
customElements.define(tagName, SallaFilters$1);
}
break;
case "salla-button":
if (!customElements.get(tagName)) {
defineCustomElement$5();
}
break;
case "salla-filters-widget":
if (!customElements.get(tagName)) {
defineCustomElement$4();
}
break;
case "salla-price-range":
if (!customElements.get(tagName)) {
defineCustomElement$3();
}
break;
case "salla-rating-stars":
if (!customElements.get(tagName)) {
defineCustomElement$2();
}
break;
} });
}
const SallaFilters = SallaFilters$1;
const defineCustomElement = defineCustomElement$1;
export { SallaFilters, defineCustomElement };
//# sourceMappingURL=salla-filters.js.map
//# sourceMappingURL=salla-filters.js.map