Files
box-box/frontend/src/components/live/GapSparkline.tsx
AmanTahiliani c708b6697d Upgrade live timing page for race weekends
- Track status flag banner (green/yellow/SC/VSC/red, defensive mapping)
- Weather strip: air/track temp, humidity, wind with compass, rain badge
- Gap trend sparklines from a per-driver interval ring buffer
- Battle detection: consecutive cars within 1.0s chained and highlighted
- Stint history column with compound sequence per driver
- Pinnable drivers (max 3) with focus cards, persisted to localStorage

Pure logic lives in lib/gapHistory.ts and lib/battles.ts with unit
tests; 137 frontend tests passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 00:21:23 -04:00

45 lines
1.2 KiB
TypeScript

import { gapTrend, sparklinePoints } from '../../lib/gapHistory'
interface Props {
samples: number[] | undefined
width?: number
height?: number
}
export function GapSparkline({ samples, width = 56, height = 14 }: Props) {
if (!samples || samples.length < 2) {
return <span className="gap-spark gap-spark-empty">·</span>
}
const trend = gapTrend(samples)
const points = sparklinePoints(samples, width, height)
return (
<span className={`gap-spark trend-${trend ?? 'steady'}`} data-testid="gap-spark">
<svg
className="gap-spark-svg"
width={width}
height={height}
viewBox={`0 0 ${width} ${height}`}
aria-hidden="true"
focusable="false"
>
<polyline
points={points}
fill="none"
stroke="currentColor"
strokeWidth="1.2"
strokeLinejoin="round"
strokeLinecap="round"
/>
</svg>
{trend === 'closing' && (
<span className="trend-arrow trend-arrow-closing" title="Gap closing"></span>
)}
{trend === 'opening' && (
<span className="trend-arrow trend-arrow-opening" title="Gap opening"></span>
)}
</span>
)
}