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;