Rating

A rating, readable or settable, drawn with monochrome marks. The icon is a prop; read-only renders one image with a text alternative — "4 out of 5" — rather than five separate announcements.

src/components/ui/rating.tsx

About

From the component's own source, where it was written.

A rating, readable or settable.

Read-only mode renders a single img with a text alternative rather than a row of interactive elements — "4 out of 5" is what a reader needs, not five separate announcements. Interactive mode is a radio group, which is exactly what picking one of five mutually exclusive values is.

Hover preview is a colour change only; nothing grows or moves, in line with the rest of the kit.

Marks are monochrome: filled is the foreground colour, empty is an outline. A rating is a quantity, not a status, and colouring it amber makes it read as a warning next to components where amber means exactly that.

icon takes a component, not an element, because each mark is drawn twice — once as the outline and once clipped for the fill. An element could only be rendered once, so a half value would have nothing to clip.

Half values are supported for display by clipping the icon, not by rendering a second half-filled glyph — that keeps a 3.5 aligned with a 3 on the grid.

Install

npx astralyx-ui add rating

Usage

import { Rating } from '@/components/ui/rating'

<Rating value={rating} onValueChange={setRating} />
<Rating value={4.5} readOnly showValue />

Composer

Change the props and the source below follows.

Props
tsx
<Rating
  value={rating}
  onValueChange={setRating}
  icon={Hexagon}
  readOnly={false}
  showValue={false}
/>

Examples

Icons and states

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

Rating

A rating, readable or settable.

Extends Omit<ComponentProps<'div'>, 'defaultValue' | 'onChange'>.

PropTypeDefaultDescription
valuenumber—Clicking the current value clears it back to zero.
defaultValuenumber0—
onValueChange(value: number) => void—Clicking the current value clears it back to zero.
countnumber5Number of marks.
readOnlybooleanfalseSwitches from a radio group to a single labelled image.
iconComponentType<{ className?: string }>HexagonThe mark — any lucide icon or your own SVG component. A component, not an element: each mark renders twice, once as the outline and once clipped for the fill, so an element would leave a half value with nothing to clip.
size'sm' | 'default' | 'lg''default'—
labelstring'Rating'—
showValuebooleanfalse—
valuesdisplay—Rendered by clipping the icon rather than a second half-filled glyph, so 3.5 stays aligned with 3 on the same grid.