Ark Logo

Rating Group

Allows users to rate items using a set of icons.

Star IconStar IconStar IconStar IconStar Icon

Anatomy

To set up the rating correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Examples

Learn how to use the RatingGroup component in your project. Let's take a look at the most basic example:

import { StarIcon } from 'lucide-react'
import { RatingGroup } from '@ark-ui/react'

export const Basic = () => (
  <RatingGroup.Root count={5} defaultValue={3}>
    <RatingGroup.Label>Label</RatingGroup.Label>
    <RatingGroup.Control>
      <RatingGroup.Context>
        {({ items }) =>
          items.map((item) => (
            <RatingGroup.Item key={item} index={item}>
              <RatingGroup.ItemContext>
                {({ highlighted }) => (highlighted ? <StarIcon fill="current" /> : <StarIcon />)}
              </RatingGroup.ItemContext>
            </RatingGroup.Item>
          ))
        }
      </RatingGroup.Context>
      <RatingGroup.HiddenInput />
    </RatingGroup.Control>
  </RatingGroup.Root>
)

Using half ratings

Allow 0.5 value steps by setting the allowHalf prop to true. Ensure to render the correct icon if the isHalf value is set in the Rating components render callback.

import { StarHalfIcon, StarIcon } from 'lucide-react'
import { RatingGroup } from '@ark-ui/react'

export const HalfRatings = () => (
  <RatingGroup.Root count={5} defaultValue={3} allowHalf>
    <RatingGroup.Label>Label</RatingGroup.Label>
    <RatingGroup.Control>
      <RatingGroup.Context>
        {({ items }) =>
          items.map((item) => (
            <RatingGroup.Item key={item} index={item}>
              <RatingGroup.ItemContext>
                {({ half, highlighted }) => {
                  if (half) return <StarHalfIcon fill="current" />
                  if (highlighted) return <StarIcon fill="current" />
                  return <StarIcon />
                }}
              </RatingGroup.ItemContext>
            </RatingGroup.Item>
          ))
        }
      </RatingGroup.Context>
      <RatingGroup.HiddenInput />
    </RatingGroup.Control>
  </RatingGroup.Root>
)

Using a default value

import { StarIcon } from 'lucide-react'
import { RatingGroup } from '@ark-ui/react'

export const InitialValue = () => (
  <RatingGroup.Root count={5} defaultValue={2} readOnly>
    <RatingGroup.Label>Label</RatingGroup.Label>
    <RatingGroup.Control>
      <RatingGroup.Context>
        {({ items }) =>
          items.map((item) => (
            <RatingGroup.Item key={item} index={item}>
              <RatingGroup.ItemContext>
                {({ highlighted }) => (highlighted ? <StarIcon fill="current" /> : <StarIcon />)}
              </RatingGroup.ItemContext>
            </RatingGroup.Item>
          ))
        }
      </RatingGroup.Context>
      <RatingGroup.HiddenInput />
    </RatingGroup.Control>
  </RatingGroup.Root>
)

Controlled

When using the RatingGroup component, you can use the value and onValueChange props to control the state.

import { StarIcon } from 'lucide-react'
import { useState } from 'react'
import { RatingGroup } from '@ark-ui/react'

export const Controlled = () => {
  const [value, setValue] = useState(0)

  return (
    <RatingGroup.Root
      count={5}
      value={value}
      onValueChange={(details) => setValue(details.value)}
      allowHalf
    >
      <RatingGroup.Label>Label</RatingGroup.Label>
      <RatingGroup.Control>
        <RatingGroup.Context>
          {({ items }) =>
            items.map((item) => (
              <RatingGroup.Item key={item} index={item}>
                <RatingGroup.ItemContext>
                  {({ highlighted }) => (highlighted ? <StarIcon fill="current" /> : <StarIcon />)}
                </RatingGroup.ItemContext>
              </RatingGroup.Item>
            ))
          }
        </RatingGroup.Context>
        <RatingGroup.HiddenInput />
      </RatingGroup.Control>
    </RatingGroup.Root>
  )
}

Disabling the rating group

To make the rating group disabled, set the disabled prop to true.

import { StarIcon } from 'lucide-react'
import { RatingGroup } from '@ark-ui/react'

