Components
Rating
Picks or shows a score on a short scale of stars (reviews, feedback), in whole or half steps. As an input it is a radio group of the allowed values; as a display (readOnly) it is an image with a text value.
Preview
import { Rating } from "@/components/ui/rating"
<Rating aria-label="Your rating" defaultValue={4} />Usage
When to use
- Collect a short score, such as a product review, in whole or half-star steps.
- Show a read-only score with an accessible value for assistive technology.
When not to use
- Collect more than ten choices. Use Slider or NumberInput.
- Ask a yes or no question. Use a checkbox or Switch.
Variants
size
Star size: 16px in sm and md, 20px in lg. Each star occupies one size-target-min square cell, including touch.
import { Rating } from "@/components/ui/rating"
<Rating aria-label="Your rating" defaultValue={4} size="sm" />
<Rating aria-label="Your rating" defaultValue={4} />
<Rating aria-label="Your rating" defaultValue={4} size="lg" />Examples
Input
import { Field, FieldControl, FieldLabel } from "@/components/ui/field"
import { Rating } from "@/components/ui/rating"
<Field id="rating">
<FieldLabel id="rating-label">Your rating</FieldLabel>
<FieldControl>
<Rating aria-labelledby="rating-label" defaultValue={0} />
</FieldControl>
</Field>Display
import { Rating } from "@/components/ui/rating"
<Rating value={4} readOnly />Half stars
import { Rating } from "@/components/ui/rating"
<Rating aria-label="Your rating" defaultValue={3.5} allowHalf />Do and don't
Do
- Show the number next to a readOnly rating (4.6) and the review count.
- Use Field for a label and an error.
Don't
- Do not use for more than 10 levels; use Slider or NumberInput.
- Do not use for a yes or no choice.
Props
| Name | Type | Values | Default | Description |
|---|---|---|---|---|
| value | number | - | - | Selected value when controlled: 0 for none, then whole steps, or half steps with allowHalf. |
| defaultValue | number | - | 0 | Initial value when uncontrolled. |
| onValueChange | function | - | - | Called with the new value. |
| max | number | - | 5 | Number of stars. |
| size | enum | sm | md | lg | md | Star size: 16px in sm and md, 20px in lg. Each star occupies one size-target-min square cell, including touch. |
| readOnly | boolean | - | false | Display only: role img, no focus, no hover. |
| disabled | boolean | - | false | Disabled look, no interaction. |
| name | string | - | - | Form field name. |
| required | boolean | - | false | At least 1 must be picked. |
| itemLabel | (value: number, max: number) => string | - | - | Accessible name of each value, with the number formatted for the locale. Default EN `{value} of {max} stars` (3.5 of 5 stars); VI `{value} trên {max} sao` (3,5 trên 5 sao). |
| valueText | (value: number, max: number) => string | - | - | Accessible name in readOnly, with the number formatted for the locale. Default EN `Rated {value} of {max} stars`; VI `Đánh giá {value} trên {max} sao`; for 0 EN `No rating yet`, VI `Chưa có đánh giá`. |
| allowHalf | boolean | - | false | Allow half values (0.5, 1.5, ...). Arrow keys and the pointer then move in steps of 0.5. |
| locale | string | - | - | BCP 47 locale for the numbers in the labels. Defaults to the document language. |
Anatomy
| Part | Description |
|---|---|
| root | The radio group (or img when readOnly), a row of stars. |
| item | One star's visual slot. In half-step mode it contains two radio options. |
| glyph | The star icon: outline when off, Filled when on, and for a half value one icon whose first half is filled (clipped fill), from the right in RTL. The fill uses the same color as the outline (currentColor). |
| hitArea | Each star occupies one size-target-min square cell. In half-step mode, its two radio options split the cell into adjacent pointer regions, one for each half. |
Accessibility
Role: radiogroup
| Keys | Action |
|---|---|
| Tab | Focuses the checked value, or the lowest one when empty. |
| ArrowRight / ArrowUp | Next value: plus 1, or plus 0.5 with allowHalf (reversed for left and right in RTL). |
| ArrowLeft / ArrowDown | Previous value: minus 1, or minus 0.5 with allowHalf. |
| Home / End | Lowest or highest value. |
- The interactive radiogroup must have aria-label or aria-labelledby.
- Each allowed value is a radio named by itemLabel with a locale-formatted number: 3.5 of 5 stars (EN), 3,5 trên 5 sao (VI).
- Half stars: one star icon per star. For a half value its first half is filled with color-warning and its second half stays outline; in RTL the fill starts from the right. Never compose two half icons.
- Choosing the current value again keeps it. There is no reset to 0 by re-clicking; the app offers its own clear action if it needs one.
- readOnly renders role img with aria-label from valueText instead of a radio group, and nothing is focusable.
- The root sets data-read-only when readOnly; the read-only bindings read that attribute (stateAttributes), never the CSS :read-only, which matches any element that cannot be edited.
- Hover previews the value up to the pointer (to the half under it with allowHalf) without changing it.
- Color is not the only cue: the filled shape differs from the outline.
Install
npx werewolf-ui add ratingRun npx werewolf-ui init once in your app before adding components. Init sets up tokens, their CSS import and agent rules. Add installs this component and its dependencies while preserving your theme. See Installation for requirements and the alternative registry setup.