Skip to main content

Rating

Info:Controls
8

A rating control — interactive or read-only — that scores with any icon and shows fractional values as a partial icon.

stars star rating score review vote rank

Live demo

live · @xtyle/astro

Rating

Product rating

4.5 out of 5 stars

4.5 · 1,204 reviews

Interactive

Click, drag, or focus and use the arrow keys.

Rate this product Rate this stay (half steps)

Any icon, any tone

Rate this recipe Rate the intensity

Sizes and values

5 out of 5 stars 3.5 out of 5 stars 2 out of 5 stars 7 out of 10 stars

Rating draws max icons and overlays a colored copy clipped to value / max, so a fractional value like 4.5 shows an exact partial icon rather than rounding. It renders two rows: a neutral base row (the icon silhouetted to a muted track color) and a filled row (the icon in full color) clipped to the value fraction.

Any icon works: the default star, any functional glyph (heart, bolt, …), or a composed colorful mark spec (taco--…), drawn through the icon system. A monochrome glyph takes its fill from tone (a register hue), a colorful mark draws its palette from colors. By default it is an interactive slider — focusable, role="slider", driven by pointer drag, click, and Arrow/Home/End keys, with a hover preview, firing input and change and posting through a hidden input when name is set. Add readonly and it becomes a fixed role="img" display for an average score, a product rating, a survey result. The element's own text is the no-JS fallback and the accessible label. Override --rating-track (base color, defaults to --neutral-bg) or --rating-fill (fill color, defaults to --accent) per instance to retune it.

When to use

How this component composes with the rest of the set.

Leave it interactive to collect a rating in a form; pair it with a name so the value posts, or bind value in Svelte.
Add readonly beside a product title with the numeric score and review count for a summary row.
Swap icon (a heart with tone="red", a bolt, a colorful mark) so the rating matches the thing being rated.
Use size="sm" inside a dense list of results, lg for a hero or a single featured review.

Props

10 props, straight from the manifest.

PropTypeDefaultBindingsDescription
value number 0
html svelte astro
The rating. Fractional values render a partial icon; clamped to `0..max`. Two-way bindable in Svelte.
max number 5
html svelte astro
How many icons to draw.
icon string star
html svelte astro
The icon to rate with: `star` (default), any functional glyph by name (`heart`, `bolt`, …), or a composed mark spec (a `--` name like `taco--…`) for a colorful multi-layer mark.
readonly boolean false
html svelte astro
Renders a fixed, fractional display (`role="img"`) instead of the interactive slider. Omit it (the default) for an editable control.
allowHalf boolean false
html svelte astro
Snaps interactive input (pointer and keys) to half steps instead of whole ones. Attribute is `allowhalf`.
tone string
html svelte astro
Fill hue for a monochrome icon: a register token name (`accent`, `success`, `red`, …). Sets `--rating-fill`.
colors SeriesScheme
accents skittles statuses thermal status
accents
html svelte astro
The series scheme a colorful mark spec draws its palette from (`accents`, `skittles`, …).
size Size
sm md lg
md
html svelte astro
Icon size: `sm`, `md`, or `lg`.
name string
html svelte astro
Form field name; when set (and interactive), the current value posts through a hidden input.
label string
html svelte astro
Accessible label. Defaults to the element's text content, then to a generated `"{value} out of {max} stars"`.

Appearance

Sizes

sm

.xtyle-rating--sm

Small icons.

md

default
.xtyle-rating

Default.

lg

.xtyle-rating--lg

Large icons.

States

interactive

.xtyle-rating--interactive

Editable (the default, readonly absent): role="slider", focusable, pointer- and key-driven, with a pointer cursor.

hover

.xtyle-rating--interactive:hover

Pointer over an interactive control: the filled row previews the value under the cursor without committing it.

focus-visible

.xtyle-rating--interactive:focus-visible

Keyboard focus on an interactive control: a token-colored ring around the rounded control.

readonly

.xtyle-rating:not(.xtyle-rating--interactive)

Non-interactive display (readonly set): a fixed role="img" with no cursor, tab stop, or events.

Anatomy

The named parts that make up the component, with their selectors.

root

.xtyle-rating

The control wrapper. Sizes the icons, stacks the two rows, and carries the interactive class, focus ring, and the --rating-track / --rating-fill override vars.

--neutral-bg --accent --text-lg --ring --radius-sm --border-thick

row

.xtyle-rating__row--empty

The base row of silhouetted icons; sets the neutral track color (--rating-track) and the overall size.

--neutral-bg

fill

.xtyle-rating__row--filled

The full-color copy of the row, clipped by width to the value fraction and laid over the base row.

--accent

Tokens & coverage

What the component consumes, checked live against what the algorithm produces.

Success:fully covered 8/8 consumed tokens produced default register: 299 tokens

Live coverage check against the xtyle-default register (derive(xtyleDefault, { anchors })coverComponent(manifest, register)). Every token this component consumes must be a key the algorithm produces.

--accent --border-thick --neutral-bg --radius-sm --ring --text-2xl --text-lg --text-sm

Slots

default
html svelte astro

The no-JS fallback text, adopted as the accessible label. Give a human-readable score or prompt like 4.5 out of 5 or Rate this product.

Accessibility

Interactive, it is a role="slider" with aria-valuemin/aria-valuemax/aria-valuenow/aria-valuetext kept in sync, focusable, and driven by Arrow keys (by step), Home/End (to min/max), plus pointer drag and click.
Read-only, it is a single role="img" with a text label, so assistive tech announces the score once ("4.5 out of 5 stars") instead of reading each icon; the icon glyphs are decorative and aria-hidden.
The value is carried by the label, not by color alone, so a color-deficient user gets the same information.
With name set, an interactive control writes its value to a hidden input so it participates in form submission.
With no JavaScript the fallback text stays visible, so the score or prompt is never lost behind the enhancement.

Code

Interactive, read-only, and custom icons

An editable star rating, a fractional read-only score, a heart rating tinted red, a half-step control, and a compact 10-point display.

<xtyle-rating value="3" label="Rate this product"></xtyle-rating>

<xtyle-rating value="4.5" readonly label="4.5 out of 5 stars"></xtyle-rating>

<xtyle-rating value="4" icon="heart" tone="red" label="Rate this recipe"></xtyle-rating>

<xtyle-rating value="3.5" allowhalf label="Rate this stay"></xtyle-rating>

<xtyle-rating value="7" max="10" size="sm" readonly label="7 out of 10"></xtyle-rating>
<script lang="ts">
	import { Rating } from "@xtyle/svelte";

	let score = $state(3);
</script>

<Rating bind:value={score} label="Rate this product" />

<Rating value={4.5} readonly label="4.5 out of 5 stars" />

<Rating value={4} icon="heart" tone="red" label="Rate this recipe" />

<Rating value={3.5} allowHalf label="Rate this stay" />

<Rating value={7} max={10} size="sm" readonly label="7 out of 10" />
---
import Rating from "@xtyle/astro/Rating.astro";
---

<Rating value={3} label="Rate this product" />

<Rating value={4.5} readonly label="4.5 out of 5 stars" />

<Rating value={4} icon="heart" tone="red" label="Rate this recipe" />

<Rating value={3.5} allowHalf label="Rate this stay" />

<Rating value={7} max={10} size="sm" readonly label="7 out of 10" />