Skip to the solution
MediumMachine Coding11 min read

Build a Star Rating component

639 views

The problem

Question presented to candidate: "On our product page we show the average rating as stars, and signed-in users can leave their own rating. Build a reusable star rating component that works for both: a read-only display that can show 3.6 stars, and an interactive version with hover preview that also works with the keyboard."

Requirements:

  • Five stars by default (max is configurable).
  • Interactive mode: hovering previews a rating without committing it; clicking commits; clicking the current rating again clears it to 0.
  • Keyboard: the stars behave like a radio group. Tab reaches one star, ArrowRight / ArrowUp raise the rating, ArrowLeft / ArrowDown lower it, Home and End jump to 1 and max.
  • A caption shows the preview or the committed rating in words ("4 of 5, Good").
  • Read-only mode renders fractional values (3.6 fills the fourth star 60 percent) and is announced as a single image ("Rated 3.6 out of 5").
  • The parent owns the value (a controlled component).

What a strong answer should cover:

  • Two pieces of state with different owners: the committed value (parent) and the transient hover (component), rendered as hover || value.
  • Partial fill with two stacked glyphs, the top one clipped by width and overflow: hidden.
  • ARIA: role="radiogroup" with role="radio" and aria-checked per star, a roving tabindex, and role="img" with a label for the read-only display.
  • Keyboard handling that moves focus together with the selection.
  • Controlled API: value + onChange in React, v-model in Vue, [(value)] in Angular.

Clarifying questions expected:

  • "Do we need half-star input, or only half-star display?"
  • "Can a user clear their rating, and how?"
  • "Is the rating saved immediately or submitted with a form?"

Code / implementation expected: Yes. A working component with both modes, hover preview, click and keyboard rating, and correct ARIA roles.

  • React
  • Events
  • Half Star

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

11 min read Β· 9 sections

React solution

Every file of the working solution. Open it in the playground to run and change it.

ReactComplete solution
import { useState } from "react";
import StarRating from "./src/components/StarRating";

export default function App() {
  // the parent owns the value: a controlled component
  const [rating, setRating] = useState(0);

  return (
    <main className="page">
      <article className="card">
        <h1>Trail running shoes</h1>
        <p className="avg">
          <StarRating value={3.6} readOnly />{" "}
          <span data-testid="avg">3.6 average from 128 reviews</span>
        </p>
        <h2>Your rating</h2>
        <StarRating value={rating} onChange={setRating} label="Your rating" />
        <p className="saved" data-testid="saved">
          {rating
            ? "Saved: " + rating + " star" + (rating > 1 ? "s" : "")
            : "Click a star, or Tab to the stars and use the arrow keys."}
        </p>
      </article>
    </main>
  );
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 50 of 107 in Machine coding

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

Up nextMedium

Build a Split Pane (Horizontal & Vertical) with Constraints

Continue