# Rating Group

URL: https://ark-ui.com/docs/components/rating-group
LLM: https://ark-ui.com/llms.txt/components/rating-group

Allows users to rate items using a set of icons.

---



## Anatomy



```tsx
<RatingGroup.Root>
  <RatingGroup.Label />
  <RatingGroup.Control>
    <RatingGroup.Item>
      <RatingGroup.ItemContext />
    </RatingGroup.Item>
    <RatingGroup.HiddenInput />
  </RatingGroup.Control>
</RatingGroup.Root>
```

## Examples

```tsx
import { RatingGroup } from '@ark-ui/react/rating-group'
import { StarIcon } from 'lucide-react'
import styles from 'styles/rating-group.module.css'

export const Basic = () => (
  <RatingGroup.Root className={styles.Root} defaultValue={3}>
    <RatingGroup.Label className={styles.Label}>Label</RatingGroup.Label>
    <RatingGroup.Control className={styles.Control}>
      <RatingGroup.Context>
        {({ items }) =>
          items.map((item) => (
            <RatingGroup.Item className={styles.Item} key={item} index={item}>
              <RatingGroup.ItemContext>
                {({ highlighted }) => (
                  <span className={styles.ItemIndicator} data-highlighted={highlighted ? '' : undefined}>
                    <StarIcon data-bg="" />
                    <StarIcon data-fg="" fill="currentColor" />
                  </span>
                )}
              </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.

```tsx
import { RatingGroup } from '@ark-ui/react/rating-group'
import { StarIcon } from 'lucide-react'
import { useState } from 'react'
import styles from 'styles/rating-group.module.css'

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

  return (
    <RatingGroup.Root className={styles.Root} value={value} onValueChange={(details) => setValue(details.value)}>
      <RatingGroup.Label className={styles.Label}>Label</RatingGroup.Label>
      <RatingGroup.Control className={styles.Control}>
        <RatingGroup.Context>
          {({ items }) =>
            items.map((item) => (
              <RatingGroup.Item className={styles.Item} key={item} index={item}>
                <RatingGroup.ItemContext>
                  {({ half, highlighted }) => (
                    <span
                      className={styles.ItemIndicator}
                      data-half={half ? '' : undefined}
                      data-highlighted={highlighted ? '' : undefined}
                    >
                      <StarIcon data-bg="" />
                      <StarIcon data-fg="" fill="currentColor" />
                    </span>
                  )}
                </RatingGroup.ItemContext>
              </RatingGroup.Item>
            ))
          }
        </RatingGroup.Context>
        <RatingGroup.HiddenInput />
      </RatingGroup.Control>
    </RatingGroup.Root>
  )
}
```

### Root Provider

An alternative way to control the rating group is to use the `RootProvider` component and the `useRatingGroup` hook.
This way you can access the state and methods from outside the component.

```tsx
import { RatingGroup, useRatingGroup } from '@ark-ui/react/rating-group'
import { StarIcon } from 'lucide-react'
import styles from 'styles/rating-group.module.css'

export const RootProvider = () => {
  const ratingGroup = useRatingGroup({ count: 5, defaultValue: 3 })

  return (
    <div className="stack">
      <output>value: {ratingGroup.value}</output>
      <RatingGroup.RootProvider className={styles.Root} value={ratingGroup}>
        <RatingGroup.Label className={styles.Label}>Label</RatingGroup.Label>
        <RatingGroup.Control className={styles.Control}>
          <RatingGroup.Context>
            {({ items }) =>
              items.map((item) => (
                <RatingGroup.Item className={styles.Item} key={item} index={item}>
                  <RatingGroup.ItemContext>
                    {({ highlighted }) => (
                      <span className={styles.ItemIndicator} data-highlighted={highlighted ? '' : undefined}>
                        <StarIcon data-bg="" />
                        <StarIcon data-fg="" fill="currentColor" />
                      </span>
                    )}
                  </RatingGroup.ItemContext>
                </RatingGroup.Item>
              ))
            }
          </RatingGroup.Context>
          <RatingGroup.HiddenInput />
        </RatingGroup.Control>
      </RatingGroup.RootProvider>
    </div>
  )
}
```

### Field

The `Field` component helps manage form-related state and accessibility attributes of a rating group. It includes
handling ARIA labels, helper text, and error text to ensure proper accessibility.

```tsx
import { Field } from '@ark-ui/react/field'
import { RatingGroup } from '@ark-ui/react/rating-group'
import { StarIcon } from 'lucide-react'
import field from 'styles/field.module.css'
import styles from 'styles/rating-group.module.css'

