Stats List
Generic home/away match stats comparison bars, one row per stat, sport-agnostic.
"use client"import { MatchHighlight } from "@/registry/mrdoge-ui/match-highlight/match-highlight"import { matchToMatchHighlightProps } from "@/lib/mrdoge-adapters/match-highlight"import { StatsList, StatsListSkeleton } from "@/registry/mrdoge-ui/stats-list/stats-list"import { statsToStatsListEntries } from "@/lib/mrdoge-adapters/stats-list"import { useLiveMatch } from "@/registry/mrdoge-ui/use-live-match/use-live-match"import { useSharedLiveOrCompletedMatchId } from "@/components/docs/demos/use-shared-demo-matches"export function StatsListDemo() { const matchId = useSharedLiveOrCompletedMatchId() const match = useLiveMatch({ matchId }) if (match === null) { return <p className="text-sm text-fd-muted-foreground">Couldn't load this match right now.</p> } const entries = match ? statsToStatsListEntries(match.stats) : [] return ( <div className="flex w-full max-w-sm flex-col gap-3"> {match === undefined ? <MatchHighlight loading /> : <MatchHighlight {...matchToMatchHighlightProps(match)} />} {match === undefined ? ( <StatsListSkeleton /> ) : entries.length === 0 ? ( <p className="text-sm text-fd-muted-foreground">No stats reported for this match's sport yet.</p> ) : ( <StatsList entries={entries} /> )} </div> )}Coverage varies by sport
Which stats show up depends entirely on what the data source reports.
See the adapter below for
exactly what each sport contributes today. Stats List itself renders
nothing for an empty entries array; decide what "no stats" should
look like at the call site, same as
Match Timeline with an empty
list.
Installation
pnpm dlx shadcn@latest add https://mrdoge.co/r/stats-list.jsonUsage
import { StatsList } from "@/components/stats-list"
<StatsList
entries={[
{ label: "Possession", home: "62%", away: "38%", homeValue: 0.62, awayValue: 0.38 },
{ label: "Shots", home: "14", away: "9", homeValue: 14, awayValue: 9 },
{ label: "Serving", home: "Yes", away: "No", homeValue: 1, awayValue: 0 },
]}
/>homeValue/awayValue size the two bars: the side with the greater
value gets a bold label and a solid bar; the other stays muted. Bars
animate when values change, e.g. from a live subscription.
Pass showBars={false} to drop the bar from every row and keep just the
numbers.
Use with the Mr. Doge SDK
Stats List takes a plain entries array, so it works with any data
source. See the
Stats List Adapter for the
real functions mapping a match's stats (from
matches.get()/matches.subscribe()) onto this prop, across all 8
sports the SDK covers, plus a second function for the player-level
section. These are the ones behind the example above.
Props
Prop
Type
StatsListEntry
Prop
Type
StatsListSkeleton
import { StatsListSkeleton } from "@/components/stats-list" for a
loading state before the real entries have arrived. Takes rowCount
(default 5) and className.