This looks very good and works nicely. The javascript is fairly concise too and readable, which is good.
There is one main thing that you could try which might simplify this a bit.
You can turn this into a form, rather than using buttons with event listeners. This has a few benefits. First it is more semantic so users of assistive technology will get better hints for how to interact with your component. Second, it will allow you to delete a large part of the javascript around styling, as you can use built in HTML and CSS instead.
The html would look something like
<form>
<fieldset>
<legend>Rating</legend>
<label>
<input type="radio" name="rating" value="1">
1
</label>
<label>
<input type="radio" name="rating" value="1">
2
</label>
</fieldset>
<button type="submit">Submit</button>
<form>
Then in your CSS you can access focus, hover and checked states, removing the need to add or remove classes with javascript
input[type="radio"] {
// all the styling for your standard radio buttons
}
input[type="radio"]:hover,
input[type="radio"]:focus-visible {
// the color change for when it's hovered/focused
}
input[type="radio"]:checked {
// the color change for the selected item
}
In your javascript you can then get the selected value when you submit the form
const formElement = document.querySelector('form')
formElement.addEventListener('submit', (event) => {
event.preventDefault() // stops the browser doing a full refresh
const formData = new FormData(form) // extract the data from the form
const rating = formData.get('rating') // get the value of the 'rating' field
// now you can do whatever you want with your rating value
})
Marked as helpful