Rating
Used to show reviews and ratings in a visual format.
import { RatingGroup } from "@chakra-ui/react"
const Demo = () => {
return (
<RatingGroup.Root count={5} defaultValue={3} size="sm">
<RatingGroup.HiddenInput />
<RatingGroup.Control />
</RatingGroup.Root>
)
}
Usage
import { RatingGroup } from "@chakra-ui/react"<RatingGroup.Root>
<RatingGroup.Label />
<RatingGroup.HiddenInput />
<RatingGroup.Control>
<RatingGroup.Item>
<RatingGroup.ItemIndicator />
</RatingGroup.Item>
</RatingGroup.Control>
</RatingGroup.Root>Shortcuts
The Rating component also provides a set of shortcuts for common use cases.
RatingControl
This component renders the number of rating items specified in the count prop.
This works:
<RatingGroup.Control>
{Array.from({ length: 5 }).map((_, index) => (
<RatingGroup.Item key={index} index={index + 1}>
<RatingGroup.ItemIndicator />
</RatingGroup.Item>
))}
</RatingGroup.Control>This might be more concise, if you don't need to customize the rating icons:
<RatingGroup.Control />Examples
Basic
import { RatingGroup } from "@chakra-ui/react"
const Demo = () => {
return (
<RatingGroup.Root count={5} defaultValue={3} size="sm">
<RatingGroup.HiddenInput />
<RatingGroup.Control />
</RatingGroup.Root>
)
}
Sizes
Use the size prop to change the size of the rating component.
import { For, RatingGroup, Stack } from "@chakra-ui/react"
const Demo = () => {
return (
<Stack>
<For each={["xs", "sm", "md", "lg"]}>
{(size) => (
<RatingGroup.Root key={size} count={5} defaultValue={3} size={size}>
<RatingGroup.HiddenInput />
<RatingGroup.Control />
</RatingGroup.Root>
)}
</For>
</Stack>
)
}
Controlled
Use the value and onValueChange prop to control the rating value.
"use client"
import { RatingGroup } from "@chakra-ui/react"
import { useState } from "react"
const Demo = () => {
const [value, setValue] = useState(3)
return (
<RatingGroup.Root
count={5}
value={value}
onValueChange={(e) => setValue(e.value)}
>
<RatingGroup.HiddenInput />
<RatingGroup.Control />
</RatingGroup.Root>
)
}
Store
An alternative way to control the rating is to use the RootProvider component
and the useRatingGroup store hook.
This way you can access the rating state and methods from outside the component.
"use client"
import { RatingGroup, useRatingGroup } from "@chakra-ui/react"
const Demo = () => {
const store = useRatingGroup({ count: 5, defaultValue: 3 })
return (
<RatingGroup.RootProvider value={store} size="sm">
<RatingGroup.HiddenInput />
<RatingGroup.Control />
</RatingGroup.RootProvider>
)
}
ReadOnly
Use the readOnly prop to make the rating component read-only.
import { RatingGroup } from "@chakra-ui/react"
const Demo = () => {
return (
<RatingGroup.Root readOnly count={5} defaultValue={3} size="sm">
<RatingGroup.HiddenInput />
<RatingGroup.Control />
</RatingGroup.Root>
)
}
Hook Form
Here's an example of how to use rating with react-hook-form.
"use client"
import { Button, Field, RatingGroup, Stack } from "@chakra-ui/react"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
import { Controller, useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
rating: z.number({ message: "Rating is required" }).min(1).max(5),
})
type FormValues = z.infer<typeof formSchema>
const Demo = () => {
const {
handleSubmit,
formState: { errors },
control,
} = useForm<FormValues>({
resolver: standardSchemaResolver(formSchema),
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
<form onSubmit={onSubmit}>
<Stack gap="4" align="flex-start">
<Field.Root invalid={!!errors.rating}>
<Field.Label>Rating</Field.Label>
<Controller
control={control}
name="rating"
render={({ field }) => (
<RatingGroup.Root
count={5}
name={field.name}
value={field.value}
onValueChange={({ value }) => field.onChange(value)}
>
<RatingGroup.HiddenInput />
<RatingGroup.Control />
</RatingGroup.Root>
)}
/>
<Field.ErrorText>{errors.rating?.message}</Field.ErrorText>
</Field.Root>
<Button size="sm" type="submit">
Submit
</Button>
</Stack>
</form>
)
}
Custom Icon
Use the icon prop to pass a custom icon to the rating component. This will
override the default star icon.
import { RatingGroup } from "@chakra-ui/react"
import { IoHeart } from "react-icons/io5"
const Demo = () => {
return (
<RatingGroup.Root count={5} defaultValue={4} colorPalette="red">
<RatingGroup.HiddenInput />
<RatingGroup.Control>
{Array.from({ length: 5 }).map((_, index) => (
<RatingGroup.Item key={index} index={index + 1}>
<RatingGroup.ItemIndicator icon={<IoHeart />} />
</RatingGroup.Item>
))}
</RatingGroup.Control>
</RatingGroup.Root>
)
}
Label
Render the RatingGroup.Label component to provide a human-readable label for
the rating component.
import { RatingGroup } from "@chakra-ui/react"
const Demo = () => {
return (
<RatingGroup.Root count={5} defaultValue={3} size="sm" gap="4">
<RatingGroup.HiddenInput />
<RatingGroup.Label>Rating</RatingGroup.Label>
<RatingGroup.Control />
</RatingGroup.Root>
)
}
Half Star
Use the allowHalf prop to allow half-star ratings.
import { RatingGroup } from "@chakra-ui/react"
const Demo = () => {
return (
<RatingGroup.Root allowHalf count={5} defaultValue={3.5} size="sm">
<RatingGroup.HiddenInput />
<RatingGroup.Control />
</RatingGroup.Root>
)
}
Emoji
Compose the rating component with emojis.
import { RatingGroup } from "@chakra-ui/react"
const emojiMap: Record<string, string> = {
1: "😡",
2: "😠",
3: "😐",
4: "😊",
5: "😍",
}
const Demo = () => {
return (
<RatingGroup.Root count={5} defaultValue={3}>
<RatingGroup.Control>
{Array.from({ length: 5 }).map((_, index) => (
<RatingGroup.Item
key={index}
index={index + 1}
minW="9"
filter={{ base: "grayscale(1)", _checked: "revert" }}
transition="scale 0.1s"
_hover={{ scale: "1.1" }}
>
{emojiMap[index + 1]}
</RatingGroup.Item>
))}
</RatingGroup.Control>
</RatingGroup.Root>
)
}
Colors
Use the colorPalette prop to change the color of the rating
gray
red
green
blue
teal
pink
purple
cyan
orange
yellow
import { RatingGroup, Stack, Text } from "@chakra-ui/react"
import { colorPalettes } from "compositions/lib/color-palettes"
const Demo = () => {
return (
<Stack gap="2" align="flex-start">
{colorPalettes.map((colorPalette) => (
<Stack
align="center"
key={colorPalette}
direction="row"
gap="10"
px="4"
>
<Text minW="8ch">{colorPalette}</Text>
<RatingGroup.Root
count={5}
defaultValue={3}
size="sm"
colorPalette={colorPalette}
>
<RatingGroup.HiddenInput />
<RatingGroup.Control />
</RatingGroup.Root>
</Stack>
))}
</Stack>
)
}
Testimonial
Use the rating component to show testimonials.
Sage is a great software engineer. He is very professional and knowledgeable.

Matthew Jones
CTO, Company
import { Avatar, HStack, RatingGroup, Stack, Text } from "@chakra-ui/react"
const Demo = () => {
return (
<Stack maxW="320px" gap="4">
<RatingGroup.Root
colorPalette="orange"
readOnly
count={5}
defaultValue={5}
size="xs"
>
<RatingGroup.HiddenInput />
<RatingGroup.Control />
</RatingGroup.Root>
<Text>
Sage is a great software engineer. He is very professional and
knowledgeable.
</Text>
<HStack gap="4">
<Avatar.Root>
<Avatar.Fallback name="Matthew Jones" />
<Avatar.Image src="https://randomuser.me/api/portraits/men/70.jpg" />
</Avatar.Root>
<Stack textStyle="sm" gap="0">
<Text fontWeight="medium">Matthew Jones</Text>
<Text color="fg.muted">CTO, Company</Text>
</Stack>
</HStack>
</Stack>
)
}
Closed Component
Here's how to setup the Rating for a closed component composition.
import { RatingGroup } from "@chakra-ui/react"
import * as React from "react"
export interface RatingProps extends RatingGroup.RootProps {
icon?: React.ReactElement
count?: number
label?: React.ReactNode
}
export const Rating = React.forwardRef<HTMLDivElement, RatingProps>(
function Rating(props, ref) {
const { icon, count = 5, label, ...rest } = props
return (
<RatingGroup.Root ref={ref} count={count} {...rest}>
{label && <RatingGroup.Label>{label}</RatingGroup.Label>}
<RatingGroup.HiddenInput />
<RatingGroup.Control>
{Array.from({ length: count }).map((_, index) => (
<RatingGroup.Item key={index} index={index + 1}>
<RatingGroup.ItemIndicator icon={icon} />
</RatingGroup.Item>
))}
</RatingGroup.Control>
</RatingGroup.Root>
)
},
)
Here's how to use the it
<Rating defaultValue={3} size="sm" />Props
Root
| Prop | Default | Type |
|---|---|---|
count | '5' | numberThe total number of ratings. |
colorPalette | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink'The color palette of the component |
size | 'md' | 'xs' | 'sm' | 'md' | 'lg'The size of the component |
as | React.ElementTypeThe underlying element to render. | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
unstyled | booleanWhether to remove the component's style. | |
allowHalf | booleanWhether to allow half stars. | |
autoFocus | booleanWhether to autofocus the rating. | |
defaultValue | numberThe initial value of the rating when rendered. Use when you don't need to control the value of the rating. | |
disabled | booleanWhether the rating is disabled. | |
form | stringThe associate form of the underlying input element. | |
id | stringThe unique identifier of the machine. | |
ids | Partial<{
root: string
label: string
hiddenInput: string
control: string
item: (id: string) => string
}>The ids of the elements in the rating. Useful for composition. | |
name | stringThe name attribute of the rating element (used in forms). | |
onHoverChange | (details: HoverChangeDetails) => voidFunction to be called when the rating value is hovered. | |
onValueChange | (details: ValueChangeDetails) => voidFunction to be called when the rating value changes. | |
readOnly | booleanWhether the rating is readonly. | |
required | booleanWhether the rating is required. | |
translations | IntlTranslationsSpecifies the localized strings that identifies the accessibility elements and their states | |
value | numberThe controlled value of the rating |
Item
| Prop | Default | Type |
|---|---|---|
index * | number | |
as | React.ElementTypeThe underlying element to render. | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |