UNPKG

rm-ng-star-rating

Version:

rm-ng-star-rating is a lightweight, highly customizable Angular standalone star rating component designed for modern Angular applications. It enables developers to easily capture and display user ratings (with half and full star) using an intuitive star-b

1 lines 11.9 kB
{"version":3,"file":"rm-ng-star-rating.mjs","sources":["../../projects/rm-ng-star-rating/src/lib/rm-ng-star-rating.component.ts","../../projects/rm-ng-star-rating/src/lib/rm-ng-star-rating.component.html","../../projects/rm-ng-star-rating/src/public-api.ts","../../projects/rm-ng-star-rating/src/rm-ng-star-rating.ts"],"sourcesContent":["import {\r\n Component,\r\n ElementRef,\r\n EventEmitter,\r\n HostBinding,\r\n Input,\r\n OnInit,\r\n Output,\r\n ViewChild,\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'rm-ng-star-rating',\r\n imports: [CommonModule],\r\n templateUrl: './rm-ng-star-rating.component.html',\r\n styleUrls: ['./rm-ng-star-rating.component.css']\r\n})\r\nexport class RmNgStarRatingComponent implements OnInit {\r\n // @Output() ratingUpdated: EventEmitter<number> = new EventEmitter();\r\n // @Input() @HostBinding('style.--star-color') color: string = 'gold';\r\n // @Input() @HostBinding('style.--star-empty-color') emptyColor: string =\r\n // 'lightgray';\r\n // @Input() @HostBinding('style.--star-size') size: string = '40px';\r\n // @Input() rating: number = 0;\r\n // @Input() starCount: number = 5;\r\n // @Input() readOnly: boolean = false;\r\n // // it is for showing pointing ratiing\r\n // // @Input() decimalRatting: boolean = false;\r\n // // @ViewChild('tooltip', {static: false}) tooltip!: ElementRef;\r\n\r\n // hovered: number = 0;\r\n // hoveredRating: number = 0;\r\n // starsArray: any[] = [];\r\n\r\n // ngOnInit(): void {\r\n // this.starsArray = Array.from({ length: this.starCount });\r\n // }\r\n\r\n // onMouseEnter(index: number, event: MouseEvent): void {\r\n // if (!this.readOnly) {\r\n // this.hovered = index;\r\n // this.hoveredRating = index;\r\n // // it is for showing pointing ratiing\r\n // // this.hoveredRating = this.calculateRating(index, event);\r\n // // const tooltipElement = this.tooltip.nativeElement as HTMLElement;\r\n // // tooltipElement.style.display = 'block';\r\n // // this.positionTooltip(event);\r\n // }\r\n // }\r\n\r\n // onMouseLeave(): void {\r\n // if (!this.readOnly) {\r\n // this.hovered = 0;\r\n // this.hoveredRating = 0;\r\n // // const tooltipElement = this.tooltip.nativeElement as HTMLElement;\r\n // // tooltipElement.style.display = 'none';\r\n // }\r\n // }\r\n\r\n // onClick(index: number): void {\r\n // if (!this.readOnly) {\r\n // this.rating = index;\r\n // // it is for showing pointing ratiing\r\n // // this.rating = this.calculateRating(index);\r\n // this.ratingUpdated.emit(this.rating);\r\n // }\r\n // }\r\n\r\n // getStarClass(index: number): string {\r\n // return this.hovered >= index || this.rating >= index\r\n // ? 'star-filled'\r\n // : 'star-empty';\r\n // }\r\n\r\n // it is for showing pointing ratiing\r\n // getStarClass(index: number): string {\r\n // if (this.hovered >= index || this.rating >= index) {\r\n // const fullStars = Math.floor(this.rating);\r\n // const fractionalPart = this.rating - fullStars;\r\n // if (index === fullStars + 1 && fractionalPart > 0) {\r\n // return 'star-half-filled';\r\n // }\r\n // return 'star-filled';\r\n // }\r\n // return 'star-empty';\r\n // }\r\n\r\n // calculateRating(index: number, event?: MouseEvent): number {\r\n // if (event) {\r\n // const starWidth = (event.target as HTMLElement).offsetWidth;\r\n // const offsetX =\r\n // event.clientX -\r\n // (event.target as HTMLElement).getBoundingClientRect().left;\r\n // const fraction = Math.min(1, Math.max(0, offsetX / starWidth));\r\n // return index - 1 + fraction;\r\n // }\r\n // return index;\r\n // }\r\n\r\n // positionTooltip(event: MouseEvent): void {\r\n // const tooltipElement = this.tooltip.nativeElement as HTMLElement;\r\n // const xOffset = -10; // Distance from the star to the tooltip\r\n // const yOffset = -30; // Position above the star\r\n //\r\n // tooltipElement.style.left = `${event.clientX + xOffset}px`;\r\n // tooltipElement.style.top = `${event.clientY + yOffset}px`;\r\n // }\r\n\r\n @Output() ratingUpdated: EventEmitter<number> = new EventEmitter();\r\n @Input() @HostBinding('style.--star-color') color: string = 'gold';\r\n @Input() @HostBinding('style.--star-empty-color') emptyColor: string = 'lightgray';\r\n @Input() @HostBinding('style.--star-size') size: string = '40px';\r\n @Input() rating: number = 0;\r\n @Input() starCount: number = 5;\r\n @Input() readOnly: boolean = false;\r\n @Input() allowHalf: boolean = true; // NEW: enable half-star support\r\n\r\n hovered: number = 0;\r\n hoveredRating: number = 0;\r\n starsArray: any[] = [];\r\n\r\n ngOnInit(): void {\r\n this.starsArray = Array.from({ length: this.starCount });\r\n }\r\n\r\n onMouseEnter(index: number, event: MouseEvent): void {\r\n if (!this.readOnly) {\r\n if (this.allowHalf) {\r\n this.hoveredRating = this.calculateRating(index, event);\r\n } else {\r\n this.hoveredRating = index;\r\n }\r\n this.hovered = index;\r\n }\r\n }\r\n\r\n onMouseLeave(): void {\r\n if (!this.readOnly) {\r\n this.hovered = 0;\r\n this.hoveredRating = 0;\r\n }\r\n }\r\n\r\n onClick(index: number, event?: MouseEvent): void {\r\n if (!this.readOnly) {\r\n if (this.allowHalf && event) {\r\n this.rating = this.calculateRating(index, event);\r\n } else {\r\n this.rating = index;\r\n }\r\n this.ratingUpdated.emit(this.rating);\r\n }\r\n }\r\n\r\n getStarClass(index: number): string {\r\n const value = this.hoveredRating || this.rating;\r\n if (value >= index) {\r\n return 'star-filled';\r\n } else if (this.allowHalf && value + 0.5 >= index) {\r\n // If value is within half, show half-filled\r\n return 'star-half-filled';\r\n } else {\r\n return 'star-empty';\r\n }\r\n }\r\n\r\n calculateRating(index: number, event?: MouseEvent): number {\r\n if (event) {\r\n const starElement = event.target as HTMLElement;\r\n const { left, width } = starElement.getBoundingClientRect();\r\n const x = event.clientX - left;\r\n if (x < width / 2) {\r\n return index - 0.5;\r\n } else {\r\n return index;\r\n }\r\n }\r\n return index;\r\n }\r\n \r\n}\r\n","<!--<div class=\"star-rating\" [ngStyle]=\"{'font-size.px': size}\">-->\n<!-- <span *ngFor=\"let star of [].constructor(starCount); let i = index\"-->\n<!-- class=\"star\"-->\n<!-- [ngClass]=\"getStarClass(i + 1)\"-->\n<!-- (mouseenter)=\"onMouseEnter(i + 1)\"-->\n<!-- (mouseleave)=\"onMouseLeave()\"-->\n<!-- (click)=\"onClick(i + 1)\">-->\n<!-- ★-->\n<!-- </span>-->\n<!--</div>-->\n\n<!--<div class=\"star-rating-container\">-->\n<!-- <div class=\"star-rating\" [ngStyle]=\"{'font-size.px': size}\">-->\n<!-- <span *ngFor=\"let star of starsArray; let i = index\"-->\n<!-- class=\"star-wrapper\"-->\n<!-- (mouseenter)=\"onMouseEnter(i + 1, $event)\"-->\n<!-- (mouseleave)=\"onMouseLeave()\">-->\n<!-- <span class=\"star\"-->\n<!-- [ngClass]=\"getStarClass(i + 1)\"-->\n<!-- (click)=\"onClick(i + 1)\">-->\n<!-- ★-->\n<!-- </span>-->\n<!-- &lt;!&ndash; Tooltip displayed above the star &ndash;&gt;-->\n<!-- <div class=\"tooltip\" #tooltip>-->\n<!-- {{ hoveredRating }}-->\n<!-- </div>-->\n<!-- </span>-->\n<!-- </div>-->\n<!--</div>-->\n\n<div class=\"star-rating-container\">\n <!-- <div class=\"star-rating\" [ngStyle]=\"{ 'font-size.px': size }\">\n <span\n *ngFor=\"let star of starsArray; let i = index\"\n class=\"star-wrapper\"\n (mouseenter)=\"onMouseEnter(i + 1, $event)\"\n (mouseleave)=\"onMouseLeave()\"\n >\n <span\n class=\"star\"\n [ngClass]=\"getStarClass(i + 1)\"\n (click)=\"onClick(i + 1)\"\n >\n\n </span>\n </span>\n</div> -->\n<!-- Tooltip element -->\n<!-- <div class=\"tooltip\" #tooltip>-->\n<!-- {{ hoveredRating }}-->\n<!-- </div>-->\n\n\n<div class=\"star-rating\" [ngStyle]=\"{ 'font-size.px': size }\">\n @for (star of starsArray; track star; let i = $index) {\n <span\n class=\"star-wrapper\"\n (mouseenter)=\"onMouseEnter(i + 1, $event)\"\n (mousemove)=\"allowHalf ? onMouseEnter(i + 1, $event) : null\"\n (mouseleave)=\"onMouseLeave()\"\n >\n <span\n class=\"star\"\n [ngClass]=\"getStarClass(i + 1)\"\n (click)=\"onClick(i + 1, $event)\"\n >\n\n </span>\n </span>\n }\n</div>\n\n</div>\n","/*\r\n * Public API Surface of rm-ng-star-rating\r\n */\r\n\r\nexport * from './lib/rm-ng-star-rating.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}