import * as React from 'react' import { cn } from '../core/cn' type KPICardSize = 'sm' | 'default' | 'lg' interface Delta { value: number isPositive: boolean /** Descriptive label before value, e.g. "Increased by" */ label?: string /** Suffix after value, e.g. "vs yesterday" */ suffix?: string } interface KPICardProps extends React.HTMLAttributes { label: string value: string | number /** Unit displayed next to value in smaller font, e.g. "k", "ms", "%" */ unit?: string delta?: Delta icon?: React.ReactNode /** Action slot rendered top-right, e.g. a menu button */ action?: React.ReactNode /** Inline chart slot rendered to the right of the value */ chart?: React.ReactNode subtitle?: string size?: KPICardSize } const sizeStyles: Record = { sm: { value: 'text-2xl font-bold', unit: 'text-base font-medium', label: 'text-xs' }, default: { value: 'text-3xl font-bold', unit: 'text-lg font-medium', label: 'text-sm' }, lg: { value: 'text-4xl font-bold', unit: 'text-xl font-medium', label: 'text-base' }, } const KPICard = React.forwardRef( ({ label, value, unit, delta, icon, action, chart, subtitle, size = 'default', className, ...props }, ref) => { const styles = sizeStyles[size] const deltaColor = delta ? delta.value === 0 ? 'text-muted-foreground' : delta.isPositive ? 'text-green-600 dark:text-green-500' : 'text-red-600 dark:text-red-500' : '' return (
{icon &&
{icon}
}

{label}

{subtitle &&

{subtitle}

}
{action &&
{action}
}
{value} {unit && {unit}}
{delta && (
{delta.label && {delta.label}} {delta.isPositive ? '▲' : '▼'} {delta.value > 0 ? '+' : ''}{delta.value}{delta.label ? '' : '%'} {delta.suffix && {delta.suffix}}
)}
{chart &&
{chart}
}
) } ) KPICard.displayName = 'KPICard' export { KPICard } export type { KPICardProps, Delta, KPICardSize }