Star Rating
Develop a star rating component where users can set a rating by clicking on stars.
Solution
Select Rating
Explanation
The HTML Structure
An unordered list
that displays 5 button elements. The text content of each button is either a filled in star or an empty one.
The rating state
The current rating of the star is set to 3 using useState
.
Displaying the correct number of filled stars
The number of stars is created by using an array with values 1 to 5. The array is mapped over and the button attributes are determined using this index value.
If the rating stored in rating
state, is higher than or equal to the current index value, the button text is set to a full star.
The button attributes
The aria-label
ensures screen readers understand what the star on the button means.
The key
is required on list items rendered by React.
The style
attribute has a function, getStarRating
to determine if it should be an empty or filled star.
The onClick
function uses an arrow function to be able to send the index of the star to setRating
.
The button content and style
The content is determined by a ternary operator
that checks if the star isSelected
.
A full star if it is, and empty if not.
The transform is a scale
of 1.2
if selected so that it is clear which value is selected for user experience.
Code
import { useState } from "react";
import styles from "./Solution.module.css";
const Solution = () => {
const [rating, setRating] = useState(3);
const getStarStyle = (isSelected: boolean) => ({
transform: isSelected ? "scale(1.2)" : "scale(1)",
});
return (
<div>
<h3>Select Rating</h3>
<ul className={styles.list}>
{[1, 2, 3, 4, 5].map((index) => {
const isSelected = rating >= index;
return (
<button
aria-label={`Rating ${index} out of 5`}
key={index}
className={styles.star}
style={getStarStyle(isSelected)}
onClick={() => setRating(index)}
>
{isSelected ? "★" : "☆"}
</button>
);
})}
</ul>
</div>
);
};
export default Solution;
Styling
.list {
display: flex;
gap: 5px;
margin-top: 10px;
}
.star {
cursor: pointer;
padding: 5px;
font-size: 24px;
border: none;
background-color: transparent;
}