@salla.sa/twilight-components
Version:
Salla Web Component
256 lines (255 loc) • 8.78 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
import { Host, h } from "@stencil/core";
import Star2 from "../../assets/svg/star2.svg";
import Helper from "../../Helpers/Helper";
export class SallaRatingStars {
constructor() {
this.translationsLoaded = false;
this.labels = [];
this.reviewLabel = '';
this.selectedStar = 0;
this.name = 'rating';
this.size = 'medium';
this.value = undefined;
this.reviews = 0;
this.withLabel = undefined;
this.editable = false;
}
async componentWillLoad() {
await new Promise(resolve => {
salla.lang.onLoaded(() => {
this.labels = [
salla.lang.get('pages.rating.poor'),
salla.lang.get('pages.rating.average'),
salla.lang.get('pages.rating.good'),
salla.lang.get('pages.rating.very_good'),
salla.lang.get('pages.rating.excellent')
];
if (this.value && this.withLabel) {
this.reviewLabel = this.labels[this.value - 1];
}
if (this.reviewsElement) {
this.reviewsElement.innerText = `(${salla.helpers.number(salla.lang.choice('pages.rating.reviews', this.reviews))})`;
}
this.translationsLoaded = true;
resolve();
});
});
}
initiateRating() {
this.host.addEventListener('click', this.handleRating.bind(this));
}
handleRating() {
if (!this.starsElem)
return;
let activeStars = this.starsElem.querySelectorAll('.s-rating-stars-hovered');
let selected = activeStars[activeStars.length - 1];
if (!selected)
return;
let selectedIndex = parseInt(selected.getAttribute('data-star'));
this.starsElem.querySelector('.rating_hidden_input').value = selectedIndex.toString();
this.starsElem.querySelectorAll('.s-rating-stars-btn-star')
.forEach((star, index) => Helper.toggleElementClassIf(star, 's-rating-stars-selected', 's-rating-stars-unselected', () => index < selectedIndex));
this.starsElem.querySelectorAll('[aria-pressed]').forEach(star => star.removeAttribute('aria-pressed'));
selected.setAttribute('aria-pressed', 'true');
this.selectedStar = selectedIndex;
this.withLabel && (this.reviewLabel = this.labels[selectedIndex - 1]);
}
triggerRatingProgrammatically(index) {
if (!this.starsElem)
return;
const stars = this.starsElem.querySelectorAll('.s-rating-stars-btn-star');
if (stars && index >= 0 && index <= stars.length) {
// Simulate the hovering effect
stars.forEach((s, i) => {
s.classList.toggle('s-rating-stars-hovered', i <= index);
});
// Trigger the same logic as clicking
this.handleRating();
}
}
highlightSelectedStars() {
var _a, _b;
let hoveredClass = 's-rating-stars-hovered', stars = (_a = this.starsElem) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.s-rating-stars-btn-star');
stars === null || stars === void 0 ? void 0 : stars.forEach((star, index) => {
star.addEventListener('mouseover', () => {
for (let i = 0; i <= index; i++) {
stars[i].classList.add(hoveredClass);
}
this.withLabel && (this.reviewLabel = this.labels[index]);
});
star.addEventListener('mouseout', () => {
star.classList.remove(hoveredClass);
this.withLabel && (this.reviewLabel = this.selectedStar ? this.labels[this.selectedStar - 1] : '');
});
});
(_b = this.starsElem) === null || _b === void 0 ? void 0 : _b.addEventListener('mouseout', () => stars.forEach(star => star.classList.remove(hoveredClass)));
}
createStars(n) {
let stars = [];
for (let i = 0; i < 5; i++) {
stars.push(h("span", { class: {
's-rating-stars-btn-star': true,
['s-rating-stars-' + this.size]: true,
's-rating-stars-selected': i < n
}, innerHTML: Star2 }));
}
if (this.reviews > 0) {
stars.push(h("span", { class: "s-rating-stars-reviews", ref: el => this.reviewsElement = el }, "(", salla.helpers.number(salla.lang.choice('pages.rating.reviews', this.reviews)), ")"));
}
return stars;
}
render() {
var _a;
return this.translationsLoaded ? (((_a = this.host.closest('.swiper-slide')) === null || _a === void 0 ? void 0 : _a.classList.contains('swiper-slide-duplicate'))
? ''
: (h(Host, null, (this.value || this.value == 0) && !this.editable ?
h("div", { class: "s-rating-stars-wrapper" }, this.createStars(this.value), this.withLabel && this.reviewLabel ? h("span", { class: "s-rating-stars-label" }, this.reviewLabel) : '')
:
h("div", { class: "s-rating-stars-wrapper" }, h("div", { class: "s-rating-stars-element", ref: (el) => this.starsElem = el }, h("input", { type: "hidden", class: "rating_hidden_input", name: this.name, value: "" }), [1, 2, 3, 4, 5].map(star => h("button", { class: `s-rating-stars-btn-star s-rating-stars-` + this.size, "data-star": star }, h("span", { innerHTML: Star2 })))), this.withLabel && this.reviewLabel ? h("span", { class: "s-rating-stars-label" }, this.reviewLabel) : '')))) : (h(Host, null));
}
componentDidLoad() {
var _a;
this.initiateRating();
this.highlightSelectedStars();
if (this.value && this.editable) {
const stars = (_a = this.starsElem) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.s-rating-stars-btn-star');
if (stars && this.value >= 0 && this.value <= stars.length) {
this.triggerRatingProgrammatically(this.value - 1);
}
}
}
static get is() { return "salla-rating-stars"; }
static get originalStyleUrls() {
return {
"$": ["salla-rating-stars.scss"]
};
}
static get styleUrls() {
return {
"$": ["salla-rating-stars.css"]
};
}
static get properties() {
return {
"name": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Sets input name."
},
"attribute": "name",
"reflect": false,
"defaultValue": "'rating'"
},
"size": {
"type": "string",
"mutable": false,
"complexType": {
"original": "\"large\" | \"medium\" | \"small\" | \"mini\"",
"resolved": "\"large\" | \"medium\" | \"mini\" | \"small\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Sets the height and width of the component. Defaults to medium."
},
"attribute": "size",
"reflect": false,
"defaultValue": "'medium'"
},
"value": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "The rating value."
},
"attribute": "value",
"reflect": false
},
"reviews": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Number of reviews to display."
},
"attribute": "reviews",
"reflect": false,
"defaultValue": "0"
},
"withLabel": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Show the description label."
},
"attribute": "with-label",
"reflect": false
},
"editable": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Allows the rating to be editable."
},
"attribute": "editable",
"reflect": false,
"defaultValue": "false"
}
};
}
static get states() {
return {
"translationsLoaded": {},
"labels": {},
"reviewLabel": {},
"selectedStar": {}
};
}
static get elementRef() { return "host"; }
}
//# sourceMappingURL=salla-rating-stars.js.map