/* StatusBadge — small rounded pill carrying a status / category label. * * Driven by lib/status-registry.ts: callers either pass an explicit * { variantClass, label } pair (the shape returned by registry helpers * like priorityBadge / ticketStatusBadge / classificationBadge), or pass * a `tone` and `children` for one-off semantic states. * * Visual: rounded-sm to match the geometric brand direction, no border, * tinted background carries the weight. */ import { cn } from '@/lib/utils'; import { TONE_CLASS, type StatusTone, type BadgeProps as RegistryBadge, } from '@/lib/status-registry'; interface BaseProps { size?: 'xs' | 'sm'; className?: string; children?: React.ReactNode; } interface ToneVariantProps extends BaseProps { /** Semantic state when no registry entry exists (children is the label). */ tone: StatusTone; variantClass?: never; label?: never; } interface PassthroughVariantProps extends BaseProps, RegistryBadge { /** Spread the result of a registry helper directly. */ tone?: never; } interface CustomVariantProps extends BaseProps { /** Free-form variant class (e.g. one of PALETTE_CLASS values). */ variantClass: string; tone?: never; label?: string; } type StatusBadgeProps = ToneVariantProps | PassthroughVariantProps | CustomVariantProps; const SIZE_CLASS = { xs: 'text-[10px] leading-4 px-1.5 py-px', sm: 'text-xs leading-4 px-2 py-0.5', } as const; export function StatusBadge(props: StatusBadgeProps) { const { size = 'sm', className, children } = props; let tint: string; let body: React.ReactNode = children ?? null; if ('tone' in props && props.tone) { tint = TONE_CLASS[props.tone]; } else { tint = props.variantClass; if (!body && 'label' in props && props.label) body = props.label; } return ( {body} ); }