I have an Angular project with a component like this:
<div class="stars-container mt-2">
<div *ngFor="let star of starsArray; let i = index" class="star">
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24">
<path fill="#ffffff"
d="m7.69 19.346l1.614-5.33L5.115 11h5.216L12 5.462L13.67 11h5.215l-4.189 3.015l1.614 5.331L12 16.07z" />
</svg>
</div>
</div>
Where startsArray is:
starsArray: boolean[] = new Array(5);
The SCSS is:
.stars-container {
display: flex;
justify-content: left;
align-items: center;
gap: .7rem;
cursor: pointer;
flex-direction: row-reverse;
.star {
transition: .3s ease;
svg {
width: 3rem;
height: auto;
path {
fill: $gris; // Color de las estrellas no seleccionadas
transition: fill .3s ease; // Transición suave del color
}
}
&:hover~.star svg path {
fill: $primario; // Color de las estrellas seleccionadas al hacer hover
}
&:hover svg path {
fill: $primario; // Color de la estrella seleccionada al hacer hover
}
}
}
.star:hover svg path,
.star:hover~.star svg path,
.star.highlighted svg path {
fill: $primario;
}
At the moment I have achieved that when I make hover on a star, the left stars also change the color. Nevertheless, I would like to make that when I press a star, all the stars on the left and the clicked star change color permanently (permanently in the browser session, no with Data Base).
I have tried several things but nothing works.
ngClass
and add a class selected
based on the selection made by the user!@Input
and @Output
to update the selected value of the user in the property called rating
5 - then latest value
since we are showing the stars reversed.Please find below working stackblitz and code
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
@Component({
selector: 'app-star-rating',
standalone: true,
template: `
<div class="stars-container mt-2">
<div *ngFor="let star of starsArray; let i = index" class="star" (click)="selectRating(i)" [ngClass]="{'selected': 5 - rating <= i}">
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24">
<path fill="#00000"
d="m7.69 19.346l1.614-5.33L5.115 11h5.216L12 5.462L13.67 11h5.215l-4.189 3.015l1.614 5.331L12 16.07z" />
</svg>
</div>
</div>
`,
styles: `
.stars-container {
display: flex;
justify-content: left;
align-items: center;
gap: .7rem;
cursor: pointer;
flex-direction: row-reverse;
.star {
transition: .3s ease;
svg {
width: 3rem;
height: auto;
path {
fill: gray; // Color de las estrellas no seleccionadas
transition: fill .3s ease; // Transición suave del color
}
}
&:hover ~ .star svg path {
fill: gold; // Color de las estrellas seleccionadas al hacer hover
}
&:hover svg path {
fill: gold; // Color de la estrella seleccionada al hacer hover
}
&.selected ~ .star svg path {
fill: gold; // Color de las estrellas seleccionadas al hacer hover
}
&selected svg path {
fill: gold; // Color de la estrella seleccionada al hacer hover
}
}
}
.star:hover svg path,
.star:hover~.star svg path,
.star.highlighted svg path {
fill: $primario;
}
`,
imports: [CommonModule],
})
export class StarRatingComponent implements OnInit {
@Input() rating: number = 0;
@Output() ratingChange: EventEmitter<number> = new EventEmitter<number>();
starsArray: boolean[] = new Array(5);
selectRating(i: number) {
this.ratingChange.emit(5 - i);
}
constructor() {}
ngOnInit() {}
}