/// Inputs
Rating
Star/mark rating — N sharp symbols with hover preview, keyboard, and optional half steps.
import { Rating } from "@protocore/pds";Basics
Five sharp marks by default. Hover to preview, click to set. The picked value fills the marks with the accent; onValueChange reports the new number.
Confidence: 4 / 5
Half steps & read-only
Set allowHalf for 0.5 precision — each mark splits into two hit zones. Use readOnly to render a static, fractional display (e.g. an aggregate score) as an image.
Editable (half steps) — 3.5
Read-only aggregate
Custom symbol & count
Change the number of symbols with count and pass your own symbol node (styled via currentColor) — a heart, a bolt, a block — while keeping the fill and keyboard behaviour.
Tier 2 of 4
When to use it
Use Rating to capture or display a small ordinal score — a review, a confidence level, a severity. For an exact value on a wide continuous range, use a Slider; for a few named choices, a SegmentedControl or RadioGroup reads clearer. Keep the default sharp mark to stay on-brand — pass a custom symbol only when the metaphor genuinely helps. In readOnly mode it renders as a single labelled image, so aggregate half-values display cleanly without implying interactivity.
Usage
Do
- Give the group an accessible name via `aria-label` or a wrapping `Field`.
- Use `readOnly` to display scores that shouldn't be edited.
- Enable `allowHalf` only when half precision applies.
- Keep the sharp default mark unless a custom metaphor aids meaning.
Don't
- Don't use it for exact values on a wide range — use a Slider.
- Don't use rounded stars; the default mark is sharp (pass a `symbol` to override).
- Don't leave it unlabelled; it announces as a radio group with no name.
- Don't set `count` beyond ~10 — the scale stops reading.
Accessibility
| Keys | Action |
|---|---|
| Tab | Move focus into the group (onto the selected mark). |
| Arrow Right / Up | Increase the rating by one step (0.5 with allowHalf). |
| Arrow Left / Down | Decrease the rating by one step. |
| Home / End | Set the rating to 0 / the maximum. |
- Interactive ratings are a `role="radiogroup"` of `role="radio"` marks, each named "N out of count".
- Roving tabindex keeps a single tab stop; arrow keys move the value and hovering previews it.
- Read-only ratings render as a single `role="img"` labelled "value out of count" with no radios.
Rating props
| Prop | Type | Default | Description |
|---|---|---|---|
allowHalf | boolean | false | Allow half-symbol precision (0.5 steps). |
aria-label | string | Rating | Accessible label for the group. |
className | string | — | |
count | number | 5 | Number of symbols. |
defaultValue | number | 0 | Initial value when uncontrolled. |
disabled | boolean | false | Disable interaction and mute the marks. |
onValueChange | ((value: number) => void) | — | Fires with the newly picked value. |
readOnly | boolean | false | Render a static, non-interactive display of `value`. |
size | enum | md | Symbol size: `sm` (16) · `md` (20, default) · `lg` (28). |
style | CSSProperties | — | |
symbol | ReactNode | (
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false">
<path d="M12 1.5 14.4 9.6 22.5 12 14.4 14.4 12 22.5 9.6 14.4 1.5 12 9.6 9.6Z" />
</svg>
) | Custom symbol node (styled via `currentColor`); defaults to a sharp mark. |
value | number | — | Controlled value (0…count). |