Dots

Rating

A star scale for rating a transfer, a support chat or the app.

How was your transfer to Jordan Lee?
"use client"

import * as React from "react"

The Rating component is a star scale built on the React Aria RadioGroup. Use it to ask for feedback after a transfer, a support chat or a card order. Each star is a radio, so the score works like any other choice in a form. Pick a RadioGroup instead when the answers are words rather than a scale.

Installation

pnpm dlx shadcn@latest add @dots/rating

Usage

import { Rating } from "@/components/ui/rating"
<Rating label="How was your transfer?" onChange={(score) => save(score)} />

Features

  • Each star is a native radio, so arrow keys move and select, and forms receive the score with name
  • Chosen stars use the foreground color and the rest the track color, in both themes
  • An optional word per score, shown under the stars and added to each star's name
  • Two sizes: stars that stretch over the row, and larger centered stars for a sheet that asks one question
  • Any number of stars with max
  • Read-only and disabled states
  • value and onChange take numbers, not strings

Words

Pass getValueLabel to name each score. The word for the chosen score shows under the stars, and each star is read as "4 of 5, Good".

How was the support chat?
"use client"

import { Rating } from "@/components/ui/rating"
const words = ["Bad", "Poor", "Okay", "Good", "Great"]
 
<Rating label="How was your transfer?" getValueLabel={(n) => words[n - 1]} />

Large

Use size="lg" for bigger, centered stars, such as a sheet that asks one question. The question is usually the sheet's title, so point to it with aria-labelledby.

How do you like the app?

"use client"

import { Rating } from "@/components/ui/rating"

Scale

Set max to change the number of stars. Keep the scale short, and pair it with words so each step has a clear meaning.

How easy was it to add money?
"use client"

import { Rating } from "@/components/ui/rating"

Hidden label

Set hideLabel when a heading nearby already asks the question. The label stays for screen readers.

Rate the support chat
"use client"

import { Rating } from "@/components/ui/rating"

Read only and disabled

Use isReadOnly to show a score that was already given, and isDisabled when rating is closed.

Your rating
Rating closed
"use client"

import { Rating } from "@/components/ui/rating"

Accessibility

Rating is a React Aria RadioGroup with one radio per star. Tab moves focus into the group, arrow keys move between stars and select, and the selected score is announced as "3 of 5". Read-only, disabled and required states are announced too.

Label the scale

Pass a label, or aria-label or aria-labelledby when the question is shown elsewhere.

<Rating aria-label="Rate the support chat" />

Name the scores

Stars are named "1 of 5" to "5 of 5". Add getValueLabel so each one also carries its word, such as "5 of 5, Great". The word shown under the stars is hidden from assistive tech, so it isn't read twice.

API Reference

Rating

Accepts the React Aria RadioGroup props. orientation, children and style are not accepted; the stars are always in a row. value, defaultValue, onChange, validate and className are replaced below.

PropTypeDefaultDescription
valuenumber | null-The chosen score, 1 to max, or null for none (controlled).
defaultValuenumber | null-The score chosen at first (uncontrolled).
onChange(value: number) => void-Called with the new score when a star is chosen.
validate(value: number | null) => string | string[] | true | null | undefined-Checks the score. Return an error message, or true or null when it is fine.
maxnumber5The number of stars.
size"default" | "lg""default"default stretches the stars over the row; lg centers bigger stars.
labelReactNode-The name of the scale. Use aria-label instead when there is none.
hideLabelbooleanfalseKeep the label for screen readers only.
getValueLabel(value: number) => string-A word for a score, shown for the chosen score and added to each star's name.
namestring-The name of the score in form data.
isRequiredboolean-A score must be chosen before the form is submitted.
isReadOnlyboolean-The score can be seen but not changed.
isDisabledboolean-Disables every star.
classNamestring-Additional classes to apply to the root element.