Spaces:
Sleeping
Sleeping
| type LoadingBarProps = { | |
| active: boolean; | |
| progress?: number | null; | |
| label?: string; | |
| className?: string; | |
| }; | |
| function clampProgress(value: number): number { | |
| if (Number.isNaN(value)) return 0; | |
| if (value < 0) return 0; | |
| if (value > 100) return 100; | |
| return value; | |
| } | |
| export function LoadingBar({ | |
| active, | |
| progress = null, | |
| label, | |
| className = "", | |
| }: LoadingBarProps) { | |
| if (!active) return null; | |
| const numericProgress = typeof progress === "number" ? clampProgress(progress) : null; | |
| return ( | |
| <div className={className}> | |
| {label ? ( | |
| <div className="mb-1 text-xs font-medium text-gray-600"> | |
| {label} | |
| {numericProgress !== null ? ` (${Math.round(numericProgress)}%)` : ""} | |
| </div> | |
| ) : null} | |
| <div | |
| role="progressbar" | |
| aria-valuemin={0} | |
| aria-valuemax={100} | |
| aria-valuenow={numericProgress ?? undefined} | |
| className="h-2 w-full overflow-hidden rounded-full bg-gray-200" | |
| > | |
| <div | |
| className={[ | |
| "h-full rounded-full bg-blue-600", | |
| numericProgress === null ? "w-2/5 animate-pulse" : "transition-all duration-200", | |
| ].join(" ")} | |
| style={numericProgress === null ? undefined : { width: `${numericProgress}%` }} | |
| /> | |
| </div> | |
| </div> | |
| ); | |
| } | |