# Scoreboard

> A ballpark scoreboard on a dark green board: the line score across the top, then the count, both batting orders, the umpires, and other games around the league.

- Name: `scoreboard`
- Status: beta
- Categories: sports, baseball, scores, live
- Files: the install writes `scoreboard.tsx`, and any part files named `scoreboard-*.tsx`, to your `components` alias, `@/components` by default. Edit them freely. They are yours.
- Other registry items: `@txbrendan/line-score`, `@txbrendan/ball-count`, `@txbrendan/batting-order`, `@txbrendan/league-scores`, `@txbrendan/skeleton`. The install adds them.
- Gallery: https://txbrendan.dev/blocks/scoreboard
- Registry item: https://txbrendan.dev/r/scoreboard.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@txbrendan": "https://txbrendan.dev/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@txbrendan` in a public list that txbrendan/ui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @txbrendan/theme
   ```

3. Add the block. It also adds every component it uses:

   ```bash
   npx shadcn@latest add @txbrendan/scoreboard
   ```

## Use it for

- A live baseball game page, a stadium screen, or a fan site's game center.
- Pass away and home with their runs by inning, hits, errors, and lineup. Then the rest as you have it: count, batter, umpires, and leagues.
- Pass inning while the game is on. Its team's lineup marks the batter, by batter.number.
- Leave inning and count out once the game is over, and pass status, like "Final".
- Each panel shows only when it has data, so a board with just a line score works too.
- The board stays dark green in light mode and dark. It scopes the theme's dark tokens to itself with the dark class.

## Avoid it for

- A board that follows the page's light and dark mode. Use LineScore and the other parts on your own card.
- Games with no innings. Use MatchCard.

## Props

- `away`: `ScoreboardTeam`. The visitors: a LineScoreTeam plus lineup?, their batting order. With home, the game on the board.
- `home`: `ScoreboardTeam`. The home side, the same shape.
- `innings`: `number`. Default `9`. How many innings the game is scheduled for.
- `inning`: `{ number: number; half: "top" | "bottom" }`. The half-inning being played now.
- `status`: `string`. A word for the game's state when no inning is in play, like "Final".
- `count`: `{ balls: number; strikes: number; outs: number }`. The count now. Leave it out to hide the count.
- `batter`: `{ number: number; average?: string }`. Who is at the plate.
- `leagues`: `{ title: string; games: LeagueScoresGame[]; note?: ReactNode }[]`. Default `[]`. Other games, one table per group.
- `umpires`: `{ label: string; number: number }[]`. Default `[]`. The umpires by base, like { label: "Plate", number: 17 }.
- `loading`: `boolean`. Default `false`. Shows placeholder tiles while the game loads.
- `loadingText`: `string`. Default `"Loading the scoreboard"`. What the status line tells screen readers while loading.
- `emptyText`: `string`. Default `"No game on the board."`. Shown when there is no game and nothing is loading.
- `className`: `string`. Extra classes on the board, which holds the container query.

## Accessibility

- The board is a section named "Scoreboard". Pass aria-label to name it after the game.
- Each part keeps its own table or list, so screen readers can move by table and by row.
- The line score says each scoring change once in a polite line. The count does not, since it changes every pitch.
- On the dark green board, white text is 12.6:1, the lit amber is 9.6:1, and the muted labels are 5.5:1.
- While loading, the board has aria-busy="true" and a status line says loadingText.

## Examples

### A game in progress

```tsx
<Scoreboard
  away={{ name: "Harbor", short: "HAR", runs: [0, 1, 0, 0], hits: 4, errors: 1, lineup: harborLineup }}
  home={{ name: "Rivers", short: "RIV", runs: [1, 0, 2], hits: 3, lineup: riversLineup }}
  inning={{ number: 4, half: "bottom" }}
  count={{ balls: 1, strikes: 2, outs: 1 }}
  batter={{ number: 24, average: ".267" }}
/>
```

### A final score with nothing else

```tsx
<Scoreboard away={{ name: "Harbor", runs: [0, 1, 0, 0, 2, 0, 0, 1, 0], hits: 9 }} home={{ name: "Rivers", runs: [1, 0, 2, 1, 0, 0, 1, 0, "X"], hits: 8 }} status="Final" />
```

### While the game loads

```tsx
<Scoreboard loading />
```
