feat: mejoras componentes UI — card variants, kpi_card slots, sparkline colors, bar_chart horizontal radius

- card: variantes default/borderless/ghost con ring condicional
- kpi_card: props unit, action, chart y delta con label/suffix personalizable
- sparkline: prop colors para colores por barra en variant bar
- bar_chart: radius condicional según orientación horizontal/vertical

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-02 15:32:35 +02:00
parent 1aaeec5090
commit aea2131dcb
8 changed files with 125 additions and 32 deletions
+5 -2
View File
@@ -7,6 +7,8 @@ interface SparklineProps extends React.SVGAttributes<SVGSVGElement> {
data: number[]
variant?: SparklineVariant
color?: string
/** Per-bar colors for 'bar' variant. Cycles if shorter than data. */
colors?: string[]
width?: number
height?: number
strokeWidth?: number
@@ -30,7 +32,7 @@ function getPath(data: number[], width: number, height: number, padding: number
}
const Sparkline = React.forwardRef<SVGSVGElement, SparklineProps>(
({ data, variant = 'line', color = 'currentColor', width = 80, height = 24, strokeWidth = 1.5, showLastPoint = true, className, ...props }, ref) => {
({ data, variant = 'line', color = 'currentColor', colors, width = 80, height = 24, strokeWidth = 1.5, showLastPoint = true, className, ...props }, ref) => {
if (data.length === 0) return <svg ref={ref} width={width} height={height} viewBox={`0 0 ${width} ${height}`} className={cn('text-primary', className)} {...props} />
if (variant === 'bar') {
@@ -46,7 +48,8 @@ const Sparkline = React.forwardRef<SVGSVGElement, SparklineProps>(
const bh = ((value - min) / range) * eh
const x = p + index * ((width - p * 2) / data.length) + 0.5
const y = p + eh - bh
return <rect key={index} x={x} y={y} width={Math.max(bw, 1)} height={Math.max(bh, 1)} fill={color} opacity={0.8} />
const barColor = colors ? colors[index % colors.length] : color
return <rect key={index} x={x} y={y} width={Math.max(bw, 1)} height={Math.max(bh, 1)} fill={barColor} rx={1} opacity={0.85} />
})}
</svg>
)