Score cardPro
A live score with the period, the clock and the moments that mattered, drawn on a strip that tells the story of the match.
On this page
Installation
Usage
import { ScoreCard } from "@/components/ui/chatcn/pro/score-card"
<ScoreCard
competition="Liga regional, matchday 12"
venue="Campo da Foz"
home={{ name: "Sporting da Foz", score: 2 }}
away={{ name: "Atlético Ribeira", score: 1 }}
phase="live"
minute={77}
events={events}
following={following}
onFollowChange={setFollowing}
/>phase drives the card: scheduled shows the kickoff and vs, live shows the running minute with added time, halftime and finished settle the clock, and postponed shows your note. At full time the loser dims and the winner's name gains weight; penalties show in brackets under the score.
The match strip is a line from kickoff to the end of duration with a notch at half time, filled to the current minute. Goals, cards and reviews sit above the line for the home side and below for the away side; each is a focusable mark that reads the moment, and the line under the strip shows it on hover or focus. Substitutions stay in the list only.
Key events list goals, cards, substitutions and reviews, mirrored for the away side like a broadcast graphic, newest first while live and in order once it ends. Scores roll with Number flow when a goal lands. Crests are yours to pass as mark; the kit ships no club logos. Render it inside the card your host draws for a widget answer. It fills the width it is given, so a comfortable max width (around 28 rem) comes from the card, and it follows the host theme through the kit tokens. Pass onExpand where the host can go full screen.
Examples
States
Props
| Prop | Type | Notes |
|---|---|---|
competition, venue | ReactNode | The header |
home, away | { name, short?, mark?, score?, penalties? } | |
phase | "scheduled" | "live" | "halftime" | "finished" | "postponed" | "loading" | "error" | Default live |
minute, added | number | The running clock |
duration, halftimeAt | number | Default 90 and half of it |
kickoff, note | ReactNode | For scheduled and postponed |
events | { id, minute, added?, team, type, player, detail? }[] | type: goal, penalty, own-goal, yellow, red, sub, var |
visibleEvents | number | Before the list folds. Default 5 |
following, onFollowChange | boolean | The follow toggle |
onRetry, onExpand | () => void | |
labels | Partial<…Labels> | Every string the widget writes, for translation |
Labels
labels covers the phase words, the minute format (minute(m, added)), event type names (labels.type), the spoken score (score(home, hs, away, as)), follow, the fold and the error copy.
Keyboard
| Key | Action |
|---|---|
| Tab | Follow, then each moment on the strip, then the fold |
| Enter or Space on Follow | Follow or stop following |
Accessibility
- The score is said in words in a polite live region, so a goal is announced once, not per digit.
- Each strip mark is a button named with the minute, the event, the player and the team.
- Cards are drawn as cards in amber and red, and every event carries its type in words.
- Follow is a toggle button with
aria-pressed.
Motion
Score digits roll in 300 ms when a goal lands. The strip fill follows the clock in 300 ms. Reduced motion swaps digits with a fade and stops the fill animating.