Skip to content
omaris

Selection

Rating

Rating — a row of stars, or of any icon you give it.

import { Rating } from 'omaris'
Learn

Examples

Basic

Hover to preview, press to choose — the chosen star pops. It is one slider: the arrows step it, Home and End go to the ends, a digit jumps there.

<script lang="ts">	import { Rating } from 'omaris';​	let rating = $state(4);</script>​<Rating label="Rate your order" bind:value={rating} />

Half and readonly

allowHalf makes the starting half of a star the half-point. readonly is a display that fills fractionally — an average of 4.3 shows a third of a star.

4.3 · 212 reviews

<script lang="ts">	import { Rating, Text } from 'omaris';​	let half = $state(3.5);</script>​<div class="flex flex-col items-start gap-4">	<Rating allowHalf label="Half stars" bind:value={half} />	<div class="flex items-center gap-2">		<Rating readonly value={4.3} size="sm" label="Average rating" />		<Text variant="body-sm" tone="muted" tabular>4.3 · 212 reviews</Text>	</div></div>

Icons and tones

Any icon, painted with currentColor — it is drawn twice, unfilled and filled. tone colours the filled one; size runs 20 / 24 / 32px.

<script lang="ts">	import { Rating } from 'omaris';​	let love = $state(3);	let spice = $state(2);</script>​{#snippet heart()}	...{/snippet}​{#snippet flame()}	...{/snippet}​<div class="flex flex-col items-start gap-4">	<Rating		icon={heart}		tone="destructive"		size="lg"		label="How much you love it"		bind:value={love}	/>	<Rating icon={flame} tone="warning" max={3} label="Spice level" bind:value={spice} /></div>

Overridden

Ten stars in a narrow box: the caller trims the finger padding so the row fits a phone, recolours both layers, and names it with its own aria-label — which wins over the component's.

<script lang="ts">	import { Rating } from 'omaris';​	let score = $state(7);</script>​<div class="w-64 max-w-full">	<Rating		max={10}		size="sm"		aria-label="Score out of ten"		classes={{			item: 'pointer-coarse:p-0.5',			icon: 'text-muted-foreground/40',			fill: 'text-success'		}}		bind:value={score}	/></div>

When to use it

Use it for

  • Asking for a score out of a few — an order, a driver, a dish — bound with bind:value; 0 means "not rated yet".
  • Half-point precision with allowHalf, where the difference between 3 and 3.5 matters to the person giving it.
  • Showing an average next to a review count: readonly fills fractionally, so 4.3 shows a third of the fifth star, and is announced as one value.
  • A scale that is not stars — hearts, flames, thumbs — through the icon snippet, painted with currentColor.

Not for

  • A precise number on a wide range — 0 to 100, a price → Slider or Number Input.
  • A choice between labelled options — Poor / Fair / Good → Segmented Button or Radio. The words carry the meaning; stars do not.
  • A like, a favourite, a bookmark — one on/off → a toggle Icon Button.
  • Progress towards a goal → Progress or Gauge.

Do

  • Give it a label that says what is rated — "Rate the driver" — or put it in a Field; "Rating" is only the fallback.
  • Keep max at 5 for a score people give, and show the number beside a readonly average; the stars alone read as roughly.
  • Localise valueText with the page — it is what a screen reader speaks.
  • Turn on haptics in settings once for the whole app; a chosen star buzzes on a phone.

Don't

  • Use readonly stars as a button to open the reviews; they are an image. Put them inside a link or a Button.
  • Put ten stars on a phone at the default size; at a finger's 44px each, the row is wider than the screen. Trim classes.item or keep to five.
  • Colour a low score red with tone; the fill is the scale, not a verdict.

Quick reference

tone
  • primary
  • secondary
  • tertiary
  • destructive
  • success
  • warning (default)
  • info
size
  • sm
  • md (default)
  • lg

20 / 24 / 32px icons; under a finger every star grows to a 44px target.

API

Rating

Rating — a row of stars, or of any icon you give it.

It is one control, not five buttons: a slider from 0 to max, with a spoken value ("3.5 of 5") and one Tab stop. The arrows step it — mirrored under RTL — Home and End go to the ends, and a digit key jumps straight to that many.

Under the pointer it previews before it commits: hover and the stars fill up to where you are, drag a finger along and they follow it, let go and the chosen star pops. allowHalf splits every star down the middle, the starting half giving the half-point.

readonly turns it into a display — an image with the value for its name — and it fills fractionally, so an average of 4.3 shows a third of a star.

import { Rating } from 'omaris'
<Rating bind:value label="Your rating" /><Rating value={4.3} readonly size="sm" />

Parts

Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.

root
No description in the source yet.
item
One star's box: the empty icon, with the filled one laid over it.
icon
The icon at rest, unfilled.
fill
The filled icon, clipped from the start to the star's share of the value.

Props

value bindable

Defaults to 0

number

The rating, from 0 to max. 0 is "not rated". Bindable.

max

Defaults to 5

number

How many stars.

allowHalf

Defaults to false

boolean

Half-star steps — the starting half of a star gives the half-point.

readonly

Defaults to false

boolean

A display, not a control: no focus, no pointer, fractional fill.

disabled
boolean

Inside a Field, defaults to the field's.

clearable

Defaults to true

boolean

Pressing the current value again clears it back to 0.

size

Defaults to 'md'

RatingSize
sm
md
lg
tone

Defaults to 'warning'

RatingTone

Colour of a filled star. Amber by default — the colour a rating is read in.

primary
secondary
tertiary
destructive
success
warning
info
label
string

Accessible name. "Rating" when omitted — or, inside a Field, the field's own label.

valueText

Defaults to (v: number, m: number) => `${Math.round(v * 10) / 10} of ${m}`

(value: number, max: number) => string

The spoken value. Defaults to "3.5 of 5".

name
string

Posts the value in a form under this name.

icon
Snippet

The icon, drawn twice — once unfilled, once filled and clipped. Paint it with currentColor and it takes both colours.

haptics

Defaults to true

boolean

A buzz when a value is chosen, once haptics.enabled is on.

onchange
(value: number) => void

Fires when a value is committed — a press, a lifted finger, a key.

class
string
classes
RatingClasses

Per-part Tailwind overrides. class still covers the root.

ref bindable

Defaults to null

HTMLDivElement | null