72 lines
2.1 KiB
Plaintext
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>
|
|
|