1 | import { ɵɵdefineInjectable, Injectable, forwardRef, EventEmitter, Component, ChangeDetectionStrategy, ChangeDetectorRef, Input, Output, HostListener, NgModule } from '@angular/core';
|
2 | import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
3 | import { CommonModule } from '@angular/common';
|
4 |
|
5 |
|
6 | class RatingConfig {
|
7 | constructor() {
|
8 |
|
9 | this.ariaLabel = 'rating';
|
10 | }
|
11 | }
|
12 | RatingConfig.ɵprov = ɵɵdefineInjectable({ factory: function RatingConfig_Factory() { return new RatingConfig(); }, token: RatingConfig, providedIn: "root" });
|
13 | RatingConfig.decorators = [
|
14 | { type: Injectable, args: [{
|
15 | providedIn: 'root'
|
16 | },] }
|
17 | ];
|
18 |
|
19 | const RATING_CONTROL_VALUE_ACCESSOR = {
|
20 | provide: NG_VALUE_ACCESSOR,
|
21 | useExisting: forwardRef(() => RatingComponent),
|
22 | multi: true
|
23 | };
|
24 | class RatingComponent {
|
25 | constructor(changeDetection, config) {
|
26 | this.changeDetection = changeDetection;
|
27 |
|
28 | this.max = 5;
|
29 |
|
30 | this.readonly = false;
|
31 |
|
32 | this.titles = [];
|
33 |
|
34 | this.onHover = new EventEmitter();
|
35 |
|
36 | this.onLeave = new EventEmitter();
|
37 | this.onChange = Function.prototype;
|
38 | this.onTouched = Function.prototype;
|
39 |
|
40 | this.ariaLabel = 'rating';
|
41 | this.range = [];
|
42 | this.value = 0;
|
43 | Object.assign(this, config);
|
44 | }
|
45 | onKeydown(event) {
|
46 | if ([37, 38, 39, 40].indexOf(event.which) === -1) {
|
47 | return;
|
48 | }
|
49 | event.preventDefault();
|
50 | event.stopPropagation();
|
51 | const sign = event.which === 38 || event.which === 39 ? 1 : -1;
|
52 | this.rate(this.value + sign);
|
53 | }
|
54 | ngOnInit() {
|
55 | this.max = this.max || 5;
|
56 | this.titles =
|
57 | typeof this.titles !== 'undefined' && this.titles.length > 0
|
58 | ? this.titles
|
59 | : [];
|
60 | this.range = this.buildTemplateObjects(this.max);
|
61 | }
|
62 |
|
63 | writeValue(value) {
|
64 | if (value % 1 !== value) {
|
65 | this.value = Math.round(value);
|
66 | this.preValue = value;
|
67 | this.changeDetection.markForCheck();
|
68 | return;
|
69 | }
|
70 | this.preValue = value;
|
71 | this.value = value;
|
72 | this.changeDetection.markForCheck();
|
73 | }
|
74 | enter(value) {
|
75 | if (!this.readonly) {
|
76 | this.value = value;
|
77 | this.changeDetection.markForCheck();
|
78 | this.onHover.emit(value);
|
79 | }
|
80 | }
|
81 | reset() {
|
82 | if (typeof this.preValue === 'number') {
|
83 | this.value = Math.round(this.preValue);
|
84 | this.changeDetection.markForCheck();
|
85 | this.onLeave.emit(this.value);
|
86 | }
|
87 | }
|
88 | registerOnChange(fn) {
|
89 | this.onChange = fn;
|
90 | }
|
91 | registerOnTouched(fn) {
|
92 | this.onTouched = fn;
|
93 | }
|
94 | rate(value) {
|
95 | if (!this.readonly && this.range
|
96 | && value >= 0 && value <= this.range.length) {
|
97 | this.writeValue(value);
|
98 | this.onChange(value);
|
99 | }
|
100 | }
|
101 | buildTemplateObjects(max) {
|
102 | const result = [];
|
103 | for (let i = 0; i < max; i++) {
|
104 | result.push({
|
105 | index: i,
|
106 | title: this.titles[i] || i + 1
|
107 | });
|
108 | }
|
109 | return result;
|
110 | }
|
111 | }
|
112 | RatingComponent.decorators = [
|
113 | { type: Component, args: [{
|
114 | selector: 'rating',
|
115 | template: "<span (mouseleave)=\"reset()\" (keydown)=\"onKeydown($event)\" tabindex=\"0\"\n role=\"slider\" aria-valuemin=\"0\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-valuemax]=\"range.length\"\n [attr.aria-valuenow]=\"value\">\n <ng-template #star let-value=\"value\" let-index=\"index\">{{ index < value ? '★' : '☆' }}</ng-template>\n <ng-template ngFor let-r [ngForOf]=\"range\" let-index=\"index\">\n <span class=\"sr-only visually-hidden\">({{ index < value ? '*' : ' ' }})</span>\n <span class=\"bs-rating-star\"\n (mouseenter)=\"enter(index + 1)\"\n (click)=\"rate(index + 1)\"\n [title]=\"r.title\"\n [style.cursor]=\"readonly ? 'default' : 'pointer'\"\n [class.active]=\"index < value\">\n <ng-template [ngTemplateOutlet]=\"customTemplate || star\"\n [ngTemplateOutletContext]=\"{index: index, value: value}\">\n </ng-template>\n </span>\n </ng-template>\n</span>\n",
|
116 | providers: [RATING_CONTROL_VALUE_ACCESSOR],
|
117 | changeDetection: ChangeDetectionStrategy.OnPush
|
118 | },] }
|
119 | ];
|
120 | RatingComponent.ctorParameters = () => [
|
121 | { type: ChangeDetectorRef },
|
122 | { type: RatingConfig }
|
123 | ];
|
124 | RatingComponent.propDecorators = {
|
125 | max: [{ type: Input }],
|
126 | readonly: [{ type: Input }],
|
127 | titles: [{ type: Input }],
|
128 | customTemplate: [{ type: Input }],
|
129 | onHover: [{ type: Output }],
|
130 | onLeave: [{ type: Output }],
|
131 | onKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }]
|
132 | };
|
133 |
|
134 | class RatingModule {
|
135 | static forRoot() {
|
136 | return {
|
137 | ngModule: RatingModule,
|
138 | providers: []
|
139 | };
|
140 | }
|
141 | }
|
142 | RatingModule.decorators = [
|
143 | { type: NgModule, args: [{
|
144 | imports: [CommonModule],
|
145 | declarations: [RatingComponent],
|
146 | exports: [RatingComponent]
|
147 | },] }
|
148 | ];
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 | export { RatingComponent, RatingConfig, RatingModule, RATING_CONTROL_VALUE_ACCESSOR as ɵa };
|
155 |
|