Fields
Rating
A star scale built from hidden native radios, one per step.
When to use it: Use it to collect one score on a small fixed scale, such as one to five stars.
Example
import { useState } from "react";
import { Rating, RatingItem } from "@comp0/react";
export function Example() {
const [stars, setStars] = useState(3);
return (
<div className="flex flex-col gap-1">
<span className="text-base font-medium text-zinc-900 sm:text-sm dark:text-zinc-100">
Rate your stay
</span>
<Rating className="flex w-fit" name="stay" value={stars} onChange={setStars}>
{[1, 2, 3, 4, 5].map((star) => (
<RatingItem
key={star}
value={star}
inputProps={{ "aria-label": `${star} of 5 stars` }}
className="cursor-pointer rounded px-0.5 text-2xl text-zinc-300 ring-teal-600 transition-colors duration-100 ease-out data-active:text-amber-500 data-focus-visible:ring-2 motion-reduce:transition-none sm:text-xl dark:text-zinc-700 dark:ring-teal-400 dark:data-active:text-amber-400"
>
<span aria-hidden="true">★</span>
</RatingItem>
))}
</Rating>
<p className="text-base text-zinc-600 sm:text-sm dark:text-zinc-400">{stars} of 5 stars</p>
</div>
);
}Anatomy
Dashed frames are invisible state providers; shaded shapes own real DOM. Numbered pins match the list below.
A wireframe sketch of the assembled component. Each numbered marker matches a part in the list that follows.
Rating
Container that names and manages the star radios. Owns a DOM element.
RatingItem
Star label around one hidden native radio. Owns a DOM element.
Step by step
- 1
Add the main part
Put Rating where the score belongs and give it a name.
- 2
Add the supporting parts
Add one RatingItem per step with its number as value and a star glyph as children.
- 3
Make the behavior clear
Style the stars through [data-active], which covers every step up to the hovered or selected one; use readOnly to display a score without allowing changes.
Exampletsx <Rating name="stay" defaultValue={3}> <RatingItem value={1} inputProps={{ "aria-label": "1 of 5 stars" }}> ★ </RatingItem> </Rating>;
Keyboard
- ↓→
- Moves to and selects the next star.
- ↑←
- Moves to and selects the previous star.
- Space
- Selects the focused star.
Forms and accessibility
The checked radio submits Rating.name and its value.
Accessibility checklist
- Give each hidden radio a spoken name such as 3 of 5 stars via inputProps.
- Show the picked score with more than color; the glyphs themselves should fill.
- Use readOnly for a score people can inspect but not change; it stays focusable.
API reference
import { Rating, RatingItem } from "@comp0/react";Rating
DOM elementContainer that names and manages the star radios.
| Prop | Type | Description |
|---|---|---|
name | string | Shared submission name for the item radios; generated when absent. |
value | number | Controlled rating; 0 means none. |
defaultValue | number | Initial rating; 0 means none. |
onChange | (value: number) => void | Receives the next rating. |
required | boolean | Requires one item in the group to be selected. |
readOnly | boolean | Keeps the items focusable while preventing changes. |
disabled | boolean | Disables every item. |
RatingItem
DOM elementStar label around one hidden native radio.
| Prop | Type | Description |
|---|---|---|
value | number | The rating this item stands for; 0.5 steps are allowed. |
inputProps | InputHTMLAttributes | Extra props for the hidden radio, such as aria-label. |
Style hooks
Attributes that appear while a state is true. Target them with Tailwind data variants such as data-open:bg-zinc-100, or with any CSS selector.
Rating
| Style hook | Meaning |
|---|---|
[data-disabled] | The rating is disabled. |
[data-readonly] | The rating cannot be changed. |
RatingItem
| Style hook | Meaning |
|---|---|
[data-active] | This step is at or below the hovered or selected rating. |
[data-selected] | This step is the exact rating. |
[data-focus-visible] | Focus should show a visible ring. |