feat(star-rating): implement dynamic star rating display

This commit is contained in:
Jan Gleytenhoover 2024-09-24 08:34:01 +02:00
parent e8683dad06
commit bd5b42f4d2
Signed by: jank
GPG Key ID: B267751B8AE29EFE
2 changed files with 19 additions and 113 deletions

@ -1,7 +1,7 @@
<div class="flex items-center">
<div class="flex flex-inline">
<div *ngFor="let star of getRatingArray()" class="flex flex-inline">
<svg
[ngClass]="{ 'hidden': !(rating > 0 && rating < 1) }"
[ngClass]="{ hidden: !(star == 0.5) }"
class="w-4 h-4 text-yellow-300 me-1"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
@ -13,111 +13,7 @@
/>
</svg>
<svg
[ngClass]="{ 'hidden': !(rating >= 1) }"
class="w-4 h-4 text-yellow-300 me-1"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 22 20"
>
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"
/>
</svg>
</div>
<div class="flex flex-inline">
<svg
[ngClass]="{ 'hidden': !(rating > 1 && rating < 2) }"
class="w-4 h-4 text-yellow-300 me-1"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 22 20"
>
<path
d="M13 4.024v-.005c0-.053.002-.353-.217-.632a1.01 1.01 0 0 0-1.176-.315c-.192.076-.315.193-.35.225c-.052.05-.094.1-.122.134a4 4 0 0 0-.31.457c-.207.343-.484.84-.773 1.375a169 169 0 0 0-1.606 3.074h-.002l-4.599.367c-1.775.14-2.495 2.339-1.143 3.488L6.17 15.14l-1.06 4.406c-.412 1.72 1.472 3.078 2.992 2.157l3.94-2.388c.592-.359.958-.996.958-1.692v-13.6Zm-2.002 0v.025z"
/>
</svg>
<svg
[ngClass]="{ 'hidden': !(rating >= 2) }"
class="w-4 h-4 text-yellow-300 me-1"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 22 20"
>
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"
/>
</svg>
</div>
<div class="flex flex-inline">
<svg
[ngClass]="{ 'hidden': !(rating > 2 && rating < 3) }"
class="w-4 h-4 text-yellow-300 me-1"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 22 20"
>
<path
d="M13 4.024v-.005c0-.053.002-.353-.217-.632a1.01 1.01 0 0 0-1.176-.315c-.192.076-.315.193-.35.225c-.052.05-.094.1-.122.134a4 4 0 0 0-.31.457c-.207.343-.484.84-.773 1.375a169 169 0 0 0-1.606 3.074h-.002l-4.599.367c-1.775.14-2.495 2.339-1.143 3.488L6.17 15.14l-1.06 4.406c-.412 1.72 1.472 3.078 2.992 2.157l3.94-2.388c.592-.359.958-.996.958-1.692v-13.6Zm-2.002 0v.025z"
/>
</svg>
<svg
[ngClass]="{ 'hidden': !(rating >= 3) }"
class="w-4 h-4 text-yellow-300 me-1"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 22 20"
>
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"
/>
</svg>
</div>
<div class="flex flex-inline">
<svg
[ngClass]="{ 'hidden': !(rating > 3 && rating < 4) }"
class="w-4 h-4 text-yellow-300 me-1"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 22 20"
>
<path
d="M13 4.024v-.005c0-.053.002-.353-.217-.632a1.01 1.01 0 0 0-1.176-.315c-.192.076-.315.193-.35.225c-.052.05-.094.1-.122.134a4 4 0 0 0-.31.457c-.207.343-.484.84-.773 1.375a169 169 0 0 0-1.606 3.074h-.002l-4.599.367c-1.775.14-2.495 2.339-1.143 3.488L6.17 15.14l-1.06 4.406c-.412 1.72 1.472 3.078 2.992 2.157l3.94-2.388c.592-.359.958-.996.958-1.692v-13.6Zm-2.002 0v.025z"
/>
</svg>
<svg
[ngClass]="{ 'hidden': !(rating >= 4) }"
class="w-4 h-4 text-yellow-300 me-1"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 22 20"
>
<path
d="M20.924 7.625a1.523 1.523 0 0 0-1.238-1.044l-5.051-.734-2.259-4.577a1.534 1.534 0 0 0-2.752 0L7.365 5.847l-5.051.734A1.535 1.535 0 0 0 1.463 9.2l3.656 3.563-.863 5.031a1.532 1.532 0 0 0 2.226 1.616L11 17.033l4.518 2.375a1.534 1.534 0 0 0 2.226-1.617l-.863-5.03L20.537 9.2a1.523 1.523 0 0 0 .387-1.575Z"
/>
</svg>
</div>
<div class="flex flex-inline">
<svg
[ngClass]="{ 'hidden': !(rating > 4 && rating < 5) }"
class="w-4 h-4 text-yellow-300 me-1"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 22 20"
>
<path
d="M13 4.024v-.005c0-.053.002-.353-.217-.632a1.01 1.01 0 0 0-1.176-.315c-.192.076-.315.193-.35.225c-.052.05-.094.1-.122.134a4 4 0 0 0-.31.457c-.207.343-.484.84-.773 1.375a169 169 0 0 0-1.606 3.074h-.002l-4.599.367c-1.775.14-2.495 2.339-1.143 3.488L6.17 15.14l-1.06 4.406c-.412 1.72 1.472 3.078 2.992 2.157l3.94-2.388c.592-.359.958-.996.958-1.692v-13.6Zm-2.002 0v.025z"
/>
</svg>
<svg
[ngClass]="{ 'hidden': !(rating >= 5) }"
[ngClass]="{ hidden: !(star == 1) }"
class="w-4 h-4 text-yellow-300 me-1"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"

@ -1,19 +1,29 @@
import { NgClass } from '@angular/common';
import { NgClass, NgFor } from '@angular/common';
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-star-rating',
standalone: true,
imports: [NgClass],
imports: [NgClass, NgFor],
templateUrl: './star-rating.component.html',
styleUrl: './star-rating.component.css'
})
export class StarRatingComponent {
@Input() public rating: number = 0;
public stars: number[] = [];
public setRating(rating: number) {
this.rating = rating;
this.stars = Array(rating).fill(0);
public getRatingArray(): number[] {
let stars = [];
for (let i = 0; i < 5; i++) {
if (i < this.rating) {
if (i + 0.5 == this.rating) {
stars.push(0.5);
} else {
stars.push(1);
}
} else {
stars.push(0);
}
}
return stars;
}
}