Files
road-monitoring-ui/src/components/ui/stepper.tsx

71 lines
2.4 KiB
TypeScript

import * as React from 'react';
import { Check } from 'lucide-react';
import { cn } from '@/lib/utils';
interface StepperProps {
steps: {
title: string;
description?: string;
}[];
activeStep: number;
className?: string;
}
export function Stepper({ steps, activeStep, className }: StepperProps) {
return (
<div className={cn('w-full', className)}>
<div className="relative flex justify-between">
{/* Connection Lines */}
<div className="absolute top-5 left-0 right-0 h-0.5 bg-muted -z-10" />
<div
className="absolute top-5 left-0 h-0.5 bg-primary transition-all duration-500 -z-10"
style={{ width: `${(activeStep / (steps.length - 1)) * 100}%` }}
/>
{steps.map((step, index) => {
const isActive = index === activeStep;
const isCompleted = index < activeStep;
const isPending = index > activeStep;
return (
<div key={step.title} className="flex flex-col items-center flex-1">
<div
className={cn(
'w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold transition-all duration-300 border-2',
isActive
? 'bg-primary border-primary text-primary-foreground ring-4 ring-primary/10 scale-110'
: isCompleted
? 'bg-primary border-primary text-primary-foreground'
: 'bg-background border-muted text-muted-foreground',
)}
>
{isCompleted ? (
<Check className="h-5 w-5" />
) : (
<span>{index + 1}</span>
)}
</div>
<div className="mt-4 text-center px-2">
<p
className={cn(
'text-sm font-bold transition-colors',
isActive ? 'text-foreground' : 'text-muted-foreground',
)}
>
{step.title}
</p>
{step.description && (
<p className="text-[11px] text-muted-foreground mt-1 line-clamp-1 max-w-[120px] mx-auto hidden md:block">
{step.description}
</p>
)}
</div>
</div>
);
})}
</div>
</div>
);
}