export const WithField = () => (
  <Field.Root className={field.Root}>
    <RatingGroup.Root className={styles.Root} count={5} defaultValue={3}>
      <RatingGroup.Label className={styles.Label}>Label</RatingGroup.Label>
      <RatingGroup.Control className={styles.Control}>
        <RatingGroup.Context>
          {({ items }) =>
            items.map((item) => (
              <RatingGroup.Item className={styles.Item} key={item} index={item}>
                <RatingGroup.ItemContext>
                  {({ highlighted }) => (
                    <span className={styles.ItemIndicator} data-highlighted={highlighted ? '' : undefined}>
                      <StarIcon data-bg="" />
                      <StarIcon data-fg="" fill="currentColor" />
                    </span>
                  )}
                </RatingGroup.ItemContext>
              </RatingGroup.Item>
            ))
          }
        </RatingGroup.Context>
        <RatingGroup.HiddenInput />
      </RatingGroup.Control>
    </RatingGroup.Root>
    <Field.HelperText className={field.HelperText}>Additional Info</Field.HelperText>
    <Field.ErrorText className={field.ErrorText}>Error Info</Field.ErrorText>
  </Field.Root>
)
```

### Half Rating

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

```tsx
import { RatingGroup } from '@ark-ui/react/rating-group'
import { StarIcon } from 'lucide-react'
import styles from 'styles/rating-group.module.css'

export const HalfStar = () => (
  <RatingGroup.Root className={styles.Root} defaultValue={2.5} allowHalf>
    <RatingGroup.Label className={styles.Label}>Label</RatingGroup.Label>
    <RatingGroup.Control className={styles.Control}>
      <RatingGroup.Context>
        {({ items }) =>
          items.map((item) => (
            <RatingGroup.Item className={styles.Item} key={item} index={item}>
              <RatingGroup.ItemContext>
                {({ half, highlighted }) => (
                  <span
                    className={styles.ItemIndicator}
                    data-half={half ? '' : undefined}
                    data-highlighted={highlighted ? '' : undefined}
                  >
                    <StarIcon data-bg="" />
                    <StarIcon data-fg="" fill="currentColor" />
                  </span>
                )}
              </RatingGroup.ItemContext>
            </RatingGroup.Item>
          ))
        }
      </RatingGroup.Context>
      <RatingGroup.HiddenInput />
    </RatingGroup.Control>
  </RatingGroup.Root>
)
```

### 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.

```tsx
import { RatingGroup } from '@ark-ui/react/rating-group'
import { StarIcon } from 'lucide-react'
import styles from 'styles/rating-group.module.css'
import button from 'styles/button.module.css'

export const FormUsage = () => (
  <form
    className="stack"
    onSubmit={(e) => {
      e.preventDefault()
      const formData = new FormData(e.currentTarget)
      alert(`Rating value: ${formData.get('review')}`)
    }}
  >
    <RatingGroup.Root className={styles.Root} name="review" defaultValue={3}>
      <RatingGroup.Label className={styles.Label}>Label</RatingGroup.Label>
      <RatingGroup.Control className={styles.Control}>
        <RatingGroup.Context>
          {({ items }) =>
            items.map((item) => (
              <RatingGroup.Item className={styles.Item} key={item} index={item}>
                <RatingGroup.ItemContext>
                  {({ highlighted }) => (
                    <span className={styles.ItemIndicator} data-highlighted={highlighted ? '' : undefined}>
                      <StarIcon data-bg="" />
                      <StarIcon data-fg="" fill="currentColor" />
                    </span>
                  )}
                </RatingGroup.ItemContext>
              </RatingGroup.Item>
            ))
          }
        </RatingGroup.Context>
        <RatingGroup.HiddenInput />
      </RatingGroup.Control>
    </RatingGroup.Root>
    <button type="submit" className={button.Root}>
      Submit
    </button>
  </form>
)
```

### Disabled

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

```tsx
import { RatingGroup } from '@ark-ui/react/rating-group'
import { StarIcon } from 'lucide-react'
import styles from 'styles/rating-group.module.css'

