dc78d8fea3
Componentes React reutilizables: card, dialog, tabs, select, alert, badge, button, input, label, skeleton, tooltip, progress_bar, page_header, form_field, settings_page, crud_page, analytics_page, dashboard_layout. Charts: area, bar, line, sparkline, kpi_card, chart_container. Hooks Wails: use_wails_query, use_wails_mutation, use_wails_stream, use_wails_event, use_animated_canvas. Funciones core: cn, format_compact, chart_colors, get_series_color, wails_cache, theme_config_to_colors. Tipos: chart_series, wails_ipc, theme_config, component_variants. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
69 lines
2.4 KiB
TypeScript
69 lines
2.4 KiB
TypeScript
import { cva, type VariantProps } from 'class-variance-authority'
|
|
import { cn } from '../core/cn'
|
|
|
|
const progressBarVariants = cva(
|
|
'relative w-full overflow-hidden rounded-full bg-muted',
|
|
{
|
|
variants: {
|
|
size: { sm: 'h-1', md: 'h-2', lg: 'h-3' },
|
|
color: {
|
|
primary: '[&_.progress-fill]:bg-primary',
|
|
success: '[&_.progress-fill]:bg-emerald-500',
|
|
warning: '[&_.progress-fill]:bg-amber-500',
|
|
destructive: '[&_.progress-fill]:bg-destructive',
|
|
},
|
|
},
|
|
defaultVariants: { size: 'md', color: 'primary' },
|
|
}
|
|
)
|
|
|
|
export interface ProgressBarProps extends VariantProps<typeof progressBarVariants> {
|
|
value: number
|
|
max?: number
|
|
buffer?: number
|
|
showValue?: boolean
|
|
animated?: boolean
|
|
indeterminate?: boolean
|
|
label?: string
|
|
className?: string
|
|
}
|
|
|
|
export function ProgressBar({
|
|
value, max = 100, buffer, showValue = false, animated = false,
|
|
indeterminate = false, size = 'md', color = 'primary', label, className,
|
|
}: ProgressBarProps) {
|
|
const percentage = Math.min(100, Math.max(0, (value / max) * 100))
|
|
const bufferPercentage = buffer ? Math.min(100, Math.max(0, (buffer / max) * 100)) : undefined
|
|
|
|
return (
|
|
<div
|
|
data-slot="progress-bar"
|
|
role="progressbar"
|
|
aria-valuenow={indeterminate ? undefined : value}
|
|
aria-valuemin={0}
|
|
aria-valuemax={max}
|
|
aria-label={label}
|
|
className={cn(progressBarVariants({ size, color }), className)}
|
|
>
|
|
{bufferPercentage !== undefined && (
|
|
<div className="progress-buffer absolute inset-0 bg-current opacity-20 transition-all duration-300" style={{ width: `${bufferPercentage}%` }} />
|
|
)}
|
|
<div
|
|
className={cn(
|
|
'progress-fill h-full transition-all duration-300',
|
|
animated && 'bg-[length:1rem_1rem] bg-[linear-gradient(45deg,rgba(255,255,255,.15)_25%,transparent_25%,transparent_50%,rgba(255,255,255,.15)_50%,rgba(255,255,255,.15)_75%,transparent_75%,transparent)] animate-[progress-stripes_1s_linear_infinite]',
|
|
indeterminate && 'w-1/3 animate-[progress-indeterminate_1.5s_ease-in-out_infinite]'
|
|
)}
|
|
style={indeterminate ? undefined : { width: `${percentage}%` }}
|
|
/>
|
|
{showValue && !indeterminate && (
|
|
<span className="absolute inset-0 flex items-center justify-center text-[10px] font-medium text-foreground mix-blend-difference">
|
|
{Math.round(percentage)}%
|
|
</span>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export { progressBarVariants }
|