Add Button, Card, Table, Badge, Modal, Drawer, Toast, Skeleton, Toggle, Timeline, SearchBox — all using CSS variables from tokens.css with className prop extension and exported Props interfaces. Co-Authored-By: Claude <noreply@anthropic.com>
65 lines
1.6 KiB
TypeScript
65 lines
1.6 KiB
TypeScript
export interface CardProps {
|
|
label: string
|
|
value: string | number
|
|
valueColor?: 'green' | 'red' | 'yellow' | 'blue'
|
|
change?: string
|
|
changeDirection?: 'up' | 'down' | 'neutral'
|
|
onClick?: () => void
|
|
className?: string
|
|
}
|
|
|
|
const valueColorMap: Record<string, string> = {
|
|
green: 'var(--green)',
|
|
red: 'var(--red)',
|
|
yellow: 'var(--yellow)',
|
|
blue: 'var(--blue)',
|
|
}
|
|
|
|
const directionIcon: Record<string, string> = {
|
|
up: '↑',
|
|
down: '↓',
|
|
neutral: '→',
|
|
}
|
|
|
|
const directionColor: Record<string, string> = {
|
|
up: 'var(--green)',
|
|
down: 'var(--red)',
|
|
neutral: 'var(--text-dim)',
|
|
}
|
|
|
|
export default function Card({
|
|
label,
|
|
value,
|
|
valueColor,
|
|
change,
|
|
changeDirection,
|
|
onClick,
|
|
className = '',
|
|
}: CardProps) {
|
|
return (
|
|
<div
|
|
onClick={onClick}
|
|
className={`bg-[var(--bg-card)] rounded-[var(--radius)] p-4 ${onClick ? 'cursor-pointer hover:bg-[var(--bg-hover)]' : ''} transition-colors duration-150 ${className}`}
|
|
>
|
|
<div className="text-[12px] uppercase tracking-wider text-[var(--text-dim)]">
|
|
{label}
|
|
</div>
|
|
<div
|
|
className="text-[28px] font-bold leading-tight mt-1"
|
|
style={{ color: valueColor ? valueColorMap[valueColor] : undefined }}
|
|
>
|
|
{value}
|
|
</div>
|
|
{change !== undefined && changeDirection && (
|
|
<div
|
|
className="text-[12px] mt-1 flex items-center gap-1"
|
|
style={{ color: directionColor[changeDirection] }}
|
|
>
|
|
<span>{directionIcon[changeDirection]}</span>
|
|
<span>{change}</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|