Playground
A row of pixel hearts (or stars) for a score. Point to preview, click to pick, or use the arrow keys. The live value is the value property, so data-bind works, and a new value attribute from the server replaces it.
Examples
Bound to a signal
<div data-signals="{_score: 3}" style="display: grid; gap: 12px">
<sb-rating label="How was the launch?" data-bind:_score__prop.value></sb-rating>
<span>Score: <b data-text="$_score"></b></span>
</div>
Half steps and stars
<div style="display: grid; gap: 12px">
<sb-rating icon="star" precision="0.5" value="2.5"></sb-rating>
<sb-rating icon="star" precision="0.5" value="4" max="10" size="sm"></sb-rating>
</div>
Read only
For showing a score, e.g. an average: readonly turns it into an image with a text alternative ("4.5 of 5").
<sb-rating readonly value="4.5" precision="0.5" size="sm"></sb-rating>
Clearable
With clearable, picking the current value again resets it to 0.
<sb-rating clearable value="2"></sb-rating>
With commands
Give it a name, and it emits sb-change with { name, value } when a value is picked: ready to post as a command. With confirm, it sets :state(pending) until the server's re-rendered attribute matches, and revert() goes back to the server's value when a command is rejected. See Commands and components.
Theming
The filled colour is --sb-rating-color (hearts default to --sb-danger, stars to --sb-warn); empty units use --sb-border-strong.
Accessibility
The row is a slider (Arrow keys change the value by one step, Home clears it, End fills it), named by label or "Rating", with aria-valuetext like "3 of 5". Read-only ratings are an img with the same text.
Installation
Add Datastar with Rocket and the Starbase autoloader once per page, then use the tag. The autoloader imports each component the first time its tag appears, including tags added later by a Datastar morph.
<!-- Once per page: Datastar with Rocket, and the Starbase autoloader.
It loads every <sb-…> component the first time its tag appears. -->
<script type="importmap">
{ "imports": { "datastar": "https://cdn.jsdelivr.net/gh/starfederation/datastar@v1.0.4/bundles/datastar-rocket.js" } }
</script>
<script type="module" src="https://starbase.zweiundeins.gmbh/c/autoloader.js"></script>
<!-- Optional, no flash of undefined elements: class="sb-cloak" on <html>, and -->
<style>.sb-cloak :not(:defined) { visibility: hidden }</style>
<sb-rating value="3.5" precision="0.5" size="lg"></sb-rating>
<!-- In production, pin today's catalog instead of the latest: the browser then
refuses any file that changed. Add "integrity" to the import map above: the
hashes from https://starbase.zweiundeins.gmbh/c/@0a1ad1bf98a4/importmap.json and Datastar's, below. -->
<!--
<script type="importmap">
{ "imports": { "datastar": "https://cdn.jsdelivr.net/gh/starfederation/datastar@v1.0.4/bundles/datastar-rocket.js" },
"integrity": { "https://cdn.jsdelivr.net/gh/starfederation/datastar@v1.0.4/bundles/datastar-rocket.js": "sha384-vUxZojLrF1Ar3de5h7VINqhJXBgjyZS4U49pHvGa87kum6j5Xn6JRziuARNw5ELG", "…": "…from importmap.json" } }
</script>
<script type="module" src="https://starbase.zweiundeins.gmbh/c/@0a1ad1bf98a4/autoloader.js" integrity="sha384-IvSCUjEWPS+wwXunU+48x96KmyWDx/Y4LeCwCL8cWFqJ/zHmTsTOsSMrzTOcpW3D"></script>
-->
<!-- Or load just this component, pinned to this version: -->
<!-- <script type="module" src="https://starbase.zweiundeins.gmbh/c/rating@c6d948a68247/rating.js" integrity="sha384-TmQRJgbAWvy4Sy745a6pcNj9N63ahkuFOB0YeUkJVR+dgipTsOPMYY77OK/fCOgD"></script> -->Size
Each file compressed on its own, the way it is served (gzip -9, brotli -11). Datastar and Rocket are shared by every component and not counted.
| File | Original | gzip | brotli |
|---|---|---|---|
rating.js | 8.1 kB | 3.4 kB | 2.9 kB |
API reference
Props
| Attribute | Type | Default | Description |
|---|---|---|---|
value | number | 0 | The value. A new value from the server replaces it; the live value is the value property. |
max | number | 5 | Number of hearts (or stars). |
precision | "1" | "0.5" | "1" | Step: whole or half units. |
icon | "heart" | "star" | "heart" | Pixel sprite. |
size | "sm" | "md" | "lg" | "md" | Size. |
label | string | "" | Visible label (also the accessible name). |
readonly | boolean | false | Show the value; no interaction. |
clearable | boolean | false | Picking the current value again clears it to 0. |
disabled | boolean | false | Disable interaction. |
confirm | boolean | false | Server-confirmed value: :state(pending) while the local value differs from the server's value attribute (see revert()). |
name | string | "" | Name reported in sb-change (e.g. the field of a command). |
Events
| Name | Description |
|---|---|
change | When the value is committed. |
sb-change | Same moment. detail: { name, value }: ready for a command. |