The Rating component collects a score from the user, or shows one that has already been given. It works with the mouse, with touch and with the keyboard, supports half stars, and submits inside a form like any other input.
Example
Import the component and bind a number to it. Clicking a star sets the value, and clicking the same star again clears it.
<script>
import { Rating } from "theui-svelte";
let score = $state(3)
</script>
<Rating bind:value={score} />Sizes
The size prop accepts sm, md, lg and xl. The default is md.
<Rating value={4} size="sm" readonly />
<Rating value={4} size="md" readonly />
<Rating value={4} size="lg" readonly />
<Rating value={4} size="xl" readonly />Half Stars
Add allowHalf to let the user pick half a star. Each star then has two halves to click, and the arrow keys step by 0.5.
<script>
let halfScore = $state(2.5)
</script>
<Rating bind:value={halfScore} allowHalf size="lg" />Read Only
Use readonly to show a score that cannot be changed, such as the average of many reviews. Any fraction is drawn exactly, so 3.7 fills the fourth star seven tenths of the way. A read-only rating is announced as a single image, such as "Rating: 3.7 of 5".
<Rating value={3.7} readonly />
<Rating value={5} readonly />
<Rating value={0} readonly />Maximum
The max prop sets how many stars there are. The default is 5.
<Rating value={2} max={3} readonly />
<Rating value={7} max={10} readonly />Disabled and Clearing
A disabled rating is dimmed and cannot be changed. Clicking the star that is already chosen clears the rating back to zero; pass clearable=false when a score, once given, must stay.
<Rating value={2} disabled />
<Rating value={3} clearable={false} />In a Form
Give the component a name and the score is submitted with the form, because the stars are real radio inputs underneath. The onchange callback runs with the new value whenever it changes.
<form method="POST">
<Rating name="score" value={4} onchange={(v) => console.log(v)} />
<button>Send review</button>
</form>Custom Icon
The icon snippet replaces the star with any shape you like. It is drawn twice, once empty and once filled, and takes its colour from the classes below, so use fill="currentColor" or an SVG from the library.
<script>
import { Rating, Svg } from "theui-svelte";
</script>
<Rating value={4} readonly activeClasses="text-error-500">
{#snippet icon()}
<Svg size={0} class="size-full">
<path d="M8 14.25s-6-4-6-8a3.5 3.5 0 0 1 6-2.45A3.5 3.5 0 0 1 14 6.25c0 4-6 8-6 8z"/>
</Svg>
{/snippet}
</Rating>Customization
Use activeClasses for the filled part, inactiveClasses for the empty part and itemClasses for every star, for example to change the gap or add a shadow.
<Rating value={4} readonly activeClasses="text-brand-500" />
<Rating value={4} readonly activeClasses="text-success-500" inactiveClasses="text-success-500/25" />
<Rating value={4} readonly class="gap-3" itemClasses="drop-shadow" />Accessibility
An editable rating is a group of radio buttons, the pattern screen reader users already know. Tab moves to the group, the arrow keys move between stars, and Space picks one. Each star carries text such as "3 of 5", which you can reword with the itemLabel prop, and the group is named by ariaLabel. A read-only rating is a single image with its score in the label, so it is read at once instead of star by star. The score is never colour alone: the filled part is a different shape, and the value is in the label.