2024-05-23 08:18:54 +04:00

68 lines
2.0 KiB
TypeScript

interface ProgressBarProps {
percentages: number[];
colors?: string[];
textColors?: string[];
displayPercentage?: boolean;
}
export default function ProgressBar({
percentages,
colors,
textColors,
displayPercentage = true,
}: ProgressBarProps) {
if (!colors) {
colors = ["bg-green-300", "bg-yellow-400", "bg-orange-500", "bg-red-600"];
}
if (!textColors) {
textColors = ["text-black", "text-black", "text-white", "text-white"];
}
const getColor = (index: number) => {
return colors ? colors[index] || "bg-neutral-100" : "bg-neutral-100";
};
const getTextColor = (index: number) => textColors?.[index] || "text-black";
const sortedPercentages = [...percentages].sort((a, b) => b - a);
return (
<div className="relative">
<div
className={`absolute top-0 left-0 h-4 bg-neutral-50 border-2 border-neutral-100`}
style={{ width: `100%` }}
></div>
{sortedPercentages.map((percentage, index) => {
const spanleft =
100 -
(((percentage - sortedPercentages[index + 1]) / 2) * 100) /
percentage;
return (
<div
key={index}
className={`absolute top-0 left-0 h-4 ${getColor(index)} group`}
style={{ width: `${percentage}%` }}
>
{displayPercentage &&
percentage > 0 &&
(spanleft < 96 || isNaN(spanleft)) && (
<span
className={`absolute opacity-0 group-hover:opacity-100 transition-opacity duration-300 px-1 text-xs ${getTextColor(
index,
)}`}
style={{
left: `${
index === sortedPercentages.length - 1 ? 50 : spanleft
}%`,
transform: "translateX(-50%)",
whiteSpace: "nowrap",
}}
>
{percentage}%
</span>
)}
</div>
);
})}
</div>
);
}