STARS INPUT: Interactive 5-star rating radiogroup
COMPOSES: .stars color tokens (save-yellow) | native radio group (keyboard + AT for free)
Each star is a real radio input, visually hidden inside its own label — Arrow keys move
between stars and select as you go, Tab moves in/out of the group as one stop, and Space
selects the focused star. stars_input_controller.js only keeps the fill in
sync (hover preview, native change) and, when explicitly opted in via
data-stars-input-clearable-value="true", adds one thing radios can't do
alone: activating the already-selected star a second time (click or Space)
clears the rating back to blank. Off by default — see the dedicated "Clearable" scenario
below.
Unrated: no radio is checked. Hover or tab in to preview a rating; click or press Space on a star to commit it.
Rate how satisfied you were with the teaching quality.
<div class="stars-input" role="radiogroup" aria-labelledby="…" data-controller="stars-input"><label class="stars-input-star" data-value="1"><input type="radio" class="tw:sr-only" aria-label="1 star"><i class="fa-light fa-star"></i></label>…</div>
Pre-filled from data: the 4th radio carries checked in the
markup — connect() reads it and fills stars 1–4 on load, no click required.
This scenario is not clearable (the default) — once set, a rating can
only be changed to a different star, matching plain native radiogroup behavior. See the
"Clearable" scenario below for the opt-in clear-on-reclick behavior.
data-stars-input-clearable-value="true": explicit opt-in. Click (or
press Space on) the already-selected star a second time to clear the rating back to
blank — the one thing a plain radiogroup can't do on its own. Works identically from
mouse and keyboard; either way the controller fires a genuine change event
on the underlying radio so form logic and assistive tech see the clear, not just this
controller's own stars-input:changed event.
Click your rating again to clear it.
<div class="stars-input" role="radiogroup" data-controller="stars-input" data-stars-input-clearable-value="true">…</div>
.stars-input-sm / .stars-input-lg: same behaviour, smaller/larger glyph and gap. Default sits between the two.
Not a disabled .stars-input: once a rating is submitted and only ever
displayed (a review card, a summary table), use the read-only .stars
component instead of a locked interactive radiogroup — it needs no controller and
carries a plain aria-label rather than five named radios.
<div class="stars" role="img" aria-label="4 out of 5 stars">…</div>