# 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.

## 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.

Values: `sm`, `md`, `lg`. Default: `md`.

## Examples

### Input

```tsx
<Field id="rating">
  <FieldLabel id="rating-label">Your rating</FieldLabel>
  <FieldControl>
    <Rating aria-labelledby="rating-label" defaultValue={0} />
  </FieldControl>
</Field>
```

### Display

```tsx
<Rating value={4} readOnly />
```

### Half stars

```tsx
<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

```bash
npx werewolf-ui add rating
```

Run `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](https://werewolf-ui.vercel.app/docs/installation.md) for requirements and the alternative registry setup.
