feat: funciones frontend React/TS — componentes UI, hooks Wails, charts y tipos
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>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
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 }
|
||||
Reference in New Issue
Block a user