File size: 1,462 Bytes
88da18c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | import React from 'react';
import { motion } from 'framer-motion';
import { cn } from '@/utils/helpers';
interface ProgressBarProps extends React.HTMLAttributes<HTMLDivElement> {
value: number;
max?: number;
showLabel?: boolean;
variant?: 'primary' | 'success' | 'warning' | 'error';
animated?: boolean;
}
const ProgressBar = React.forwardRef<HTMLDivElement, ProgressBarProps>(
(
{
value,
max = 100,
showLabel = true,
variant = 'primary',
animated = true,
className,
...props
},
ref
) => {
const percentage = Math.min((value / max) * 100, 100);
const variants = {
primary: 'bg-gradient-emerald',
success: 'bg-green-500',
warning: 'bg-yellow-500',
error: 'bg-red-500',
};
return (
<div ref={ref} className={cn('w-full', className)} {...props}>
<div className="bg-slate-800 rounded-full h-2 overflow-hidden border border-slate-700">
<motion.div
initial={{ width: 0 }}
animate={{ width: `${percentage}%` }}
transition={{ duration: 0.5, ease: 'easeOut' }}
className={cn(variants[variant], animated && 'animate-pulse-glow')}
/>
</div>
{showLabel && (
<p className="text-xs text-slate-400 mt-2">
{value} / {max}
</p>
)}
</div>
);
}
);
ProgressBar.displayName = 'ProgressBar';
export default ProgressBar;
|