export const Disabled = () => (
  <RatingGroup.Root count={5} defaultValue={3} disabled>
    <RatingGroup.Label>Label</RatingGroup.Label>
    <RatingGroup.Control>
      <RatingGroup.Context>
        {({ items }) =>
          items.map((item) => (
            <RatingGroup.Item key={item} index={item}>
              <RatingGroup.ItemContext>
                {({ highlighted }) => (highlighted ? <StarIcon fill="current" /> : <StarIcon />)}
              </RatingGroup.ItemContext>
            </RatingGroup.Item>
          ))
        }
      </RatingGroup.Context>
      <RatingGroup.HiddenInput />
    </RatingGroup.Control>
  </RatingGroup.Root>
)

Readonly rating group

To make the rating group readonly, set the readOnly prop to true.

import { StarIcon } from 'lucide-react'
import { RatingGroup } from '@ark-ui/react'

export const ReadOnly = () => (
  <RatingGroup.Root count={5} defaultValue={3} readOnly>
    <RatingGroup.Label>Label</RatingGroup.Label>
    <RatingGroup.Control>
      <RatingGroup.Context>
        {({ items }) =>
          items.map((item) => (
            <RatingGroup.Item key={item} index={item}>
              <RatingGroup.ItemContext>
                {({ highlighted }) => (highlighted ? <StarIcon fill="currrent" /> : <StarIcon />)}
              </RatingGroup.ItemContext>
            </RatingGroup.Item>
          ))
        }
      </RatingGroup.Context>
      <RatingGroup.HiddenInput />
    </RatingGroup.Control>
  </RatingGroup.Root>
)

Usage within forms

To use the rating group within forms, pass the prop name. It will render a hidden input and ensure the value changes get propagated to the form correctly.

import { StarIcon } from 'lucide-react'
import { RatingGroup } from '@ark-ui/react'

export const FormUsage = () => (
  <RatingGroup.Root name="my-rating" count={5} defaultValue={3}>
    <RatingGroup.Label>Label</RatingGroup.Label>
    <RatingGroup.Control>
      <RatingGroup.Context>
        {({ items }) =>
          items.map((item) => (
            <RatingGroup.Item key={item} index={item}>
              <RatingGroup.ItemContext>
                {({ highlighted }) => (highlighted ? <StarIcon fill="current" /> : <StarIcon />)}
              </RatingGroup.ItemContext>
            </RatingGroup.Item>
          ))
        }
      </RatingGroup.Context>
      <RatingGroup.HiddenInput />
    </RatingGroup.Control>
  </RatingGroup.Root>
)

API Reference

Root

PropDefaultType
allowHalf
boolean

Whether to allow half stars.

asChild
boolean

Render as a different element type.

autoFocus
boolean

Whether to autofocus the rating.

count5
number

The total number of ratings.

defaultValue
number

The initial value of the rating group when it is first rendered. Use when you do not need to control the state of the rating group.

disabled
boolean

Whether the rating is disabled.

form
string

The associate form of the underlying input element.

id
string

The unique identifier of the machine.

ids
Partial<{ root: string label: string hiddenInput: string control: string rating(id: string): string }>

The ids of the elements in the rating. Useful for composition.

name
string

The name attribute of the rating element (used in forms).

onHoverChange
(details: HoverChangeDetails) => void

Function to be called when the rating value is hovered.

onValueChange
(details: ValueChangeDetails) => void

Function to be called when the rating value changes.

readOnly
boolean

Whether the rating is readonly.

translations
IntlTranslations

Specifies the localized strings that identifies the accessibility elements and their states

value
number

The current rating value.

Control

PropDefaultType
asChild
boolean

Render as a different element type.

Data AttributeValue
[data-scope]rating-group
[data-part]control
[data-readonly]Present when read-only
[data-disabled]Present when disabled

HiddenInput

PropDefaultType
asChild
boolean

Render as a different element type.

Item

PropDefaultType
index
number

asChild
boolean

Render as a different element type.

Data AttributeValue
[data-scope]rating-group
[data-part]item
[data-disabled]Present when disabled
[data-readonly]Present when read-only
[data-checked]Present when checked
[data-highlighted]Present when highlighted
[data-half]

Label

PropDefaultType
asChild
boolean

Render as a different element type.

Data AttributeValue
[data-scope]rating-group
[data-part]label
[data-disabled]Present when disabled

Accessibility

Keyboard Support

KeyDescription
ArrowRight
Moves focus to the next star, increasing the rating value based on the `allowHalf` property.
ArrowLeft
Moves focus to the previous star, decreasing the rating value based on the `allowHalf` property.
Enter
Selects the focused star in the rating group.