Skip to content

Repository files navigation

Sports Score Bug React Component

A professional-grade React component for displaying sports scoreboards/score bugs, commonly seen in sports broadcasts.

Score Bug Preview

Features

  • Multi-Sport Support: Football, basketball, hockey, soccer
  • Real-time Updates: Data-driven rendering via props
  • Team Branding: Custom logos, colors, and team data
  • Game Context: Down/distance, quarter, timeout indicators
  • Timing Information: Game clock and play/shot clock
  • Warning Animations: Progressive fill animation for play clock countdown (5 seconds)
  • Responsive Design: Works across different screen sizes
  • Broadcast Quality: Professional styling and animations
  • Input Validation: Automatic bounds checking for all numeric inputs

Quick Start

1. Build the Component

npm install
npm run build

2. Test the Component

Open dist/index.html in your browser to see the interactive demo.

3. Use in Your Project

Include the built files in your project:

<!-- Component Styles -->
<link rel="stylesheet" href="path/to/style.css">

<!-- React dependencies (React 18) -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>

<!-- Score Bug Component -->
<script src="path/to/index.umd.cjs"></script>

Usage Example

const scoreBugProps = {
  sport: 'football',
  homeTeam: {
    id: 'MIA',
    name: 'Miami Dolphins',
    abbreviation: 'MIA',
    primaryColor: '#008E97',
    secondaryColor: '#FC4C02',
    logo: 'https://a.espncdn.com/i/teamlogos/nfl/500/mia.png'
  },
  awayTeam: {
    id: 'IND', 
    name: 'Indianapolis Colts',
    abbreviation: 'IND',
    primaryColor: '#002C5F',
    secondaryColor: '#A2AAAD', 
    logo: 'https://a.espncdn.com/i/teamlogos/nfl/500/ind.png'
  },
  gameState: {
    quarter: 3,
    down: 3,
    distance: 3,  // Use 0 to display "inches"
    homePossession: true,
    homeScore: 0,
    awayScore: 20,
    homeTimeouts: 3,  // 0-3 timeouts remaining
    awayTimeouts: 2
  },
  timing: {
    gameTime: '11:30',
    playTime: 4,
    period: '3RD'
  },
  display: {
    showPlayClock: true,
    showDown: true,
    animate: true
  }
};

// Render the component (React 18)
const root = ReactDOM.createRoot(document.getElementById('scoreBugContainer'));
root.render(React.createElement(ScoreBug.default, scoreBugProps));

Component API

Props

Prop Type Description
sport 'football' | 'basketball' | 'hockey' | 'soccer' Sport type determines display rules
homeTeam TeamData Home team information and branding
awayTeam TeamData Away team information and branding
gameState GameState Current game situation and scores
timing TimingData Game and play clock information
display? DisplayOptions Optional display preferences

TeamData Interface

interface TeamData {
  id: string;
  name: string;
  abbreviation: string;
  primaryColor: string;    // Hex color for team section background
  secondaryColor: string;  // Hex color for accents/borders
  logo: string;           // URL to team logo image
}

GameState Interface

interface GameState {
  quarter: number;                // 1-4 for regulation, 5+ for overtime
  down?: number;                  // Football specific (1-4)
  distance?: number;              // Football specific (0-99, 0 displays "inches")
  homePossession: boolean;        // Which team has possession
  homeScore: number;              // 0-200
  awayScore: number;              // 0-200
  homeTimeouts?: number;          // 0-3 timeouts remaining
  awayTimeouts?: number;          // 0-3 timeouts remaining
}

TimingData Interface

interface TimingData {
  gameTime: string;     // Format: "MM:SS"
  playTime?: number;    // Play/shot clock seconds
  period: string;       // "3RD", "4TH", "OT", etc.
}

DisplayOptions Interface

interface DisplayOptions {
  showPlayClock?: boolean;  // Show play/shot clock
  showDown?: boolean;       // Show down & distance
  animate?: boolean;        // Enable warning animations
}

Special Features

Play Clock Warning Animation

When playTime is 5 seconds or less:

  • Play clock background turns red with flashing border
  • Progressive fill animation: 100% red at 5 seconds, decreasing to 0% at 0 seconds
  • Smooth 1-second transition between states

Timeout Indicators

  • Three dots displayed below each team's score
  • Active timeouts shown in white (full opacity)
  • Used timeouts shown in gray (30% opacity)
  • Updates dynamically based on homeTimeouts and awayTimeouts values

Possession Highlighting

  • Team with possession displays enhanced white border
  • Glow effect around possessed team section
  • Updates based on homePossession boolean

Distance Display

  • Shows numeric yardage (1-99) for football
  • Automatically displays "inches" when distance is 0
  • Formats as "3rd & 7" or "1st & inches"

Input Validation

  • Scores: Automatically clamped to 0-200 range
  • Timeouts: Limited to 0-3 range
  • Distance: Restricted to 0-99 yards
  • Down: Restricted to 1-4
  • Play Clock: Limited to 0-40 seconds
  • All negative values automatically corrected to 0

Sport-Specific Rules

  • Football: Shows down & distance, play clock, timeouts
  • Basketball: Shows shot clock, periods
  • Hockey: Shows periods, penalty situations
  • Soccer: Shows match time, stoppage time

Team Data

The component includes built-in team data for multiple leagues:

  • NFL: All 32 teams with official colors and logos
  • NBA: All 30 teams with official colors and logos
  • NHL: Top 10 teams with official colors and logos

Import team data from src/data/teams:

import { nflTeams, nbaTeams, nhlTeams } from './data/teams';

const dolphins = nflTeams.MIA;
const lakers = nbaTeams.LAL;
const bruins = nhlTeams.BOS;

Development

# Install dependencies
npm install

# Development with hot reload
npm run dev

# Build for production
npm run build

# Preview built version
npm run preview

# Run tests
npm test

# Run tests with UI
npm run test:ui

File Structure

src/
├── components/ScoreBug/
│   ├── index.tsx              # Main component
│   ├── ScoreBug.module.css    # Styles
│   ├── TeamSection.tsx        # Team display
│   ├── GameStatus.tsx         # Game situation
│   └── TimingInfo.tsx         # Clock displays
├── types/index.ts             # TypeScript interfaces
└── data/teams/                # Team data files

Testing

The project includes comprehensive unit tests using Vitest and React Testing Library:

# Run tests in watch mode
npm test

# Run tests once
npm run test:run

# Run tests with UI
npm run test:ui

Test coverage includes:

  • Component rendering
  • Props handling
  • Conditional display logic
  • Warning animations
  • Timeout indicators
  • Score validation

Technical Details

Bundle Size

  • UMD Build: ~3.3 KB (minified)
  • CSS: ~2.8 KB
  • Total: ~6.1 KB

Dependencies

  • React: 18.x (peer dependency, not bundled)
  • React-DOM: 18.x (peer dependency, not bundled)

Build Configuration

  • Built with Vite 4.x
  • Uses classic JSX transform (React.createElement)
  • Optimized for UMD format for easy CDN integration
  • CSS Modules for scoped styling
  • TypeScript declaration files included

TypeScript Support

The package includes TypeScript declaration files (.d.ts) for full IDE support and type safety when using the component in TypeScript projects.

Browser Support

Modern browsers supporting ES2018+ features:

  • Chrome 63+
  • Firefox 55+
  • Safari 11.1+
  • Edge 79+

License

MIT

About

A Football-style score bug React component

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages