Feedback & Data Display
Status, signal, and the player board
The read-out layer of the system: badges and tags that call the state of play, avatars for the roster, loading skeletons and spinners for data in flight, a sortable broadcast table, and empty states that point the way forward.
6-8 UI
Player Board
Table, badges, avatars, tags, and skeletons composed into one broadcast read-out. Sort any stat column; refresh to watch the data stream back in.
| Player | Team | Streak | Status | |||
|---|---|---|---|---|---|---|
MB Marcus Bell#23 · G | Riptide | 28.4 | 5.1 | 7.8 | W6 | Live |
TV Theo Vance#7 · G | Summit | 24.9 | 3.8 | 6.4 | W4 | Active |
NA Nico Alvarez#9 · F | Vanguard | 22.1 | 6.7 | 4.3 | W3 | Live |
AC Andre Cole#4 · F | Riptide | 21.7 | 9.3 | 3.2 | L2 | Active |
KM Kai Monroe#12 · G | Ironworks | 19.6 | 4.1 | 8.9 | W1 | Active |
DF Devin Frost#11 · C | Summit | 18.2 | 11.6 | 1.9 | L1 | GTD |
JR Jalen Reed#30 · F | Ironworks | 15.3 | 7.2 | 2.5 | W2 | GTD |
SR Silas Rourke#45 · C | Vanguard | 12.8 | 12.4 | 1.4 | L3 | Out |
6-8 UI
Badges
Compact status pills in the broadcast HUD language. Seven intents, three sizes, an optional status dot, and a live variant that pulses on air.
6-8 UI
Tags
Removable filter and keyword pills. Click the X to dismiss; the roster filters above are the same component, live.
6-8 UI
Avatars
A Radix Avatar with a graceful initials fallback, sized sm through xl, with an optional luminous teal ring to flag starters.
6-8 UI
Loading States
Spinners for indeterminate waits and skeletons for content taking shape. Both respect reduced-motion preferences.
6-8 UI
Empty States
The zero-data view: a glowing icon medallion, a clear title, and copy that invites the next action rather than dead-ending.
No athletes match these filters
Nothing lines up with the current filter set. Widen a stat threshold or clear a filter to bring players back into the board.
6-8 UI
API
Props for the primitives on this page. Compose the exported cva variants when you need a one-off styling override.
Badge
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "teal" | "yellow" | "success" | "warning" | "danger" | "outline" | "default" | Intent color of the pill. |
| size | "sm" | "md" | "lg" | "md" | Padding and type scale. |
| dot | boolean | false | Show a status dot in the current color. |
| live | boolean | false | On-air state: pulsing broadcast dot and yellow glow. |
Table
| Prop | Type | Default | Description |
|---|---|---|---|
| Table | table + wrapperClassName | — | Scrollable glass panel wrapping the grid. |
| TableHead.sortable | boolean | false | Render an accessible sort toggle with a chevron. |
| TableHead.sortDirection | "asc" | "desc" | false | false | Current sort state for this column. |
| TableHead.onSort | () => void | — | Fired when the sort toggle is activated. |
| TableHead.align | "left" | "center" | "right" | "left" | Column alignment; also flips the sort layout. |
import { Badge } from "@/components/ui/badge";
import {
Table, TableHeader, TableBody,
TableRow, TableHead, TableCell,
} from "@/components/ui/table";
<Table>
<TableHeader>
<TableRow>
<TableHead>Player</TableHead>
<TableHead
align="right"
sortable
sortDirection={dir}
onSort={toggleSort}
>
Pts
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Marcus Bell</TableCell>
<TableCell className="text-right tabular-nums">28.4</TableCell>
</TableRow>
</TableBody>
</Table>
<Badge variant="yellow" live>Live</Badge>