Files
website/astro/src/components/web/subcomponents/StarRating.astro
2026-03-25 22:14:32 +01:00

72 lines
2.1 KiB
Plaintext

---
interface Props {
stars: number;
size: "big" | "small";
}
function roundToCustomHalf(value: number) {
const whole = Math.floor(value);
const decimal = value - whole;
if (decimal < 0.25) return whole;
if (decimal < 0.75) return whole + 0.5;
return whole + 1;
}
const stars = roundToCustomHalf(Astro.props.stars);
const totalStars = 5;
---
<div class="flex flex-row gap-[4.25px]">
{Array.from({ length: totalStars }).map((_, i) => {
const starValue = i + 1;
let type = "empty";
if (stars >= starValue) {
type = "full";
} else if (stars >= starValue - 0.5) {
type = "half";
}
return (
<svg width={Astro.props.size === "big" ? 32 : 20} height={Astro.props.size === "big" ? 32 : 20} viewBox="3 0 24 24">
{type === "full" && (
<path
fill="gold"
d="M12 2l3.09 6.26L22 9.27l-5 4.87L18.18 22
12 18.56 5.82 22 7 14.14 2 9.27
8.91 8.26 12 2z"
/>
)}
{type === "half" && (
<>
<defs>
<linearGradient id={`half-${i}`}>
<stop offset="50%" stop-color="gold" />
<stop offset="50%" stop-color="lightgray" />
</linearGradient>
</defs>
<path
fill={`url(#half-${i})`}
d="M12 2l3.09 6.26L22 9.27l-5 4.87L18.18 22
12 18.56 5.82 22 7 14.14 2 9.27
8.91 8.26 12 2z"
/>
</>
)}
{type === "empty" && (
<path
fill="lightgray"
d="M12 2l3.09 6.26L22 9.27l-5 4.87L18.18 22
12 18.56 5.82 22 7 14.14 2 9.27
8.91 8.26 12 2z"
/>
)}
</svg>
);
})}
</div>