Stats List
mrdoge-ui/stats-listFreeComponent
Generic home/away match stats comparison, one row per stat, sport-agnostic.
Install it
npx shadcn@latest add https://mrdoge.co/r/stats-list.jsonSource
1import { cn } from "@/lib/utils"23export interface StatsListEntry {4 label: string5 /** Pre-formatted for display, e.g. "62%", "14", "Yamal (3)". */6 home: string7 away: string8 /** Raw numeric values for the two sides: every row is a comparison bar, sized from these. */9 homeValue: number10 awayValue: number11}1213export interface StatsListProps {14 /** Rows in display order. Sport-specific: see the adapter for which stats each sport contributes. */15 entries: StatsListEntry[]16 /**17 * Omits the comparison bar under every row, keeping just the numbers18 * and label, for entries where the two sides aren't a meaningful19 * proportional split, e.g. two different players' individual totals.20 *21 * @defaultValue true22 */23 showBars?: boolean24 className?: string25}2627function StatsListRow({ entry, showBar }: { entry: StatsListEntry; showBar: boolean }) {28 const total = entry.homeValue + entry.awayValue29 const homeShare = total > 0 ? (entry.homeValue / total) * 100 : 030 const awayShare = total > 0 ? (entry.awayValue / total) * 100 : 031 const homeLeading = entry.homeValue > entry.awayValue32 const awayLeading = entry.awayValue > entry.homeValue3334 return (35 <li className="flex flex-col gap-1.5 py-2.5">36 <div className="flex items-center justify-between gap-3 text-sm">37 <span className={cn("tabular-nums", homeLeading ? "font-semibold" : "text-muted-foreground")}>38 {entry.home}39 </span>40 <span className="text-xs text-muted-foreground">{entry.label}</span>41 <span className={cn("tabular-nums", awayLeading ? "font-semibold" : "text-muted-foreground")}>42 {entry.away}43 </span>44 </div>45 {showBar ? (46 <div className="flex items-center gap-1">47 <div className="flex flex-1 justify-end">48 <div49 className={cn(50 "h-1 rounded-full transition-[width] duration-300",51 total === 0 ? "invisible" : homeLeading ? "bg-foreground" : "bg-muted-foreground/25"52 )}53 style={{ width: `${homeShare}%` }}54 />55 </div>56 <div className="flex flex-1 justify-start">57 <div58 className={cn(59 "h-1 rounded-full transition-[width] duration-300",60 total === 0 ? "invisible" : awayLeading ? "bg-foreground" : "bg-muted-foreground/25"61 )}62 style={{ width: `${awayShare}%` }}63 />64 </div>65 </div>66// … truncated
Files it writes
More from mrdoge-ui
All 26 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Bet Slipbet-slip | mrdoge-ui | Components | Free | no deps | |
| Entity Imageentity-image | mrdoge-ui | Components | Free | no deps | |
| Match Cardmatch-card | mrdoge-ui | Components | Free | no deps · 3 files | |
| Match Card Compactmatch-card-compact | mrdoge-ui | Components | Free | no deps | |
| Match Highlightmatch-highlight | mrdoge-ui | Components | Free | no deps · 2 files | |
| Match Timelinematch-timeline | mrdoge-ui | Components | Free | no deps | |
| Odds Selectorodds-selector | mrdoge-ui | Components | Free | no deps · 2 files |
