Design comparison
Solution retrospective
I'm most proud of how I dynamically created the rating buttons.
What challenges did you encounter, and how did you overcome them?{[...Array(5).keys()].map((_, index) => { const value = index + 1; const isSelected = rating === value; return ( handleRating(value)} > {value}
I had challenges with the semi-transparent rating circles. My solution was to use absolute positioning which I wasn't too familiar with. I also used this approach for the top star image.
Another challenge was changing the rating circle's background to white after a selection. I added a new react state to assist with this. I'm not sure if it was entirely necessary. There's probably a more efficient solution.
What specific areas of your project would you like help with?Am I using React state correctly in this example?
function App() {
const [rating, setRating] = useState(null);
const [submitted, setSubmitted] = useState(false);
const handleSubmit = (e) => {
e.preventDefault();
if (rating !== null) {
setSubmitted(true);
}
};
function Rating({ setRating, handleSubmit, rating }) {
const handleRating = (value) => {
setRating(value);
};
Community feedback
- @haquanqPosted 3 months ago
Hello @justinsane 👋
This is my feedback on HTML markups:
- Page must have one
main
landmark (read more here)) which means wrap the mot important content of the page inside it. - Consider using more semantic elements such as
section, article, figure,..
to wrap a part of content. For example, instead of wrapping your card withdiv
you can consider it as an article or section. - Avoid unnecessary
div
wrapping, keep your HTML simple. Becausediv
has no semantic meaning (choose div when there is no other elements that fit the use case), you should leave the content as it is if the layout does not need special style control (like flexbox)
When ever you want to send data a way you should use
form
element with properinput
type to represent what type of data users need to provide. In this use case, you can see there is 5 points (scores) from 1 to 5 that users can only choose one, you should useinput type="radio"
for each score button. Further more, you should wrap all radio buttons insidefieldset
(read more here) withlegend
to describe a group of inputs.About your react code, i could say these above information will change the way you handled submit event for now.
Have a nice day and happy coding! 😁😁😁
Marked as helpful1@justinsanePosted 3 months ago@haquanq Thanks for the great feedback.
-
incorporate semantic html
-
avoid unnecessary
div
wrapping- still working on this one. I feel this is a byproduct of React?
-
Used the correct
form
withtype="radio"
See my
Rating
component below:function Rating({ setRating, handleSubmit, rating }) { const handleRatingChange = (e) => { setRating(Number(e.target.value)); }; return ( <section> <div className="relative mb-9 flex h-11 w-11 items-center justify-center"> <span className="absolute left-0 top-0 h-11 w-11 rounded-full bg-light-gray/10"></span> <img src="./icon-star.svg" alt="star image" className="relative z-10" /> </div> <h1 className="mb-3 text-3xl font-medium">How did we do?</h1> <p className="mb-6 text-light-gray"> Please let us know how we did with your support request. All feedback is appreciated to help us improve our offering! </p> <form onSubmit={handleSubmit}> <div className="flex justify-between"> {[...Array(5).keys()].map((_, index) => { const value = index + 1; return ( <label key={index}> <input type="radio" name="rating" value={value} className="hidden" onChange={handleRatingChange} /> <div className={`group relative mb-4 flex h-14 w-14 cursor-pointer items-center justify-center rounded-full ${ rating === value ? "bg-white" : "bg-light-gray/10" } hover:bg-orange`} > <p className={`relative z-10 font-bold ${ rating === value ? "text-very-dark-blue" : "group-hover:text-very-dark-blue" }`} > {value} </p> </div> </label> ); })} </div> <button type="submit" className="mb-3 mt-2 w-full rounded-3xl bg-orange p-3 text-center font-bold uppercase tracking-widest text-very-dark-blue hover:bg-white sm-375:mt-0" > Submit </button> </form> </section> ); }
0@haquanqPosted 3 months ago@justinsane example about not using
div
:- Replace the
div
wrapper of inputs withfieldset
along withlegend
as such:
<fieldset> <legend class"visibility-hidden">Please rate us... (tell users concisely what to do with these inputs)</legend> ... inputs render... </fieldset>
- The
legend
will stay hidden (this help screen readers on providing more context for how are users supposed to do when they focus on the input for the first time)
0 - Page must have one
Please log in to post a comment
Log in with GitHubJoin our Discord community
Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!
Join our Discord