2026-02-06 23:01:30 -05:00

62 lines
1.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react';
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export type ProgressColor = 'indigo' | 'emerald';
export interface ProgressBarProps {
percent?: number; // 0100, ignored in indeterminate mode
color?: ProgressColor;
indeterminate?: boolean;
className?: string;
height?: 'sm' | 'md' | 'lg';
}
const colorMap: Record<ProgressColor, string> = {
indigo: 'bg-indigo-500',
emerald: 'bg-emerald-500',
};
const heightMap: Record<string, string> = {
sm: 'h-1',
md: 'h-2',
lg: 'h-3',
};
export const ProgressBar: React.FC<ProgressBarProps> = ({
percent = 0,
color = 'indigo',
indeterminate = false,
className,
height = 'md',
}) => {
const clamped = Math.max(0, Math.min(100, percent));
return (
<div
role="progressbar"
aria-valuenow={indeterminate ? undefined : clamped}
aria-valuemin={0}
aria-valuemax={100}
className={twMerge(
clsx(
'w-full rounded-full overflow-hidden bg-gray-800',
heightMap[height],
),
className,
)}
>
<div
className={clsx(
'h-full rounded-full transition-all duration-500 ease-out',
colorMap[color],
indeterminate && 'animate-[indeterminate_1.5s_ease-in-out_infinite] w-1/3',
)}
style={indeterminate ? undefined : { width: `${clamped}%` }}
/>
</div>
);
};
ProgressBar.displayName = 'ProgressBar';