Rating

Free

Star, heart, fire and thumb rating variants with half-star support, hover preview and 4 sizes.

</>sv-rating ratingstarsfeedback
import { SvRatingComponent } from '@styloviz/forms';

Demo & usage

Basic usage

Usage example — open the gallery for the full interactive demo.

An interactive demo for this component lives in the gallery.

Open live demo

More examples

Read-only with count

example.htmlAngular
<sv-rating [value]="4.5" [half]="true" [readonly]="true" [showCount]="true" [count]="128" />

Alternate icons

example.htmlAngular
<sv-rating variant="heart" color="#ef4444" [(ngModel)]="likeScore" />

Review summary (histogram)

Read-only summary: a large average, precise fractional icons and a per-level histogram computed from a distribution array.

example.htmlAngular
<sv-rating [summary]="true" [distribution]="[58, 42, 96, 210, 1187]" />

When to use

  • Collecting or displaying a 1–5 style score (reviews, feedback, quality).
  • You want half-step precision and hover preview.
  • Set `readonly` to show an aggregate rating without allowing edits.

Async states

  • error

Server writes

Writes
  • changeRequest

Each payload carries a requestKey — send it with the request so a retry cannot apply the same change twice.

Rollback
Call event.rollback() when the save fails — the change is already on screen, and this is what puts it back.
While saving
Bind pending — with two writes outstanding there is no single state to roll back to, so the action stays locked until the first one lands.
On failure
Pass the failure to error to show it in place — without taking away what the user was working on.

Inputs

NameTypeDefaultDescription
valuenumber (two-way)0Current rating (two-way).
maxnumber5Number of icons in the scale.
sizeRatingSize'md'Icon size: sm, md, lg or xl.
variantRatingVariant'star'Icon set: star, heart, fire or thumb.
readonlybooleanfalseDisplay-only mode — no hover or click.
halfbooleanfalseAllow half-step ratings.
disabledbooleanfalseDisable interaction.
labelstring''Accessible label for the rating control.
showCountbooleanfalseShow the rating count next to the icons.
countnumber0Number of ratings to display when showCount is on.
colorstring'#f59e0b'Active icon color (any CSS color).
levelLabelsreadonly string[][]What each level of the scale MEANS, from level 1 upwards. The defect this exists for: ONLY STARS ARE ORDINAL BY CONVENTION. Five stars is a quality scale everyone has already agreed on, so "3 of 5 stars" is a complete sentence. Three hearts out of five is not a rating of 3 — it is a like count wearing a rating's clothes, and "3 of 5 hearts" tells a screen-reader user a number and nothing about what they just said. Fire and thumb are worse: nobody has a shared scale for either. So the meaning is declarable instead of assumed. With labels, `aria-valuetext` becomes "4 of 5 — Really like it", which is what `aria-valuetext` is FOR: the number is already in `aria-valuenow`, and a value text that only repeats it earns nothing. ⚠️ Labels are per WHOLE level. A half-step has no name, so `3.5` announces numerically — which is honest, and better than inventing "between Good and Great".
scaleNounstring''What the scale is called, overriding the per-variant noun. `'star' | 'heart' | 'fire' | 'thumb'` pick a GLYPH, and the glyph is not the meaning: a heart scale measuring urgency is not measured in hearts. Supply the plural form — it is used for the whole scale, and only a one-point scale would want a singular, which a host in that position can simply write.
summarybooleanfalseRead-only summary layout: a large average, precise fractional icons and a per-level histogram breakdown (as seen under product reviews).
distributionnumber[][]Per-level counts for the summary histogram. `distribution[i]` is the number of ratings equal to `(i + 1)` items — so `distribution[max - 1]` is the top-rating count.
pendingbooleanfalseThe user's rating is drawn and its write is in flight. Not `disabled` and not `readonly`: the chosen value stays at full strength — fading it reads as "this did not take" — and the slider stays focusable. It refuses further changes while true, which is what makes `rollback()` unambiguous. Bind it for the whole round-trip.
errorSvDataError | string | nullnullThe write failed. Accepts an `SvDataError` or a plain string. Not `serverError`, which expires on the next value change — and a rollback IS a change, so the failure would vanish in the same tick the rating reverted. Call `rollback()` as well.
errorMessagestring''Client-side validation message.
serverErrorSvServerErrornullA rejection reported by the server about this value. Self-expiring.

Outputs

EventPayload typeDescription
changednumberEmitted with the new rating when the user selects one.
changeRequestSvRatingChangeThe same change, carrying what a server write needs: an idempotency key and a guarded `rollback()`. Additive — `changed` still fires first.
valueChangenumberEmits the new `value` whenever it changes — the output half of `[(value)]`.

Customization & theming

  • Choose `variant` (star, heart, fire, thumb), `size` (sm–xl), `max`, `color` and optional `showCount` / `count`.
  • Half-step ratings (`half`) with hover preview; `readonly` and `disabled` states.
  • Two-way bind `[(value)]` or a reactive control (CVA); listen to `(changed)`.
  • Read-only `summary` mode renders an average + per-level histogram from a `distribution` array (or compose `readonly` icons with a Progress Bar).

Best practices

  • Do: Use `readonly` + `showCount` when displaying an average so it isn't mistaken for input.
  • Do: Provide a `label` so the control has a meaningful accessible name.
  • Tip: Pick an icon `variant` (star/heart/fire/thumb) that matches the sentiment being measured.

Accessibility

  • A single `role="slider"` (one tab stop, not N buttons): Arrow keys change the value, Home/End jump to min/max, with half-steps when `half` is on.
  • `aria-valuemin`/`max`/`now` plus `aria-valuetext` announce e.g. "3 of 5 stars"; the bound `label` names the control.
  • Declare what the scale means: `levelLabels` (one per whole level) makes the value text "4 of 5 — Great" and shows the level beside the glyphs; `scaleNoun` replaces the per-glyph noun ("3 of 5 levels of urgency") — hearts, fire and thumbs are not ordinal by convention. Half steps announce numerically.
  • With `half` on, each interactive slot widens to 48px (and a `sm` slot gains vertical padding) so each half is at least a 24×24px pointer target; read-only ratings are not widened.
  • Read-only ratings render as `role="img"` with the same descriptive label; implements ControlValueAccessor for `[(ngModel)]` / reactive forms.

Feedback on Rating

Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.

Loads giscus.app and GitHub — nothing is fetched until you click.