Components

Rating

Headless slider-like rating input with fractional values and decorative item parts.

When to Use

Use Rating when a person chooses a score on a small ordered scale, such as one to five stars. Use Slider when the value is a general numeric setting like volume, and use RadioGroup when each choice has a different meaning rather than simply being more or less.

Features

  • Implements rating as a WAI-ARIA slider.
  • Supports controlled and uncontrolled values.
  • Supports fractional values with configurable step.
  • Supports pointer selection, drag updates, keyboard control, and click-to-clear.
  • Mirrors horizontal pointer and keyboard behavior in RTL direction.
  • Supports disabled, read-only, invalid, and required states.
  • Renders an optional hidden input for form submission.

Import

import { Rating } from "@flowstack-ui/atom";

Anatomy

<Rating.Root>
  <Rating.Item value={1} />
  <Rating.Item value={2} />
  <Rating.Item value={3} />
  <Rating.Item value={4} />
  <Rating.Item value={5} />
</Rating.Root>

API Reference

Root

Owns the numeric rating, form value, and slider semantics. It is the single focusable control; Item parts only provide pointer targets and visual state.

PropTypeDefault
valuenumber-
defaultValuenumbermin
onValueChange(value: number) => void-
minnumber0
maxnumber5
stepnumber1
largeStepnumbermin(step * 10, half range snapped to step)
disabledbooleanfalse
readOnlybooleanfalse
invalidbooleanfalse
requiredbooleanfalse
dir"ltr" | "rtl"Direction context
namestring-
formValuestringCurrent value
formstring-
aria-valuetextstring-
getValueLabel(value, min, max) => string-
tabIndexnumber0
onKeyDownKeyboardEventHandler<HTMLDivElement>-
asChildbooleanfalse
renderRenderProp-
ARIA attributeValues
role"slider"
aria-valueminNormalized min
aria-valuemaxNormalized max
aria-valuenowCurrent snapped value
aria-valuetextExplicit or generated rating label
aria-disabledtrue when disabled
aria-readonlytrue when read-only
aria-invalidtrue when invalid
aria-requiredtrue when required
Data attributeValues
[data-slot]"rating"
[data-value]Current value
[data-min]Minimum value
[data-max]Maximum value
[data-step]Step value
[data-disabled]Present when disabled
[data-readonly]Present when read-only
[data-invalid]Present when invalid
[data-required]Present when required

Item

Represents one point on the rating scale. It reports empty, partial, or full fill state and forwards pointer interaction to Root while remaining decorative to assistive technology.

PropTypeDefault
valuenumberrequired
onPointerDownPointerEventHandler<HTMLSpanElement>-
onPointerMovePointerEventHandler<HTMLSpanElement>-
onPointerUpPointerEventHandler<HTMLSpanElement>-
onPointerCancelPointerEventHandler<HTMLSpanElement>-
asChildbooleanfalse
renderRenderProp-
ARIA attributeValues
aria-hiddenAlways true; Root is the single slider control
Data attributeValues
[data-slot]"rating-item"
[data-value]Item value
[data-fill]Fill percentage from 0 to 100
[data-state]"empty" | "partial" | "full"
[data-disabled]Present when disabled
[data-readonly]Present when read-only
[data-invalid]Present when invalid

Advanced compound parts can read useRatingContext or use the exported RatingContextProvider. Public helpers normalizeRatingRange, clampRatingValue, snapRatingValue, getRatingValueLabel, and getRatingItemState expose the calculations used by Root and Item.

Examples

Whole Star Rating

import { Rating } from "@flowstack-ui/atom";

export default function WholeStarRating() {
  return (
    <Rating.Root defaultValue={3} aria-label="Rating">
      {[1, 2, 3, 4, 5].map((value) => (
        <Rating.Item key={value} value={value}>Star</Rating.Item>
      ))}
    </Rating.Root>
  );
}

Fractional Rating

import { Rating } from "@flowstack-ui/atom";

export default function FractionalRating() {
  return (
    <Rating.Root
      defaultValue={4.6}
      step={0.1}
      aria-label="Rating"
      getValueLabel={(value) => `${value} stars`}
    >
      {[1, 2, 3, 4, 5].map((value) => (
        <Rating.Item key={value} value={value}>Star</Rating.Item>
      ))}
    </Rating.Root>
  );
}

Form Value

import { Rating } from "@flowstack-ui/atom";

export default function ReviewRating() {
  return (
    <form>
      <Rating.Root name="rating" defaultValue={5} aria-label="Your rating">
        {[1, 2, 3, 4, 5].map((value) => (
          <Rating.Item key={value} value={value}>Star</Rating.Item>
        ))}
      </Rating.Root>
      <button type="submit">Submit review</button>
    </form>
  );
}

Accessibility

Rating follows the WAI-ARIA slider pattern so the whole control is one Tab stop. Items are decorative and hidden from assistive technology. Provide an accessible name on Root with aria-label or aria-labelledby.

KeyDescription
ArrowRight / ArrowUpIncreases value by step; ArrowRight decreases in RTL.
ArrowLeft / ArrowDownDecreases value by step; ArrowLeft increases in RTL.
PageUpIncreases value by largeStep.
PageDownDecreases value by largeStep.
HomeMoves value to min.
EndMoves value to max.

Changelog

See CHANGELOG.md.