Skip to content
TopClass UI

Rating

Read-only stars are server HTML and ship no script. Only an editable rating hydrates, as a group of native radios.

split - size not measured yet

Rating

split - size not measured yet

Read-only stars are server HTML and ship no script. Only an editable rating hydrates, as a group of native radios.

Install

Try it

value
max
size
readOnly
defaultValue
disabled

The code

rating.tsx
import { Rating } from 'topclassui/rating'
import type { RatingDesignProps } from 'topclassui/rating'

/** The site's Try it stage: each schema prop arrives from a control, and an absent one keeps its default. */
export default function Demo(props: RatingDesignProps = {}) {
  const { readOnly, defaultValue, disabled, ...shown } = props
  if (readOnly === false) {
    return <Rating defaultValue={defaultValue ?? 3} disabled={disabled} {...shown} readOnly={false} aria-label="Rate this course" />
  }
  return <Rating value={3.5} {...shown} />
}

value alone renders stars on the server; only readOnly={false} ships the client half.

Every state

6 states

Import from the package

topclassui/rating
import { Rating } from 'topclassui/rating'

Install once:npm i topclassui@beta zod

Examples

  • Read-only is the default: value is clamped to 0 and max and drawn to the nearest half star.
  • readOnly={false} renders native radios, one per star, named "1 star" to "5 stars".
  • With a name, the checked step, 1 to max, is submitted before any script runs. A form reset goes back to the served step and calls onValueChange.
  • value with onValueChange needs a 'use client' file: a server page cannot pass a function. defaultValue works from a server page.
  • max is 1 to 10, 5 by default. Ten xl stars are 436px, so on a phone the row wraps rather than scroll the page.
read-only

128 reviews

editable

Rate this course

in-form

How was your stay?

controlled

Chosen: 2 of 5

disabled
sizes
max-ten
In Arabic, right to left

قيّم هذه الدورة

Props

The props of Rating
PropTypeDefaultLimitsDescription
aria-labelstring--
aria-labelledbystring--
defaultValuenumber, min 0, max 100min 0, max 10Editing only: the step checked at first when value is not passed, rounded to a whole star. 0 checks none.
disabledbooleanfalse-Editing only: every radio is disabled, so it takes no key, no click and is not submitted.
labelsLabels--The built-in strings: labels.rating.value names a read-only rating, labels.rating.stars each step. Defaults to English.
localestring--The BCP 47 tag the numbers in those names are formatted in. Defaults to en.
maxinteger, min 1, max 105min 1, max 10How many stars, rounded and clamped to 1-10.
namestring--The field name in a form. Each radio submits its step, "1" to max. Without one the rating is in no form: not submitted, not reset.
readOnlybooleantrue-true renders stars on the server and ships no script. false renders a radio group, which hydrates.
sizexs | sm | md | lg | xl | custom"md"-The star, from the icon scale: 16, 20, 24, 32 or 40 px. custom draws it at 1em, so it follows your font size.
valuenumber, min 0, max 100min 0, max 10The rating shown, clamped to 0 and max. Read-only, it is drawn to the nearest half; editing, it is the checked step, and passing it makes the rating controlled.

Keyboard and accessibility

The keyboard of Rating
KeysWhat it does
TabEnters an editable rating on the checked star, or on the first when none is; the next Tab leaves.
ArrowRightArrowLeftArrowUpArrowDownMove between the stars and check the one reached.
SpaceChecks the focused star.
  • Read-only, it is one image named "4.5 out of 5"; pass aria-label to say more, as in "4.3 from 128 reviews".
  • Editable, the group needs aria-label or aria-labelledby. Each star is at least 24px to press, and 44px under a touch pointer.
  • A filled star is warning-on-soft, 3:1 or more on every surface; under forced colours a filled star stays solid and an empty one an outline.

Right to left

The first star is at the right, and half a star fills its right half. Pass the Arabic labels and locale for Arabic names.

Server and client

Renders on the server; the interactive part is a client component that ships only when it is used.

Files: index.tsx, client.tsx.

On the chip: split - size not measured yet.