@salla.sa/twilight-components
Version:
Salla Web Component
255 lines (254 loc) • 11.2 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
import { h } from "@stencil/core";
/**
* @slot header - The top of the modal.
* @slot footer - Replaces the bottom button.
* @slot language - Replaces language label, has replaceable props `{name}`, `{code}`, `{country_code}`.
* @slot currency - Replaces currency label, has replaceable props `{name}`, `{code}`, `{country_code}`.
*/
export class SallaLocalizationModal {
constructor() {
var _a, _b;
this.translationLoaded = false;
this.languages = [];
this.currencies = [];
this.hasError = false;
this.errorMessage = undefined;
this.language = salla.config.get('user.language_code');
this.currency = salla.config.get('user.currency_code');
salla.event.on('localization::open', () => this.open());
salla.lang.onLoaded(() => {
this.translationLoaded = true;
});
/**
* letting developer to insert his own slot like:
* <salla-localization>
* <div slot="language">...{name}....</div>
* <div slot="currency">...{name}....</div>
* </salla-localization>
* Because scoped templates not supported in stencil );
* we made a workaround to pass language & currency attributes, then replace names in rendering
*/
this.languageSlot = ((_a = this.host.querySelector('[slot="language"]')) === null || _a === void 0 ? void 0 : _a.innerHTML) || '<label class="s-localization-modal-label" for="lang-{code}"><span>{name}</span><div class="s-localization-modal-flag flag iti__flag iti__{country_code}"></div></label>';
this.currencySlot = ((_b = this.host.querySelector('[slot="currency"]')) === null || _b === void 0 ? void 0 : _b.innerHTML) || '<label class="s-localization-modal-label" for="currency-{code}"><span>{name}</span><small class="s-localization-modal-currency">{code}</small></label>';
}
/**
* open the component
*/
async open() {
this.modal.open();
return await salla.api.withoutNotifier(() => this.getLanguages())
.then(() => this.getCurrencies())
.then(() => {
if (this.languages.length < 2 && this.currencies.length < 2) {
this.modal.close();
}
})
.catch(e => {
var _a, _b, _c, _d;
console.log(e);
this.hasError = true;
this.errorMessage = ((_c = (_b = (_a = e.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c.message) || ((_d = e.response) === null || _d === void 0 ? void 0 : _d.data);
})
.finally(() => this.modal.stopLoading());
}
/**
* Hide the component
*/
async close() {
return this.modal.close();
}
async getLanguages() {
this.language = this.language || salla.config.get('user.language_code');
return this.languages.length > 1 ? null : await salla.config.languages().then(data => this.languages = data);
}
async getCurrencies() {
this.currency = this.currency || salla.config.get('user.currency_code');
return this.currencies.length > 1 ? null : await salla.config.currencies().then(data => this.currencies = Object.values(data || {}));
}
onChangeCurrency(event) {
this.currency = event.target.value;
}
onChangeLanguage(event) {
this.language = event.target.value;
}
/**
* Change currency and language to the selected ones.
*/
async submit() {
let url;
this.btn.load()
.then(() => {
if (!this.currency) {
salla.log('There is no currency!');
return;
}
if (this.currency === salla.config.get('user.currency_code', 'SAR')) {
return;
}
url = window.location.href;
return salla.currency.api.change(this.currency);
})
.then(() => {
if (this.language !== salla.config.get('user.language_code', 'ar')) {
url = salla.helpers.addParamToUrl('lang', this.language);
}
})
.then(() => this.btn.stop())
.then(() => this.close())
.then(() => {
if (url) {
window.location.href = url.replace(`/${salla.config.get('user.language_code')}/`, `/${this.language}/`);
}
});
}
render() {
return (h("salla-modal", { isLoading: true, class: "s-hidden", ref: modal => this.modal = modal, width: "xs" }, h("div", { slot: 'loading' }, h("div", { class: "s-localization-modal-skeleton" }, h("salla-skeleton", { width: '25%', height: '15px' }), h("div", { class: "s-localization-modal-skeleton-content" }, [...Array(4)].map(() => h("div", { class: "s-localization-modal-skeleton-item" }, h("div", { class: "s-localization-modal-skeleton-item-flex" }, h("salla-skeleton", { type: 'circle', height: '16px', width: '16px' }), h("salla-skeleton", { height: '10px', width: '100px' })), h("salla-skeleton", { height: '15px', width: '20px' })))), h("salla-skeleton", { width: '25%', height: '15px' }), h("div", { class: "s-localization-modal-skeleton-content" }, [...Array(4)].map(() => h("div", { class: "s-localization-modal-skeleton-item" }, h("div", { class: "s-localization-modal-skeleton-item-flex" }, h("salla-skeleton", { type: 'circle', height: '16px', width: '16px' }), h("salla-skeleton", { height: '10px', width: '100px' })), h("salla-skeleton", { height: '15px', width: '20px' })))), h("salla-skeleton", { height: '40px', width: '100%' }))), !!this.hasError ?
h("salla-placeholder", { alignment: "center" }, h("span", { slot: "description" }, this.errorMessage)) :
h("div", { class: "s-localization-modal-inner" }, this.languages.length > 1 ?
h("div", { class: "s-localization-modal-section" }, h("label", { class: "s-localization-modal-title" }, salla.lang.get('common.titles.language')), h("div", { class: "s-localization-modal-section-inner" }, this.languages.length < 6 ?
this.languages.map(lang => h("div", { class: "s-localization-modal-item" }, h("input", { class: "s-localization-modal-input", type: "radio", checked: this.language == lang.iso_code, onChange: () => this.language = lang.iso_code, name: "language", id: 'lang-' + lang.code.toLowerCase(), value: lang.code }), h("div", { class: "s-localization-modal-label-slot", id: "language-slot", innerHTML: this.languageSlot
.replace(/\{name\}/g, lang.name)
.replace(/\{code\}/g, lang.code)
.replace(/\{country_code\}/g, lang.country_code) }))) :
h("select", { class: "s-localization-modal-select", name: "language", onChange: e => this.onChangeLanguage(e) }, this.languages.map(lang => h("option", { value: lang.code, selected: this.language == lang.code }, lang.name)))))
: '', this.currencies.length > 1 ?
h("div", { class: "s-localization-modal-section" }, h("label", { class: "s-localization-modal-title" }, salla.lang.get('common.titles.currency')), h("div", { class: "s-localization-modal-section-inner" }, this.currencies.length < 6 ?
this.currencies.map(currency => h("div", { class: "s-localization-modal-item" }, h("input", { class: "s-localization-modal-input", type: "radio", name: "currency", checked: this.currency == currency.code, onChange: () => this.currency = currency.code, id: 'currency-' + currency.code, value: currency.code }), h("div", { class: "s-localization-modal-label-slot", id: "currency-slot", innerHTML: this.currencySlot
.replace(/\{name\}/g, currency.name)
.replace(/\{code\}/g, currency.code)
.replace(/\{country_code\}/g, currency.country_code) }))) :
h("select", { class: "s-localization-modal-select", name: "currency", onChange: e => this.onChangeCurrency(e) }, this.currencies.map(currency => h("option", { value: currency.code, selected: this.currency == currency.code }, currency.name)))))
: '', h("salla-button", { width: "wide", ref: btn => this.btn = btn, onClick: () => this.submit() }, salla.lang.get('common.elements.ok')))));
}
/**
* to reduce dom levels we will move slot data into the parent dom
*/
componentDidRender() {
this.host.querySelectorAll('#currency-slot').forEach(el => el.replaceWith(el.firstChild));
this.host.querySelectorAll('#language-slot').forEach(el => el.replaceWith(el.firstChild));
}
static get is() { return "salla-localization-modal"; }
static get originalStyleUrls() {
return {
"$": ["salla-localization-modal.scss"]
};
}
static get styleUrls() {
return {
"$": ["salla-localization-modal.css"]
};
}
static get properties() {
return {
"language": {
"type": "string",
"mutable": true,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Current language (existing or newly selected)"
},
"attribute": "language",
"reflect": true,
"defaultValue": "salla.config.get('user.language_code')"
},
"currency": {
"type": "string",
"mutable": true,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Current currency (existing or newly selected)"
},
"attribute": "currency",
"reflect": true,
"defaultValue": "salla.config.get('user.currency_code')"
}
};
}
static get states() {
return {
"translationLoaded": {},
"languages": {},
"currencies": {},
"hasError": {},
"errorMessage": {}
};
}
static get methods() {
return {
"open": {
"complexType": {
"signature": "() => Promise<any>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
}
},
"return": "Promise<any>"
},
"docs": {
"text": "open the component",
"tags": []
}
},
"close": {
"complexType": {
"signature": "() => Promise<HTMLElement>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
},
"HTMLElement": {
"location": "global",
"id": "global::HTMLElement"
}
},
"return": "Promise<HTMLElement>"
},
"docs": {
"text": "Hide the component",
"tags": []
}
},
"submit": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Change currency and language to the selected ones.",
"tags": []
}
}
};
}
static get elementRef() { return "host"; }
}
//# sourceMappingURL=salla-localization-modal.js.map