import type { ReactNode } from "react"; export type BadgeVariant = | "success" | "warning" | "danger" | "info" | "neutral"; export type BadgeSize = "sm" | "md"; export interface BadgeProps { variant: BadgeVariant; size?: BadgeSize; icon?: ReactNode; children: ReactNode; } const VARIANT_STYLES: Record< BadgeVariant, { background: string; color: string; border: string } > = { success: { background: "var(--success-soft)", color: "var(--success)", border: "transparent", }, warning: { background: "var(--warn-soft)", color: "var(--warn)", border: "transparent", }, danger: { background: "var(--danger-soft)", color: "var(--danger)", border: "transparent", }, info: { background: "var(--accent-soft)", color: "var(--accent)", border: "transparent", }, neutral: { background: "var(--bg-card-alt)", color: "var(--fg-secondary)", border: "var(--border-card)", }, }; const SIZE_STYLES: Record< BadgeSize, { fontSize: number; padding: string; gap: number } > = { sm: { fontSize: 11, padding: "2px 6px", gap: 3 }, md: { fontSize: 12, padding: "3px 8px", gap: 4 }, }; /** * Badge — inline-flex semantic badge with variants aligned to design tokens. * Variants: success | warning | danger | info | neutral. * Icon slot accepts any ReactNode (use Lucide icons, size 12-14px). */ export function Badge({ variant, size = "md", icon, children }: BadgeProps) { const vs = VARIANT_STYLES[variant]; const ss = SIZE_STYLES[size]; return ( {icon && ( {icon} )} {children} ); }