Rating Input

Interactive star rating with hover preview and selection.

Forms & Inputratingstarsinputreviewfeedback

Dependencies

Other dependencies:

@/components/ui/card

How to use this component

Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.

Code

1"use client";
2
3import { useState } from 'react';
4import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
5import { Star } from 'lucide-react';
6
7const ratingLabels: Record<number, string> = {
8 1: 'Poor',
9 2: 'Fair',
10 3: 'Good',
11 4: 'Very Good',
12 5: 'Excellent'
13};
14
15export default function RatingInput() {
16 const [rating, setRating] = useState(0);
17 const [hoverRating, setHoverRating] = useState(0);
18 const [comment, setComment] = useState('');
19
20 return (
21 <Card className="w-full max-w-md mx-auto">
22 <CardHeader>
23 <CardTitle>Rate your experience</CardTitle>
24 </CardHeader>
25 <CardContent className="space-y-6">
26 <div className="flex flex-col items-center space-y-4">
27 <div className="flex gap-1">
28 {[1, 2, 3, 4, 5].map((star) => (
29 <button
30 key={star}
31 type="button"
32 className="transition-transform hover:scale-110"
33 onMouseEnter={() => setHoverRating(star)}
34 onMouseLeave={() => setHoverRating(0)}
35 onClick={() => setRating(star)}
36 >
37 <Star
38 className={`w-10 h-10 \` +
39 `${(hoverRating || rating) >= star ? 'fill-amber-400 text-amber-400' : 'text-gray-300'}`}
40 />
41 </button>
42 ))}
43 </div>
44
45 {rating > 0 && (
46 <p className="text-lg font-medium text-amber-600">
47 {ratingLabels[rating]}
48 </p>
49 )}
50
51 {rating > 0 && (
52 <p className="text-sm text-muted-foreground">
53 {rating} out of 5 stars
54 </p>
55 )}
56 </div>
57
58 <div className="space-y-2">
59 <label htmlFor="comment" className="text-sm font-medium">
60 Optional Review
61 </label>
62 <textarea
63 id="comment"
64 value={comment}
65 onChange={e => setComment(e.target.value)}
66 placeholder="Tell us more about your experience..."
67 className="flex min-h-[100px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 resize-none"
68 />
69 </div>
70
71 <button
72 type="button"
73 disabled={rating === 0}
74 className="w-full bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2 rounded-md font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
75 onClick={() => alert(`Rating: ${rating} stars\nComment: ${comment}`)}
76 >
77 Submit Review
78 </button>
79 </CardContent>
80 </Card>
81 );
82}

Related Forms & Input Components

Command Palette

Search for a command to run...