import React from 'react'; import { cn } from '../copilot/cn'; // The cells sit on the divider colour, so the 1px grid gap *is* the divider. export const StatStrip = ({ children, }: { children: React.ReactNode; }): JSX.Element => (
{children}
); interface StatCellProps { label: string; value: React.ReactNode; /** Suffix glued to the value at a smaller size (``/100``, ``%``). */ unit?: string; /** Signed change vs the previous week (already formatted). */ delta?: string | null; deltaTone?: 'positive' | 'negative' | 'idle'; note?: React.ReactNode; /** Slot for an ``InfoTooltip`` next to the label. */ action?: React.ReactNode; /** Colours the value itself, for a figure that is good or bad on its own. */ valueClassName?: string; /** * Drops the value to a size that suits a phrase rather than a bare numeral. * "43" reads well at display size; "7 up · 3 down" at that size shouts. */ compact?: boolean; } const NOTE_FIGURE = /(\d[\d.,]*\s?%?)/g; const IS_FIGURE = /^\d/; const DELTA_COLOR: Record<'positive' | 'negative' | 'idle', string> = { positive: 'text-emerald-600', negative: 'text-red-600', idle: 'text-gray-500', }; // A footnote like "of 100 · mentioned in 15 of 16 prompts" carries three // numbers a merchant reads and eight words of scaffolding; at one muted grey // they all weigh the same. const emphasiseFigures = (text: string): React.ReactNode[] => text.split(NOTE_FIGURE).map((part, index) => IS_FIGURE.test(part) ? ( {part} ) : ( part ) ); export const StatCell = ({ label, value, unit, delta = null, deltaTone = 'idle', note, action, valueClassName, compact = false, }: StatCellProps): JSX.Element => (
{label} {action}
{value} {unit && ( {unit} )} {delta && ( {delta} )}
{note && (
{typeof note === 'string' ? emphasiseFigures(note) : note}
)}
); export default StatStrip;