Skip to content
Sign in
Apps SDKScore cardMenu

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.

ProA seaside derby, live: the clock runs, a red card and a goal land on the match strip.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/score-card

Usage

tsx
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

ProFull time, half time, won on penalties with long names, before kickoff, postponed, loading and an error.

Props

PropTypeNotes
competition, venueReactNodeThe header
home, away{ name, short?, mark?, score?, penalties? }
phase"scheduled" | "live" | "halftime" | "finished" | "postponed" | "loading" | "error"Default live
minute, addednumberThe running clock
duration, halftimeAtnumberDefault 90 and half of it
kickoff, noteReactNodeFor scheduled and postponed
events{ id, minute, added?, team, type, player, detail? }[]type: goal, penalty, own-goal, yellow, red, sub, var
visibleEventsnumberBefore the list folds. Default 5
following, onFollowChangebooleanThe follow toggle
onRetry, onExpand() => void
labelsPartial<…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

KeyAction
TabFollow, then each moment on the strip, then the fold
Enter or Space on FollowFollow 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.