UNPKG

ngx-stars

Version:
217 lines (209 loc) 15.1 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common')) : typeof define === 'function' && define.amd ? define('ngx-stars', ['exports', '@angular/core', '@angular/common'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['ngx-stars'] = {}, global.ng.core, global.ng.common)); }(this, (function (exports, core, common) { 'use strict'; var NgxStarsComponent = /** @class */ (function () { function NgxStarsComponent() { var _this = this; this.maxStars = 5; this.initialStars = 0; this.animationSpeed = 100; this.wholeStars = false; this.ratingOutput = new core.EventEmitter(); this.customClassIdentifier = Math.random().toString(36).substring(2); this.safeSize = function () { return (Number.isInteger(_this.size) && _this.size > 0 && _this.size < 6) ? _this.size : 1; }; } NgxStarsComponent.prototype.ngOnInit = function () { this.setupStarImages(); this.editableStars = Array.from(new Array(this.maxStars)).map(function (elem, index) { return new EditableStar(index); }); this.setRating(this.initialStars); if (this.animation) { this.animationInterval = setInterval(this.starAnimation.bind(this), this.animationSpeed); } }; NgxStarsComponent.prototype.ngOnDestroy = function () { // remove the three custom classes we created if custom image urls were provided if (this.customCssClasses) { this.customCssClasses.forEach(function (style) { if (style && style.parentNode) { style.parentNode.removeChild(style); } }); } }; NgxStarsComponent.prototype.setupStarImages = function () { var _this = this; if (this.customStarIcons) { this.customCssClasses = []; Object.keys(this.customStarIcons).map(function (key) { return key; }).forEach(function (starType) { var classname = _this.getStarClass(starType); _this.createCssClass(classname, starType); }); } }; NgxStarsComponent.prototype.createCssClass = function (classname, starType) { var clazz = document.createElement('style'); clazz.type = 'text/css'; clazz.innerHTML = "." + classname + " {\n -webkit-mask-image: url(" + this.customStarIcons[starType] + ");\n mask-image: url(" + this.customStarIcons[starType] + ");\n }"; document.getElementsByTagName('head')[0].appendChild(clazz); this.customCssClasses.push(clazz); }; NgxStarsComponent.prototype.starPadding = function () { return { 'margin-right': this.customPadding || "calc(" + this.starSize().width + " / 10)" }; }; NgxStarsComponent.prototype.starColorAndSize = function () { return Object.assign({}, this.starColor(), this.starSize()); }; NgxStarsComponent.prototype.starColor = function () { return { 'background-color': this.color || 'crimson' }; }; NgxStarsComponent.prototype.starSize = function () { return { height: this.customSize || 15 * this.safeSize() + "px", width: this.customSize || 16 * this.safeSize() + "px", }; }; NgxStarsComponent.prototype.starAnimation = function () { this.animationRunning = true; if (this.rating < this.maxStars) { this.setRating(this.rating += 0.5); } else { this.setRating(0); } }; NgxStarsComponent.prototype.cancelStarAnimation = function () { if (this.animationRunning) { clearInterval(this.animationInterval); this.rating = 0; this.animationRunning = false; } }; NgxStarsComponent.prototype.setRating = function (rating) { this.rating = Math.round(rating * 2) / 2; this.onStarsUnhover(); }; NgxStarsComponent.prototype.onStarHover = function (event, clickedStar) { var _this = this; this.cancelStarAnimation(); var clickedInFirstHalf = this.clickedInFirstHalf(event); // fill in either a half or whole star depending on where user clicked clickedStar.classname = (!this.wholeStars && clickedInFirstHalf) ? this.getStarClass('half') : this.getStarClass('full'); // fill in all stars in previous positions and clear all in later ones this.editableStars.forEach(function (star) { if (star.position > clickedStar.position) { star.classname = _this.getStarClass('empty'); } else if (star.position < clickedStar.position) { star.classname = _this.getStarClass('full'); } }); }; NgxStarsComponent.prototype.onStarClick = function (event, clickedStar) { this.cancelStarAnimation(); // lock in current rating var clickedInFirstHalf = this.clickedInFirstHalf(event); this.rating = clickedStar.position + ((!this.wholeStars && clickedInFirstHalf) ? 0.5 : 1); this.ratingOutput.emit(this.rating); }; // hidden star to left of first star lets user click there to set to 0 NgxStarsComponent.prototype.onZeroStarClick = function () { this.setRating(0); this.ratingOutput.emit(this.rating); }; NgxStarsComponent.prototype.onZeroStarHover = function () { var _this = this; // clear all stars this.editableStars.forEach(function (star) { return star.classname = _this.getStarClass('empty'); }); }; NgxStarsComponent.prototype.onStarsUnhover = function () { var _this = this; // when user stops hovering we want to make stars reflect the last rating applied by clicking this.editableStars.forEach(function (star) { var starNumber = star.position + 1; if (_this.rating >= starNumber) { star.classname = _this.getStarClass('full'); } else if (_this.rating > starNumber - 1 && _this.rating < starNumber) { star.classname = _this.getStarClass('half'); } else { star.classname = _this.getStarClass('empty'); } }); }; NgxStarsComponent.prototype.clickedInFirstHalf = function (event) { var starIcon = event.target; return event.pageX < starIcon.getBoundingClientRect().left + starIcon.offsetWidth / 2; }; NgxStarsComponent.prototype.noop = function () { }; NgxStarsComponent.prototype.getStarClass = function (starType) { if (this.customCssClasses) { return "ngx-stars-star-" + starType + "-" + this.customClassIdentifier; } return "star-" + starType; }; // this and the aria-labels and role in the html inspired by https://stackoverflow.com/q/55966205 NgxStarsComponent.prototype.getAriaLabel = function () { return "Rating: " + this.rating + " out of " + this.maxStars + " stars " + (this.readonly ? '' : '. Can be edited.'); }; return NgxStarsComponent; }()); NgxStarsComponent.decorators = [ { type: core.Component, args: [{ selector: 'ngx-stars', template: "<div class=\"stars-line\" (mouseleave)=\"readonly ? noop() : onStarsUnhover()\" role=\"img\" [attr.aria-label]=\"getAriaLabel()\">\n <span class=\"star zero-star\" [ngStyle]=\"starSize()\" aria-hidden=\"true\" (click)=\"onZeroStarClick()\" (mousemove)=\"readonly ? noop() : onZeroStarHover()\"></span>\n <div *ngFor=\"let star of editableStars;\" [ngStyle]=\"starPadding()\" aria-hidden=\"true\" (click)=\"readonly ? noop() : onStarClick($event, star)\" (mousemove)=\"readonly ? noop() : onStarHover($event, star)\">\n <span class=\"star\" [ngClass]=\"star.classname\" [ngStyle]=\"starColorAndSize()\" aria-hidden=\"true\"></span>\n </div>\n</div>\n", styles: [".stars-line{display:flex;align-items:center;position:relative}.stars-line>div{z-index:999}.zero-star{color:transparent;position:absolute;left:-16px}.star{display:inline-block;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.star-empty{-webkit-mask-image:url(\"data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='far' data-icon='star' class='svg-inline--fa fa-star fa-w-18' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E%3Cpath fill='currentColor' d='M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z'%3E%3C/path%3E%3C/svg%3E%0A\");mask-image:url(\"data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='far' data-icon='star' class='svg-inline--fa fa-star fa-w-18' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E%3Cpath fill='currentColor' d='M528.1 171.5L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6zM388.6 312.3l23.7 138.4L288 385.4l-124.3 65.3 23.7-138.4-100.6-98 139-20.2 62.2-126 62.2 126 139 20.2-100.6 98z'%3E%3C/path%3E%3C/svg%3E%0A\")}.star-half{-webkit-mask-image:url(\"data:image/svg+xml,%3C!-- had to hack this one's viewbox otherwise it didn't line up with the other two --%3E%3C!-- changed viewbox from '0 0 536 512' to '-20 0 576 512' --%3E%3Csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='star-half-alt' class='svg-inline--fa fa-star-half-alt fa-w-17' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='-20 0 576 512'%3E%3Cpath fill='currentColor' d='M508.55 171.51L362.18 150.2 296.77 17.81C290.89 5.98 279.42 0 267.95 0c-11.4 0-22.79 5.9-28.69 17.81l-65.43 132.38-146.38 21.29c-26.25 3.8-36.77 36.09-17.74 54.59l105.89 103-25.06 145.48C86.98 495.33 103.57 512 122.15 512c4.93 0 10-1.17 14.87-3.75l130.95-68.68 130.94 68.7c4.86 2.55 9.92 3.71 14.83 3.71 18.6 0 35.22-16.61 31.66-37.4l-25.03-145.49 105.91-102.98c19.04-18.5 8.52-50.8-17.73-54.6zm-121.74 123.2l-18.12 17.62 4.28 24.88 19.52 113.45-102.13-53.59-22.38-11.74.03-317.19 51.03 103.29 11.18 22.63 25.01 3.64 114.23 16.63-82.65 80.38z'%3E%3C/path%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml,%3C!-- had to hack this one's viewbox otherwise it didn't line up with the other two --%3E%3C!-- changed viewbox from '0 0 536 512' to '-20 0 576 512' --%3E%3Csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='star-half-alt' class='svg-inline--fa fa-star-half-alt fa-w-17' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='-20 0 576 512'%3E%3Cpath fill='currentColor' d='M508.55 171.51L362.18 150.2 296.77 17.81C290.89 5.98 279.42 0 267.95 0c-11.4 0-22.79 5.9-28.69 17.81l-65.43 132.38-146.38 21.29c-26.25 3.8-36.77 36.09-17.74 54.59l105.89 103-25.06 145.48C86.98 495.33 103.57 512 122.15 512c4.93 0 10-1.17 14.87-3.75l130.95-68.68 130.94 68.7c4.86 2.55 9.92 3.71 14.83 3.71 18.6 0 35.22-16.61 31.66-37.4l-25.03-145.49 105.91-102.98c19.04-18.5 8.52-50.8-17.73-54.6zm-121.74 123.2l-18.12 17.62 4.28 24.88 19.52 113.45-102.13-53.59-22.38-11.74.03-317.19 51.03 103.29 11.18 22.63 25.01 3.64 114.23 16.63-82.65 80.38z'%3E%3C/path%3E%3C/svg%3E\")}.star-full{-webkit-mask-image:url(\"data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='star' class='svg-inline--fa fa-star fa-w-18' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E%3Cpath fill='currentColor' d='M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z'%3E%3C/path%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml,%3Csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='star' class='svg-inline--fa fa-star fa-w-18' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E%3Cpath fill='currentColor' d='M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z'%3E%3C/path%3E%3C/svg%3E\")}"] },] } ]; NgxStarsComponent.propDecorators = { maxStars: [{ type: core.Input }], initialStars: [{ type: core.Input }], readonly: [{ type: core.Input }], size: [{ type: core.Input }], customSize: [{ type: core.Input }], color: [{ type: core.Input }], animation: [{ type: core.Input }], animationSpeed: [{ type: core.Input }], customPadding: [{ type: core.Input }], wholeStars: [{ type: core.Input }], customStarIcons: [{ type: core.Input }], ratingOutput: [{ type: core.Output }] }; var EditableStar = /** @class */ (function () { function EditableStar(position) { this.position = position; } return EditableStar; }()); var NgxStarsModule = /** @class */ (function () { function NgxStarsModule() { } return NgxStarsModule; }()); NgxStarsModule.decorators = [ { type: core.NgModule, args: [{ imports: [ common.CommonModule ], declarations: [ NgxStarsComponent ], exports: [ NgxStarsComponent ] },] } ]; /* * Public API Surface of ngx-stars */ /** * Generated bundle index. Do not edit. */ exports.EditableStar = EditableStar; exports.NgxStarsComponent = NgxStarsComponent; exports.NgxStarsModule = NgxStarsModule; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=ngx-stars.umd.js.map