diff --git a/app/(marketing)/_components/markets-widget.tsx b/app/(marketing)/_components/markets-widget.tsx index 90ad334f..7f46c9af 100644 --- a/app/(marketing)/_components/markets-widget.tsx +++ b/app/(marketing)/_components/markets-widget.tsx @@ -7,6 +7,7 @@ import { Card } from "@/components/ui/card"; import { sampleMarkets, winNotifications, type Market } from "@/content/markets.sample"; import { useState, useEffect } from "react"; import { useFollowsStore } from "@/app/state/follows"; +import Sparkline from "@/components/Sparkline"; interface MarketsWidgetProps { className?: string; @@ -148,6 +149,12 @@ function MarketCard({ market, IconComponent, colors, index, reducedMotion }: Mar

{market.title}

{market.description}

+ {/* Sparkline preview */} + {/* Following indicator — visible only for followed markets */} {isFollowing && ( diff --git a/app/components/Sparkline.tsx b/app/components/Sparkline.tsx new file mode 100644 index 00000000..e01e807c --- /dev/null +++ b/app/components/Sparkline.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +interface SparklineProps { + data: number[]; + className?: string; + 'data-testid'?: string; +} +/** + * Sparkline – a minimalist line chart rendered as an SVG. + * It receives an array of numeric values and draws a thin line that fills the container width. + * The component is theme‑aware – it uses stroke-current so the parent can set the colour via Tailwind utilities. + */ +export default function Sparkline({ data, className = '', 'data-testid': testId }: SparklineProps) { + if (!data || data.length === 0) { + return null; + } + const min = Math.min(...data); + const max = Math.max(...data); + const range = max - min || 1; + const points = data + .map((value, i) => { + const x = (i / (data.length - 1)) * 100; + const y = 100 - ((value - min) / range) * 100; + return ${x},; + }) + .join(' '); + return ( + + + + ); +} diff --git a/app/components/__tests__/Sparkline.test.tsx b/app/components/__tests__/Sparkline.test.tsx new file mode 100644 index 00000000..54541af8 --- /dev/null +++ b/app/components/__tests__/Sparkline.test.tsx @@ -0,0 +1,13 @@ +import { render } from '@testing-library/react'; +import Sparkline from '@/components/Sparkline'; + +test('renders sparkline with data', () => { + const data = [10, 20, 15, 30, 25]; + const { getByTestId } = render(); + const svg = getByTestId('sparkline-test'); + expect(svg).toBeInTheDocument(); + // polyline should have points attribute with commas + const polyline = svg.querySelector('polyline'); + expect(polyline).not.toBeNull(); + expect(polyline?.getAttribute('points')).toMatch(/,/); +});