Rating

Form

Star rating selector with hover preview.

Preview

Rate your experience

Usage

example.jsx
import { Rating } from "@/components/ui/rating";

export default function Example() {
  return <Rating />;
}

Source Code

Copy this file into components/ui/rating.jsx in your project.

rating.jsx
"use client";

import { forwardRef } from "react";
import { cn } from "@/lib/utils";

const Rating = forwardRef(({ className, value = 0, onValueChange, max = 5, ...props }, ref) => {
  return (
    <div ref={ref} className={cn("flex items-center gap-0.5", className)} {...props}>
      {Array.from({ length: max }).map((_, i) => (
        <button
          key={i}
          type="button"
          onClick={() => onValueChange?.(i + 1)}
          className="cursor-pointer p-0.5 transition-colors hover:scale-110 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded"
        >
          <svg
            xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"
            fill={i < value ? "currentColor" : "none"}
            stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
            className={cn(i < value ? "text-yellow-500" : "text-muted-foreground/40")}
          >
            <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
          </svg>
        </button>
      ))}
    </div>
  );
});
Rating.displayName = "Rating";

export { Rating };

Quick Install

Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.

npm install clsx tailwind-merge