- Accordion
- Action Bar
- Action Toast
- Alert Banner
- Alert Dialog
- Alert
- Alphabet Index
- Amount Field
- Aspect Ratio
- Attachment
- Availability List
- Avatar
- Badge
- Bank Card
- Breadcrumb
- Bubble
- Button Group
- Button
- Calendar
- Camera Frame
- Card Design Picker
- Card Details
- Card Peek
- Card Stack
- Card
- Carousel
- Chart
- Chat Thread
- Checkbox
- Chip Group
- Choice Tile
- Code Block
- Code Dots
- Collapsible
- Combobox
- Command
- Context Menu
- Copy Field
- Countdown
- Country Select
- Data Table
- Date Field
- Date Picker
- Date Range Picker
- Dialog
- Direction
- Document Paper
- Drawer
- Dropdown Menu
- Empty
- Entity Avatar
- Field
- File Trigger
- File Upload Item
- Hover Card
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Key Value
- Keypad
- Label
- Live Region
- Marker
- Message Scroller
- Message
- Money Amount
- Native Select
- Number Field
- Pagination
- Percent Split Editor
- Phone Field
- Popover
- Progress
- QR Code
- Questionnaire
- Radio Group
- Range Histogram
- Rating
- Resizable
- Scroll Area
- Search Field
- Select
- Separator
- Share Bar
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Sortable List
- Spinner
- Status Timeline
- Step Header
- Steps List
- Swipe Row
- Switch
- Table
- Tabs
- Text Field
- Textarea
- Tier Ladder
- Toggle Group
- Toggle
- Token Search Field
- Tooltip
- Trace
- Transaction Row
- Usage Meter
"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
valueandonChangetake 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".
"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.
"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.
"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.
"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.
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | null | - | The chosen score, 1 to max, or null for none (controlled). |
defaultValue | number | 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. |
max | number | 5 | The number of stars. |
size | "default" | "lg" | "default" | default stretches the stars over the row; lg centers bigger stars. |
label | ReactNode | - | The name of the scale. Use aria-label instead when there is none. |
hideLabel | boolean | false | Keep 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. |
name | string | - | The name of the score in form data. |
isRequired | boolean | - | A score must be chosen before the form is submitted. |
isReadOnly | boolean | - | The score can be seen but not changed. |
isDisabled | boolean | - | Disables every star. |
className | string | - | Additional classes to apply to the root element. |