73 lines
2.4 KiB
TypeScript
73 lines
2.4 KiB
TypeScript
import React from 'react';
|
|
import { Check } from 'lucide-react';
|
|
|
|
interface Step {
|
|
label: string;
|
|
description?: string;
|
|
}
|
|
|
|
interface StepperProps {
|
|
steps: Step[];
|
|
currentStep: number;
|
|
}
|
|
|
|
const Stepper: React.FC<StepperProps> = ({ steps, currentStep }) => {
|
|
return (
|
|
<div className="w-full py-4">
|
|
<div className="flex items-start justify-between w-full">
|
|
{steps.map((step, index) => {
|
|
const isCompleted = index < currentStep;
|
|
const isActive = index === currentStep;
|
|
const isPending = index > currentStep;
|
|
|
|
return (
|
|
<div key={index} className="relative flex flex-col items-center flex-1">
|
|
{/* Connector Line */}
|
|
{index !== steps.length - 1 && (
|
|
<div
|
|
className={`absolute top-5 left-1/2 w-full h-0.5 transition-colors duration-300 ${
|
|
isCompleted ? 'bg-green-500' : 'bg-gray-200'
|
|
}`}
|
|
style={{ left: '50%' }}
|
|
/>
|
|
)}
|
|
|
|
{/* Step Circle */}
|
|
<div
|
|
className={`relative z-10 flex items-center justify-center w-10 h-10 rounded-full border-2 transition-all duration-300 ${
|
|
isCompleted
|
|
? 'bg-green-500 border-green-500 text-white'
|
|
: isActive
|
|
? 'bg-white border-blue-600 text-blue-600 ring-4 ring-blue-50'
|
|
: 'bg-white border-gray-300 text-gray-400'
|
|
}`}
|
|
>
|
|
{isCompleted ? (
|
|
<Check className="w-6 h-6" strokeWidth={3} />
|
|
) : (
|
|
<span className="text-sm font-semibold">{index + 1}</span>
|
|
)}
|
|
</div>
|
|
|
|
{/* Labels */}
|
|
<div className="mt-3 text-center px-2">
|
|
<p className={`text-sm font-medium transition-colors duration-300 ${
|
|
isActive ? 'text-blue-600' : isCompleted ? 'text-green-600' : 'text-gray-500'
|
|
}`}>
|
|
{step.label}
|
|
</p>
|
|
{step.description && (
|
|
<p className="text-xs text-gray-400 mt-1 max-w-[120px] mx-auto">
|
|
{step.description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Stepper; |