Skip to content

ComponentsForms

Rating

Lets users give a rating with stars (or any icon), and shows existing ratings with half-star precision. Built on React Aria's RadioGroup for arrow-key support and form integration, with three sizes, seven colors, custom icons, labels for each value and field-style label, description and validation.

React AriaSource
How was your delivery?
Your rating is shared with the courier.

Installation

pnpm dlx shadcn@latest add @desyne/rating

The CLI installs dependencies and any other components this one uses.

Usage

tsx
import { Rating } from "@/components/ui/rating";
tsx
<Rating label="How was your delivery?" defaultValue={4} />

<Rating isReadOnly value={4.5} />

value is a number from 0 (no rating) to maxValue. onChange receives a number.

When to use

  • Rating: a quick, low-effort score, such as product reviews, satisfaction after a support chat, or rating an article.
  • Radio Group: when each value needs a written label the user should read before choosing.
  • Slider: a value on a continuous or fine-grained scale.
  • Meter with segments: a level, not something the user rates.

Anatomy

tsx
<Rating>                    {/* role="radiogroup" */}
  {/* Label */}
  {/* icons: one radio per value */}
  {/* value text / value label (optional) */}
  {/* Description, FieldError */}
</Rating>

<Rating isReadOnly />        {/* role="img" with "4.5 out of 5" */}
PartRendersNotes
Rating<div role="radiogroup">React Aria RadioGroup, horizontal. Handles arrow keys, name for forms, isRequired and validation.
Item<label> with a hidden radioOne per value. Its accessible name is "3 of 5", or the matching valueLabels entry.
Icon<span> × 2A faint base icon with a filled copy on top, clipped to the fill amount.
Value text<span>With showValue: the number, e.g. 4.5.
Value label<span aria-hidden>With valueLabels: the label for the hovered or selected value.
Read-only root<div role="img">With isReadOnly: not focusable, named "4.5 out of 5".

Examples

Read-only with half stars

isReadOnly renders a static display. Fractional values round to the nearest half, so 4.3 shows four and a half stars. Pair it with the numeric average and the review count.

4.5
1,188 reviews
  • 5812
  • 4264
  • 371
  • 218
  • 123

Sizes

sm (16px), md (20px, default) and lg (28px).

Custom icon and color

Pass any icon to icon and a tone to color (default warning). Use maxValue for a shorter scale.

How much did you love it?
Spice level

Value labels

valueLabels names each value. The names are used as each radio's accessible name and shown next to the icons for the hovered or selected value.

Rate this article

No rating yet.

In a form

Ratings work like any React Aria field: name submits the value with the form, isRequired blocks submission until a value is chosen, and errorMessage customizes the message.

Overall experience

Accessibility

  • Interactive ratings are a React Aria RadioGroup with one radio per value. Tab moves focus into the group; Left and Right arrows (Up and Down too) change the value, and each change is announced.
  • Every radio has a name: "3 of 5" by default, or the matching valueLabels entry, such as "Helpful".
  • Name the group with label, aria-label or aria-labelledby.
  • The read-only display is a single role="img" element named "4.5 out of 5", prefixed with label when you pass one. It isn't focusable.
  • Filled and empty icons differ in fill, not only color, so the value reads in high-contrast and grayscale modes.
  • Clicking the selected star clears the rating (value 0); from the keyboard, Backspace or Delete clears it. Turn this off with allowClear={false}, for example when a rating is required.

Styling

Data attributes

AttributeOnPresent when
data-slot="rating"RootAlways
data-readonlyRootisReadOnly
data-slot="rating-icon"Each iconAlways
data-slot="rating-value"Value textshowValue

The root also gets React Aria's RadioGroup attributes (data-disabled, data-invalid, data-required, …) and sets the group/field group, like other fields.

Tone variables

color sets --tone on the root. Filled icons use text-(--tone); empty icons use text-(--tone)/20 in light mode and text-muted-foreground/30 in dark mode.

API Reference

Prop

Type

Also accepts the props of React Aria's RadioGroup except orientation, such as isInvalid, validate and aria-describedby.

  • Radio Group: choices with written labels.
  • Slider: a value on a fine-grained scale.
  • Textarea: pair a rating with a written review.