/**
* Stacked stat column: label / value / delta. The delta slot is always rendered
* (a muted "—" placeholder when there is no change) so that every row reserves the
* same vertical space and the columns line up across the standings table.
*/
export function StatColumn({
label,
value,
delta,
reserveDelta = false,
}: {
label: string;
value: React.ReactNode;
/** Optional change indicator rendered on its own line below the value. */
delta?: React.ReactNode;
/**
* When true, the delta line is always rendered (a muted placeholder when there is
* no delta) so columns stay vertically aligned across rows. When false and no delta
* is provided, the line is omitted entirely.
*/
reserveDelta?: boolean;
}) {
const showDeltaLine = delta !== undefined || reserveDelta;
return (
{label}
{value}
{showDeltaLine && (
{delta ?? —}
)}
);
}
export function StatDivider({ className = "h-12" }: { className?: string } = {}) {
return ;
}
/**
* 7-day change indicator. `rank` deltas are unitless places; `points` deltas are
* rounded point totals. Positive = up (green ▲), negative = down (coral ▼).
*/
export function DeltaBadge({
delta,
kind,
}: {
delta: number;
kind: "rank" | "points";
}) {
const magnitude = kind === "rank" ? Math.abs(delta) : Math.abs(Math.round(delta));
const up = delta > 0;
const label =
kind === "rank"
? up
? `up ${magnitude}`
: `down ${magnitude}`
: up
? `+${magnitude} points`
: `-${magnitude} points`;
if (up) {
return (
▲{magnitude}
);
}
return (
▼{magnitude}
);
}
export function RankingDisplay({
displayRank,
rankChange,
reserveDelta = false,
}: {
displayRank: string | number;
rankChange?: number;
reserveDelta?: boolean;
}) {
return (
{displayRank}}
delta={
rankChange !== undefined && rankChange !== 0 ? (
) : undefined
}
/>
);
}