Rating
Star rating component with interactive and read-only modes. Supports custom max value and sizes.
3 / 5
import { Rating } from "@/components/ui/rating";
const [value, setValue] = useState(3);
<Rating value={value} onChange={setValue} />Installation
npx @aniui/cli add ratingSizes
★★★★★
★★★★★
★★★★★
<Rating size="sm" value={3} readOnly />
<Rating size="md" value={3} readOnly />
<Rating size="lg" value={3} readOnly />Read-Only
Use readOnly to display a non-interactive rating. Use max to customize the number of stars.
★★★★★
★★★★★★★★★★
<Rating value={4} readOnly />
<Rating value={2} max={10} readOnly />Props
PropTypeDefault
valuenumber—maxnumber5onChange(value: number) => void—readOnlybooleanfalsesize"sm" | "md" | "lg""md"classNamestring—Source
components/ui/rating.tsx
import React from "react";
import { View, Pressable, Text } from "react-native";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const ratingVariants = cva("flex-row items-center", {
variants: {
size: {
sm: "gap-0.5",
md: "gap-1",
lg: "gap-1.5",
},
},
defaultVariants: { size: "md" },
});
const starSizes = { sm: "text-base", md: "text-xl", lg: "text-2xl" } as const;
export interface RatingProps
extends React.ComponentPropsWithoutRef<typeof View>,
VariantProps<typeof ratingVariants> {
className?: string;
value: number;
max?: number;
onChange?: (value: number) => void;
readOnly?: boolean;
}
export function Rating({ size, className, value, max = 5, onChange, readOnly, ...props }: RatingProps) {
const s = size ?? "md";
return (
<View className={cn(ratingVariants({ size }), className)} accessibilityRole="adjustable" accessibilityValue={{ min: 0, max, now: value }} {...props}>
{Array.from({ length: max }, (_, i) => {
const filled = i < value;
const star = (
<Text className={cn(starSizes[s], filled ? "text-yellow-400" : "text-muted-foreground/30")}>★</Text>
);
return readOnly ? (
<View key={i}>{star}</View>
) : (
<Pressable key={i} onPress={() => onChange?.(i + 1)} accessible={true} accessibilityRole="button" accessibilityLabel={`${i + 1} star`}>
{star}
</Pressable>
);
})}
</View>
);
}