spb/cancerindex
Public
TypeScript 97.2%
SQL 1.5%
CSS 0.6%
JavaScript 0.5%
1import { fmtValue, unitLabel } from '@/lib/format';2import { SourceBadge, type ProvenanceInfo } from './source-badge';3import { ClaimBadge, type ClaimKind } from './badge';45/**6 * Every numeric value on the site renders through <Value>: number + unit, source badge with7 * provenance popover, and a population/period caption (CLAUDE.md UI rules).8 */9export function Value({10 value,11 unit,12 provenance,13 caption,14 claim,15 size = 'md',16 ci,17 estimateType,18 className = '',19}: {20 value: number | string | null | undefined;21 unit?: string | null;22 provenance?: ProvenanceInfo | null;23 caption?: string | null;24 claim?: ClaimKind;25 size?: 'sm' | 'md' | 'lg';26 ci?: [number | null | undefined, number | null | undefined];27 estimateType?: string | null;28 className?: string;29}) {30 const sizeCls = size === 'lg' ? 'text-2xl font-display' : size === 'sm' ? 'text-[13.5px]' : 'text-base';31 const hasCi = ci && ci[0] != null && ci[1] != null;32 return (33 <span className={`inline-flex flex-col items-start ${className}`}>34 <span className="inline-flex flex-wrap items-baseline gap-x-1.5 gap-y-0.5">35 <span className={`ci-num ${sizeCls} text-ink`}>{fmtValue(value, unit)}</span>36 {unit && unit !== 'probability' ? <span className="text-[11.5px] text-ink-3">{unitLabel(unit)}</span> : null}37 {hasCi ? (38 <span className="ci-num text-[11.5px] text-ink-3" title="95% confidence interval as published by the source">39 ({fmtValue(ci![0], unit)}–{fmtValue(ci![1], unit)})40 </span>41 ) : null}42 {estimateType && estimateType !== 'observed' ? <span className="text-[11px] italic text-warn">{estimateType}</span> : null}43 {provenance ? <SourceBadge p={provenance} /> : null}44 {claim ? <ClaimBadge kind={claim} /> : null}45 </span>46 {caption ? <span className="text-[11.5px] leading-4 text-ink-3">{caption}</span> : null}47 </span>48 );49}50