Rating
A rating control — interactive or read-only — that scores with any icon and shows fractional values as a partial icon.
Live demo
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.
Props
10 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Appearance
Sizes
sm
Small icons.
md
Default.
lg
Large icons.
States
interactive
Editable (the default, readonly absent): role="slider", focusable, pointer- and key-driven, with a pointer cursor.
hover
Pointer over an interactive control: the filled row previews the value under the cursor without committing it.
focus-visible
Keyboard focus on an interactive control: a token-colored ring around the rounded control.
readonly
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
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.
row
The base row of silhouetted icons; sets the neutral track color (--rating-track) and the overall size.
fill
The full-color copy of the row, clipped by width to the value fraction and laid over the base row.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
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
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
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" />