export const Disabled = () => (
  <RatingGroup.Root className={styles.Root} defaultValue={3} disabled>
    <RatingGroup.Label className={styles.Label}>Label</RatingGroup.Label>
    <RatingGroup.Control className={styles.Control}>
      <RatingGroup.Context>
        {({ items }) =>
          items.map((item) => (
            <RatingGroup.Item className={styles.Item} key={item} index={item}>
              <RatingGroup.ItemContext>
                {({ highlighted }) => (
                  <span className={styles.ItemIndicator} data-highlighted={highlighted ? '' : undefined}>
                    <StarIcon data-bg="" />
                    <StarIcon data-fg="" fill="currentColor" />
                  </span>
                )}
              </RatingGroup.ItemContext>
            </RatingGroup.Item>
          ))
        }
      </RatingGroup.Context>
      <RatingGroup.HiddenInput />
    </RatingGroup.Control>
  </RatingGroup.Root>
)
```

## API Reference

### Props

### Root

#### Props

**`allowHalf`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether to allow half stars.

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

**`autoFocus`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether to autofocus the rating.

**`count`**
Type: `number`
Required: false
Default Value: `5`
Description: The total number of ratings.

**`defaultValue`**
Type: `number`
Required: false
Default Value: `undefined`
Description: The initial value of the rating when rendered.
Use when you don't need to control the value of the rating.

**`disabled`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the rating is disabled.

**`form`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The associate form of the underlying input element.

**`id`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The unique identifier of the machine.

**`ids`**
Type: `Partial<{
  root: string
  label: string
  hiddenInput: string
  control: string
  item: (id: string) => string
}>`
Required: false
Default Value: `undefined`
Description: The ids of the elements in the rating. Useful for composition.

**`name`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The name attribute of the rating element (used in forms).

**`onHoverChange`**
Type: `(details: HoverChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Function to be called when the rating value is hovered.

**`onValueChange`**
Type: `(details: ValueChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Function to be called when the rating value changes.

**`readOnly`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the rating is readonly.

**`required`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the rating is required.

**`translations`**
Type: `IntlTranslations`
Required: false
Default Value: `undefined`
Description: Specifies the localized strings that identifies the accessibility elements and their states

**`value`**
Type: `number`
Required: false
Default Value: `undefined`
Description: The controlled value of the rating

### Control

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: rating-group
**`data-part`**: control
**`data-readonly`**: Present when read-only
**`data-disabled`**: Present when disabled

### HiddenInput

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Item

#### Props

**`index`**
Type: `number`
Required: true
Default Value: `undefined`
Description: undefined

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`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

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: rating-group
**`data-part`**: label
**`data-disabled`**: Present when disabled
**`data-required`**: Present when required

### RootProvider

#### Props

**`value`**
Type: `UseRatingGroupReturn`
Required: true
Default Value: `undefined`
Description: undefined

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Context

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `setValue` | `(value: number) => void` | Sets the value of the rating group |
| `clearValue` | `VoidFunction` | Clears the value of the rating group |
| `hovering` | `boolean` | Whether the rating group is being hovered |
| `value` | `number` | The current value of the rating group |
| `hoveredValue` | `number` | The value of the currently hovered rating |
| `count` | `number` | The total number of ratings |
| `items` | `number[]` | The array of rating values. Returns an array of numbers from 1 to the max value. |
| `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a rating item |


## Accessibility

### Keyboard Support

**`ArrowRight`**
Description: Moves focus to the next star, increasing the rating value based on the `allowHalf` property.

**`ArrowLeft`**
Description: Moves focus to the previous star, decreasing the rating value based on the `allowHalf` property.

**`Enter`**
Description: Selects the focused star in the rating group.