98 lines
2.6 KiB
TypeScript
98 lines
2.6 KiB
TypeScript
"use client";
|
|
|
|
import { HTMLAttributes } from "react";
|
|
|
|
interface ProgressBarProps extends HTMLAttributes<HTMLDivElement> {
|
|
value: number;
|
|
max: number;
|
|
variant?: "hp" | "xp" | "default";
|
|
showLabel?: boolean;
|
|
label?: string;
|
|
}
|
|
|
|
const getGradientStyle = (
|
|
variant: "hp" | "xp" | "default",
|
|
percentage: number
|
|
) => {
|
|
if (variant === "hp") {
|
|
if (percentage > 60) {
|
|
return {
|
|
background: `linear-gradient(to right, var(--success), color-mix(in srgb, var(--success) 90%, transparent))`,
|
|
};
|
|
} else if (percentage > 30) {
|
|
return {
|
|
background: `linear-gradient(to right, var(--yellow), color-mix(in srgb, var(--accent) 90%, transparent))`,
|
|
};
|
|
} else {
|
|
return {
|
|
background: `linear-gradient(to right, var(--destructive), color-mix(in srgb, var(--destructive) 90%, transparent))`,
|
|
};
|
|
}
|
|
} else {
|
|
return {
|
|
background: `linear-gradient(to right,
|
|
color-mix(in srgb, var(--accent-color) 80%, transparent),
|
|
color-mix(in srgb, var(--accent-color) 70%, transparent),
|
|
color-mix(in srgb, var(--accent-color) 80%, transparent)
|
|
)`,
|
|
};
|
|
}
|
|
};
|
|
|
|
export default function ProgressBar({
|
|
value,
|
|
max,
|
|
variant = "default",
|
|
showLabel = false,
|
|
label,
|
|
className = "",
|
|
...props
|
|
}: ProgressBarProps) {
|
|
const percentage = Math.min(100, Math.max(0, (value / max) * 100));
|
|
|
|
return (
|
|
<div className={className} {...props}>
|
|
{showLabel && (
|
|
<div
|
|
className="flex justify-between text-xs mb-1"
|
|
style={{ color: "var(--gray-400)" }}
|
|
>
|
|
<span>{label || variant.toUpperCase()}</span>
|
|
<span>
|
|
{value} / {max}
|
|
</span>
|
|
</div>
|
|
)}
|
|
<div
|
|
className="relative h-2 sm:h-3 border rounded overflow-hidden"
|
|
style={{
|
|
backgroundColor: "var(--gray-900)",
|
|
borderColor: "var(--gray-700)",
|
|
}}
|
|
>
|
|
<div
|
|
className="absolute inset-0 transition-all duration-1000 ease-out"
|
|
style={{
|
|
width: `${percentage}%`,
|
|
...getGradientStyle(variant, percentage),
|
|
}}
|
|
>
|
|
<div
|
|
className="absolute inset-0"
|
|
style={{
|
|
background:
|
|
"linear-gradient(to right, transparent, color-mix(in srgb, var(--foreground) 10%, transparent), transparent)",
|
|
}}
|
|
/>
|
|
</div>
|
|
{variant === "hp" && percentage < 30 && (
|
|
<div
|
|
className="absolute inset-0 border rounded animate-pulse"
|
|
style={{ borderColor: "var(--destructive)" }}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|