File size: 1,687 Bytes
65d68f5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
59
60
61
"use client";

import { cn } from "@/lib/utils";

// =============================================================================
// CleanProgressBar — Thin black-on-gray progress bar
// =============================================================================

export interface CleanProgressBarProps {
  value: number; // 0–100
  max?: number;
  label?: string;
  showPercent?: boolean;
  size?: "sm" | "md";
  variant?: "default" | "success";
  className?: string;
}

export function CleanProgressBar({
  value,
  max = 100,
  label,
  showPercent = false,
  size = "sm",
  variant = "default",
  className,
}: CleanProgressBarProps) {
  const pct = Math.min(100, Math.max(0, (value / max) * 100));

  return (
    <div className={cn("flex flex-col gap-1.5", className)}>
      {(label || showPercent) && (
        <div className="flex items-center justify-between">
          {label && <span className="text-[12px] font-medium text-[#6B7280]">{label}</span>}
          {showPercent && (
            <span className="text-[12px] font-semibold text-[#111] tabular-nums">{Math.round(pct)}%</span>
          )}
        </div>
      )}
      <div
        className={cn(
          "w-full overflow-hidden rounded-full bg-[#E5E7EB]",
          size === "sm" ? "h-1.5" : "h-2.5",
        )}
        role="progressbar"
        aria-valuenow={value}
        aria-valuemin={0}
        aria-valuemax={max}
      >
        <div
          className={cn(
            "h-full rounded-full transition-all duration-500 ease-out",
            variant === "success" ? "bg-[#059669]" : "bg-[#111111]",
          )}
          style={{ width: `${pct}%` }}
        />
      </div>
    </div>
  );
}