Rating component
Rating is a star rating you can set or only show. Set, it is a slider you can click, tap or use with the arrow keys; shown, it is an image that reads "4.5 out of 5". It takes whole or half stars, 1 to 10 of them, your own icon, and it joins an oks-ui Form like any other field.
Playground
Change a prop on the right and the preview updates. Switch to Code to copy what you see.
Setting a rating
Rating works uncontrolled with defaultValue, or controlled with value and onChange. The value is a number from 0 (no rating) to max. Give it a label, or an aria-label when there is no visible label, because the control needs a name.
<Rating aria-label="Quality" defaultValue={3} onChange={(v) => console.log(v)} />
const [stars, setStars] = useState(0);
<Rating label="How was it?" value={stars} onChange={setStars} precision={0.5} allowClear showValue />Showing an average
isReadOnly turns the control into a picture: it is not focusable and is announced as an image ("4.5 out of 5"). With precision 0.5 the last star can be half filled, so an average of 4.5 shows as 4.5 stars.
<Rating isReadOnly value={4.5} precision={0.5} aria-label="Average rating" />Inside a Form
With a name, Rating registers with the surrounding Form and is stored as a number, or null when there is no rating, so a required rule means "has a rating". Outside a Form the name becomes a hidden input for a native form post.
<Form onSubmit={save}>
<Rating label="Score" name="score" validation={{ rules: { required: true } }} />
</Form>Your own icon
icon and emptyIcon replace the star. Draw the icon with currentColor so the color prop still works. Without an emptyIcon the filled icon is shown in a muted colour for the empty ones.
<Rating aria-label="Love" icon={<HeartIcon />} color="danger" />Props
The full public API for Rating. Every prop is stable and intentionally typed.
Data
| Prop | Type | Default | Description |
|---|---|---|---|
| value / defaultValue | number | 0 | The rating, 0 (none) to max. value makes it controlled. |
| onChange | (value: number) => void | — | Called with the new rating (0 when cleared). |
| max | number | 5 | How many icons, 1 to 10. |
| precision | 1 | 0.5 | 1 | Whole or half steps. With 0.5 the left half of an icon is a half. |
| name | string | — | In a Form: the key it is stored under (null for no rating, so required means has a rating). Outside one: a hidden input for a native form. |
| validation | FieldValidation | — | Rules when inside a Form. |
value / defaultValue
number
default: 0
The rating, 0 (none) to max. value makes it controlled.
onChange
(value: number) => void
default: —
Called with the new rating (0 when cleared).
max
number
default: 5
How many icons, 1 to 10.
precision
1 | 0.5
default: 1
Whole or half steps. With 0.5 the left half of an icon is a half.
name
string
default: —
In a Form: the key it is stored under (null for no rating, so required means has a rating). Outside one: a hidden input for a native form.
validation
FieldValidation
default: —
Rules when inside a Form.
Appearance
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "md" | "lg" | md | Icon size (18, 24 and 32 px). |
| color | "default" | "primary" | "secondary" | "info" | "success" | "warning" | "danger" | warning | Colour of the filled icons. |
| icon / emptyIcon | ReactNode | a star | The filled and the empty icon. Without emptyIcon the filled one is drawn in a muted colour. |
| classNames | Partial<Record<slot, string>> | — | Class per part: base, label, control, star, icon, valueText, description, error. |
size
"sm" | "md" | "lg"
default: md
Icon size (18, 24 and 32 px).
color
"default" | "primary" | "secondary" | "info" | "success" | "warning" | "danger"
default: warning
Colour of the filled icons.
icon / emptyIcon
ReactNode
default: a star
The filled and the empty icon. Without emptyIcon the filled one is drawn in a muted colour.
classNames
Partial<Record<slot, string>>
default: —
Class per part: base, label, control, star, icon, valueText, description, error.
Behavior & states
| Prop | Type | Default | Description |
|---|---|---|---|
| isReadOnly | boolean | false | Shows the rating; announced as an image. |
| isDisabled | boolean | false | Dimmed, not focusable, ignores input. |
| allowClear | boolean | false | Choosing the current rating again clears it; Delete, Backspace and 0 clear from the keyboard. |
| onHoverChange | (value: number | null) => void | — | The rating under a mouse pointer (a touch has no hover), null when it leaves. |
isReadOnly
boolean
default: false
Shows the rating; announced as an image.
isDisabled
boolean
default: false
Dimmed, not focusable, ignores input.
allowClear
boolean
default: false
Choosing the current rating again clears it; Delete, Backspace and 0 clear from the keyboard.
onHoverChange
(value: number | null) => void
default: —
The rating under a mouse pointer (a touch has no hover), null when it leaves.
Content
| Prop | Type | Default | Description |
|---|---|---|---|
| showValue | boolean | false | Shows the number beside the icons. |
| getValueText | (value, max) => string | "4 out of 5" | The spoken value; use it to translate. |
| label / description | ReactNode | — | A visible label (it names the control) and help text. |
| error | ReactNode | boolean | form's error for name | An error message, or true for the invalid look. |
| aria-label | string | — | Needed when there is no label. |
showValue
boolean
default: false
Shows the number beside the icons.
getValueText
(value, max) => string
default: "4 out of 5"
The spoken value; use it to translate.
label / description
ReactNode
default: —
A visible label (it names the control) and help text.
error
ReactNode | boolean
default: form's error for name
An error message, or true for the invalid look.
aria-label
string
default: —
Needed when there is no label.
Accessibility
- Editable, it is role="slider" with aria-valuemin 0, aria-valuemax, aria-valuenow and aria-valuetext ("3 out of 5"), with one tab stop. getValueText changes the spoken text, for translation.
- Keys: Arrow keys move one step (swapped in right-to-left pages), PageUp and PageDown move a whole icon, Home and End go to the ends, a digit goes to that rating, and Delete, Backspace or 0 clear it when allowClear is on.
- Read-only, it is role="img" named "4.5 out of 5" and is not focusable.
- The hover preview is for a mouse only. A touch rates on tap and the page still scrolls. Filled and empty icons differ by more than colour, and forced-colors mode uses system colours.
Best practices
- Always give it a label or aria-label; a bare row of stars has no name for a screen reader.
- Use allowClear when "no rating" is a valid answer, otherwise the keyboard cannot go below one step.
- Show averages with isReadOnly and precision 0.5, and put the number next to them (showValue) so the exact figure is not left to the reader's eye.
- Do not use a rating where a reader needs to compare many items precisely; ask for a number or a choice instead.