Mr. Doge
Components

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.json

Usage

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.

On this page