Files
got-gaming/components/ui/StarRating.tsx
Julien Froidefond 6d1e3daebb
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m19s
Add Footer component to layout and remove StyleGuidePage
2025-12-12 17:10:19 +01:00

80 lines
2.0 KiB
TypeScript

"use client";
import { useState } from "react";
interface StarRatingProps {
value: number;
onChange?: (rating: number) => void;
disabled?: boolean;
size?: "sm" | "md" | "lg";
showValue?: boolean;
}
const sizeClasses = {
sm: "text-lg sm:text-xl",
md: "text-2xl sm:text-3xl",
lg: "text-4xl",
};
export default function StarRating({
value,
onChange,
disabled = false,
size = "md",
showValue = false,
}: StarRatingProps) {
const [hoverValue, setHoverValue] = useState(0);
const handleClick = (rating: number) => {
if (!disabled && onChange) {
onChange(rating);
}
};
const displayValue = hoverValue || value;
return (
<div className="flex flex-col items-center gap-2">
<div className="flex items-center justify-center gap-2">
{[1, 2, 3, 4, 5].map((star) => (
<button
key={star}
type="button"
onClick={() => handleClick(star)}
disabled={disabled}
onMouseEnter={(e) => {
if (!disabled) {
setHoverValue(star);
if (star > displayValue) {
e.currentTarget.style.color = "var(--gray-400)";
}
}
}}
onMouseLeave={(e) => {
if (!disabled) {
setHoverValue(0);
if (star > displayValue) {
e.currentTarget.style.color = "var(--gray-500)";
}
}
}}
className={`transition-transform hover:scale-110 disabled:hover:scale-100 disabled:cursor-not-allowed ${sizeClasses[size]}`}
style={{
color: star <= displayValue ? "var(--accent-color)" : "var(--gray-500)",
}}
aria-label={`Noter ${star} étoile${star > 1 ? "s" : ""}`}
>
</button>
))}
</div>
{showValue && value > 0 && (
<p className="text-gray-500 text-xs text-center">
{value}/5
</p>
)}
</div>
);
}