import Badge from "@/components/ui/Badge"; import { fmt } from "@/lib/data"; import type { DatasetInfo } from "@/lib/types"; import HourBar from "./HourBar"; export interface SplitsTableProps { /** Frozen split inventory of a live dataset. */ splits: NonNullable; /** Dataset name for the accessible caption, e.g. "ViMedCSS". */ datasetName?: string; } const ROWS: ReadonlyArray<{ key: keyof NonNullable; name: string; tone: "muted" | "accent" | "accent-soft"; badge?: { label: string; variant: "accent" | "outline" }; role: string; }> = [ { key: "train", name: "Train", tone: "muted", role: "Adaptation corpus — Track C systems may train on this split and nothing else.", }, { key: "valid", name: "Valid", tone: "muted", role: "Hyperparameter tuning and checkpoint selection. Never reported as a result.", }, { key: "test", name: "Test", tone: "accent", badge: { label: "Primary", variant: "accent" }, role: "The primary leaderboard — every headline number on the home page is scored here.", }, { key: "hard", name: "Hard", tone: "accent-soft", badge: { label: "Generalization", variant: "outline" }, role: "Rare and unseen terms, disjoint from Train — the generalization leaderboard.", }, ]; /** Dataset split table with proportional hour-bars and role captions. */ export default function SplitsTable({ splits, datasetName }: SplitsTableProps) { const totalHours = ROWS.reduce((sum, r) => sum + splits[r.key].hours, 0); return (
{ROWS.map((row, i) => { const s = splits[row.key]; const share = s.hours / totalHours; return ( ); })}
{datasetName ?? "Dataset"} splits: hours, utterances, share of total audio, and the role of each split
Split Hours Utterances Share of audio Role
{row.name} {row.badge && ( {row.badge.label} )} {fmt(s.hours)} h {s.utts.toLocaleString("en-US")}
{(share * 100).toFixed(1)}%
{row.role}
); }