|Kit

Rating

Fixed-count star rating on top of Ark UI's RatingGroup machine — half-star precision, sizes, colors, and custom symbols, with the full keyboard / ARIA model handled upstream.

Rating renders a fixed-count row of symbols — a bundled star by default — and wires up Ark UI's RatingGroup machine: click-to-set, drag-hover preview, ←/→ / Home / End keyboard navigation, and the roving-tabindex role="radio" group all come for free.

import { Rating } from '@42-central/ui-react/rating';

<Rating defaultValue={3} />

Playground

Component

Loading preview

Props

Code

<Component count={5} size="md" />

Count

count sets the total number of symbols (default 5).

Code

<Rating count={3} defaultValue={2} />
<Rating count={10} defaultValue={6} />

Half stars

Pass allowHalf for half-symbol precision — a click (or an arrow key) can land on a half value. This is Ark's own half-star support only; arbitrary fractional precision is out of scope.

Sizes

Five sizes — xs through xl — matching the rest of the family.

Code

<Rating size="xs" defaultValue={3} />
<Rating size="sm" defaultValue={3} />
<Rating size="md" defaultValue={3} />
<Rating size="lg" defaultValue={3} />
<Rating size="xl" defaultValue={3} />

Colors

The filled portion of each symbol rides the kit's data-color + --c-solid slot-var system — the same recipe as Slider's track fill. Unset, it falls back to the neutral black/white default.

brand
neutral
red
orange
yellow
green
teal
cyan
blue
purple
pink

Code

import { COLORS } from '@42-central/ui-react';

{COLORS.map((c) => (
  <Rating key={c} color={c} defaultValue={4} />
))}

Per-star colors

color also accepts (index: number) => Color, called once per symbol with its 0-based position — every star resolves its own color independently instead of sharing one for the whole group. A mood scale is the classic case: red for a poor rating, green for a great one.

Code

const moodColors: Color[] = ['red', 'orange', 'yellow', 'teal', 'green'];

<Rating count={5} defaultValue={4} color={(index) => moodColors[index]} />

Custom symbols

Override fullSymbol / emptySymbol to replace the bundled star with anything else — an emoji, an icon from your own set, whatever fits. Half-fill still works: whichever nodes you pass are layered and clipped the same way as the default star.

Code

<Rating
  allowHalf
  defaultValue={3.5}
  fullSymbol={<span>❤️</span>}
  emptySymbol={<span className="opacity-25">🤍</span>}
/>

Highlight selected only

By default every symbol up to the hovered/selected value fills in — the usual "N out of count" look (Ark's highlighted state). Pass highlightSelectedOnly to fill just the exact selected value's symbol instead (Ark's checked state) — useful for a single-choice "pick a size" style row rather than a magnitude rating.

Controlled

onChange hands you the next rating value directly (a value, not a DOM event).

'use client';
import { useState } from 'react';
import { Rating } from '@42-central/ui-react/rating';

export function CourseRating() {
  const [value, setValue] = useState(0);
  return <Rating value={value} onChange={setValue} />;
}

Read-only & disabled

readOnly keeps full contrast and stays announced to assistive tech but rejects changes. disabled dims the control and blocks all interaction.

Code

<Rating readOnly defaultValue={4} />
<Rating disabled defaultValue={2} />

Field integration

Rating has no built-in label / description / error — it's a bare control (like Calendar). Wrap it in Field and the label, description, error, and aria-* relationships wire up onto the real role="radiogroup" control:

<Field label="Rate this course" description="1 star = poor, 5 stars = excellent">
  <Rating />
</Field>
1 star = poor, 5 stars = excellent

Code

<Field label="Rate this course" description="1 star = poor, 5 stars = excellent">
  <Rating />
</Field>

Forms

name (and form) wire the group into native <form> submission and FormData via a hidden input — no controlled state required.

Code

<form action={save}>
  <Rating name="rating" defaultValue={4} />
</form>

API

Prop

Type

All other props are forwarded to the underlying Ark RatingGroup.Root.

Accessibility

  • Full keyboard model from Ark: ← / → step by one symbol (or half, with allowHalf), Home / End jump to the minimum / maximum, Space sets the value when none is set yet.
  • Each symbol is role="radio" in a role="radiogroup", with a roving tabindex — Tab reaches the group once, arrows move within it.
  • aria-label on each symbol names its value (translations.ratingValueText); aria-checked / aria-posinset / aria-setsize are wired by Ark.
  • A hidden <input> backs form submission — pass name to include it.
  • RTL is honored via the document dir: hover/click position and the half-symbol clip both mirror automatically.

Changelog

v0.19.0
  • These entry points ship "use client", so a Server Component can import them

    #320
v0.18.0
  • asChild is a compile error on CircularProgress, Progress, Rating, Slider, Divider, Field, InputBase and PillsInput

    #294
v0.11.0
  • Palette-tinted focus rings draw from --c-text

    #161
v0.8.0
  • New Rating component on Ark UI's RatingGroup, with per-star colors and hover animations

    #117

On this page