Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelog
  1. Home
  2. Blog
  3. Component guides
  4. React Sparkline: Table Cells, KPI Tiles, Delta Chips
Auf Deutsch lesen
  1. Blog
  2. Component guides
  3. React Sparkline: Table Cells, KPI Tiles, Delta Chips
Component guides
Component guides

React Sparkline: Table Cells, KPI Tiles, Delta Chips

SR
Serban Rusu · Founder of Wingo UI
Oct 19, 2026 · 9 min read

On this page

0%
  1. What is a sparkline and when should I use one?
  2. Which React sparkline chart libraries are there?
  3. How do I add a React sparkline to a component?
  4. How do I put a sparkline in a table cell?
  5. How do I build a KPI sparkline tile?
  6. What goes in the delta chip next to a sparkline?
  7. How do I make a sparkline accessible?
  8. How does a sparkline work on a phone?
  9. What are the common React sparkline pitfalls?
  10. How do I add it to my project?
  11. FAQ
    1. What is a sparkline chart?
    2. How do I add a sparkline to a table cell in React?
    3. Should a sparkline have a tooltip?
    4. How do I make a sparkline accessible?
    5. Is the Wingo UI Sparkline free?

TL;DR

A React sparkline is a word-sized chart with no axes that shows the shape of a trend next to a number, in a table cell, a KPI tile or a sentence. Give every row in a table the same min and max so the lines compare, pair the line with the current value and a delta chip that turns green or red by meaning, and give it an accessible summary such as "from $8,200 to $12,480, +52.2%". The Wingo UI Sparkline, Stat Card and Trend Badge do this from a data array.

Published Oct 19, 2026

You have a table of clients, products or servers, and each row needs to say "going up" or "going down" without turning into a full chart. A React sparkline does that: a word-sized line next to the number, with no axes, no legend and no grid. The hard parts show up later. Each row scales to its own range, so a flat client looks as busy as a growing one. The delta next to it turns red when costs drop. A screen reader hears nothing, and on a phone the tooltip hides under the finger. This guide covers when to use a sparkline, how to put one in a table cell and in a KPI tile, the delta chip that goes with it, and the pitfalls.

What is a sparkline and when should I use one?

Use a sparkline when the shape of a trend matters more than its exact values. Edward Tufte, who coined the term, defines it as "a small intense, simple, word-sized graphic with typographic resolution" in his notes on sparkline theory and practice (opens in a new tab), and lists sentences, tables, headlines and spreadsheets as places it can live.

In a React app that means three places:

  1. Table cells and list rows: revenue per client, response time per endpoint, stock per warehouse.
  2. KPI tiles on a dashboard, under or beside the big number.
  3. Running text: "Signups rose all quarter" with the line inline at the size of the text.

A sparkline is the wrong tool when the reader needs to read values off an axis, compare two series in one box, or see dates. Use a Line chart for that, and keep the sparkline as the summary that links to it.

Which React sparkline chart libraries are there?

Pick by the stack you already have: react-sparklines for a plain SVG line, the MUI X SparkLineChart if you use MUI, the Wingo UI Sparkline for table cells with a value and a delta. Facts below are from each project's docs, its source and the npm registry, as of October 19, 2026.

OptionWhat it isTypesInspect pointsNotes
react-sparklines (opens in a new tab)MIT npm package with composable children (SparklinesLine, SparklinesCurve, SparklinesBars, SparklinesSpots, SparklinesReferenceLine, SparklinesNormalBand)Line, curve, bars, spotsNo tooltip; an onMouseMove callback on line points and barsThe latest version on npm, 1.7.0, was published in July 2017
MUI X SparkLineChart (opens in a new tab)Part of the MIT @mui/x-charts package (9.15.0)Line, or bars with plotType="bar", optional areashowTooltip and showHighlightThemed with MUI; yAxis takes min and max
Wingo UI SparklinePro source component, npx wingo-ui@latest add sparklineLine, area, bar, win-lossinteractive: hover, touch scrub, arrow keysShips with a value-and-delta wrapper, trend colors and an accessible summary

If your app already uses MUI, the SparkLineChart is the natural pick: it shares your theme, and you avoid adding a second chart stack. react-sparklines is free and depends only on prop-types, but it has not had a release since 2017, so any tooltip, keyboard or screen reader support is yours to build. The rest of this guide uses the Wingo UI components.

How do I add a React sparkline to a component?

Install it and pass an array of numbers, oldest first. The defaults are a 96 by 28 px line with a dot on the last point, which reads well in a phone row.

bash
npx wingo-ui@latest add sparkline
tsx
import { Sparkline } from "@/components/ui/sparkline";
const revenue = [8200, 8650, 8400, 9100, 9480, 9230, 10150, 10600, 10380, 11420, 11900, 12480];
export function RevenueNote() {
return (
<p className="text-sm">
Revenue rose all quarter{" "}
<Sparkline
data={revenue}
width={64}
height={16}
className="align-[-0.2em]"
valueFormat="currency"
locale="en-US"
label="Revenue, last 12 weeks"
/>{" "}
and closed at $12,480.
</p>
);
}

The props you will reach for first:

  • type: "line", "area" (a line over a soft fill), "bar" or "win-loss" (equal ticks up for positive values and down for negative ones, for streaks or daily goals).
  • width and height in px. width={0} fills the parent, which then needs a width of its own.
  • tone colors the line (neutral ink by default). trendColor colors it by direction instead: green when the last value is above the first, red when it is below.
  • invertTrend for metrics where down is good, such as costs, churn or response time.
  • reference: a dashed hairline at the "first" value, the "average" or "zero".
  • data can also hold rows with a label or an ISO date for the readout, and null leaves a gap.

Turn on interactive and the sparkline becomes one tab stop you can read point by point. Hover it, drag across it with a finger, or focus it and use the arrow keys.

Hover the line or drag a finger across it: the readout shows each week and the amount on the right follows. Tab to it and press Left and Right to step through the points
$ npx wingo-ui@latest add sparkline
ProSparkline docs

How do I put a sparkline in a table cell?

Give every row the same scale. A sparkline in a table cell scales to its own minimum and maximum by default, so every line fills its box: a client that went from $9,000 to $9,400 looks as steep as one that doubled. Pass shared min and max to every row and a taller line means more revenue. The trade-off: a small client's line sits nearly flat near the bottom. When the shape of each row matters more than its size, keep the per-row scale and say so in the column header.

SparklineWithValue puts the current value and a Trend Badge next to the line, which is what most table cells need. The value defaults to the last point, the badge to the percent change from first to last.

tsx
import { SparklineWithValue } from "@/components/ui/sparkline";
type ClientRow = { id: string; name: string; weekly: number[] };
export function ClientsTable({ rows }: { rows: ClientRow[] }) {
// one range for every row, so the lines compare
const max = Math.max(0, ...rows.flatMap((row) => row.weekly));
return (
<table className="w-full text-sm">
<caption className="sr-only">Weekly revenue per client, last 12 weeks</caption>
<thead>
<tr className="text-left text-xs text-muted-foreground">
<th className="py-2 font-medium">Client</th>
<th className="py-2 text-right font-medium">Last 12 weeks</th>
</tr>
</thead>
<tbody className="divide-y divide-border">
{rows.map((row) => (
<tr key={row.id}>
<td className="py-3 font-medium">{row.name}</td>
<td className="py-3 text-right">
<SparklineWithValue
data={row.weekly}
type="area"
width={88}
height={32}
min={0}
max={max}
layout="responsive"
valueFormat="currency"
locale="en-US"
label={`${row.name}, revenue over 12 weeks`}
/>
</td>
</tr>
))}
</tbody>
</table>
);
}

layout="responsive" stacks the value and badge over the line below 640px and puts them in one row from there, so the cell stays narrow on a phone. The badge uses the ghost variant and the sm size by default, colored text with an arrow and no fill, which keeps a column of them quiet. If an interactive sparkline sits in a scrolling table, the readout is portaled and pinned above the line, so the table cannot clip it.

For a table with more than a handful of columns, the Data Table handles sorting and paging, and the responsive table guide shows how its rows turn into cards on a phone.

How do I build a KPI sparkline tile?

Use the Stat Card. It takes the label, the value, the delta and the sparkline values, and lays them out as a dashboard tile: the number counts up the first time it scrolls into view, the delta pill fades in, and the KPI sparkline draws from left to right.

bash
npx wingo-ui@latest add stat-card
tsx
import { Timer, Wallet } from "lucide-react";
import { StatCard, StatGroup } from "@/components/ui/stat-card";
export function Kpis({ daily, responseHours }: { daily: number[]; responseHours: number[] }) {
return (
<StatGroup>
<StatCard
label="Revenue"
icon={<Wallet />}
value={128450}
format="currency"
delta={12.4}
deltaLabel="vs. last month"
sparkline={daily}
locale="en-US"
/>
<StatCard
label="Median first response"
icon={<Timer />}
value={8100}
format="duration"
delta={-8.5}
deltaLabel="vs. last month"
invertTrend
sparkline={responseHours}
sparklineType="bar"
locale="en-US"
/>
</StatGroup>
);
}

format="duration" takes seconds, so 8100 reads "2 hr, 15 min". With invertTrend the drop in response time shows green while the arrow still points down. StatGroup lays the tiles out two per row on phones and four from 1024px.

The card's built-in sparkline is decorative: the card already speaks one sentence with the value and the change, so the chart is hidden from screen readers and cannot be inspected. When you want the reader to scrub the line, pass the standalone Sparkline through the chart prop:

tsx
import { StatCard } from "@/components/ui/stat-card";
import { Sparkline } from "@/components/ui/sparkline";
const revenue = [8200, 8650, 8400, 9100, 9480, 9230, 10150, 10600, 10380, 11420, 11900, 12480];
<StatCard
label="Revenue"
value={12480}
format="currency"
delta={52.2}
deltaLabel="vs. 12 weeks ago"
locale="en-US"
chart={
<Sparkline data={revenue} type="area" width={0} height={48} interactive valueFormat="currency" locale="en-US" label="Revenue, last 12 weeks" />
}
/>

Press Simulate a new day in the demo below: a new day joins the sparkline and the value and delta count to their new numbers from where they are.

Press Simulate a new day: the sparkline gains a point and the value and the delta count to their new numbers
$ npx wingo-ui@latest add stat-card
ProStat Card docs

What goes in the delta chip next to a sparkline?

An arrow, a signed number and a color that reflects meaning instead of sign. The line shows the shape, and the chip gives the number people quote. The Trend Badge is that chip on its own, for places where you print the value yourself.

tsx
import { TrendBadge } from "@/components/ui/trend-badge";
<TrendBadge value={12.4} label="vs. last month" locale="en-US" />
<TrendBadge value={-3200} format="currency" variant="ghost" size="sm" locale="en-US" />
<TrendBadge value={-0.8} invertTrend label="churn vs. last month" locale="en-US" />

The first prints "+12.4%" in green, the second "−$3,200" in red, and the third a green "−0.8%" because lower churn is good. A few props worth knowing:

  • format: "percent" (12.4 is +12.4%), "number" or "currency". Values of a million and up go compact ("+$1.3M").
  • flatThreshold (0.05 by default): smaller changes count as no change and turn gray, so +0.01% does not flash green.
  • neutralTone paints every direction in the neutral ink, for metrics where up is neither good nor bad, like open tickets.
  • animated is off by default, so a table of fifty badges does not all count up at once. Turn it on for a single hero number.

Screen readers hear the direction in words ("Up 12.4% vs. last month"), never the arrow glyph. Change the sentences through labels when you translate.

Press Change to cycle the value: the pill glides to each new number, the arrow flips with the direction, and a value under the threshold turns gray
$ npx wingo-ui@latest add trend-badge
ProTrend badge docs

How do I make a sparkline accessible?

Say the trend in words. A read-only Sparkline renders with role="img" and an accessible name made from your label plus a summary of the first value, the last value and the change: "Revenue, last 12 weeks: from $8,200 to $12,480, +52.2%". Pass labels.summary to word it in another language.

With interactive on, the sparkline is one tab stop. Left and Right walk the points, Home and End jump to the ends, Page Up and Page Down move by 10, and Escape clears the readout. A polite live region reads each point as you move. On the color side, trendColor is never the only signal: the delta chip prints the sign and an arrow, which matters for readers who cannot tell red from green. Under reduced motion the draw-in and the count-up are skipped and everything appears final.

How does a sparkline work on a phone?

The default 28px height fits a list row, and an interactive sparkline treats the whole row height (8px above and below the drawing) as its touch target. Tap and drag sideways to scrub; a vertical drag still scrolls the page. The readout sits above the line instead of under the finger, and a second tap on the same point or a tap outside clears it. The same rules about touch targets and gestures run through the component guides category and the React form components guide.

What are the common React sparkline pitfalls?

Six mistakes show up once real data arrives.

  • A separate scale per row. Every line fills its box and the rows stop comparing. Share min and max.
  • Importing the wrong Sparkline. stat-card.tsx exports its own small Sparkline (the decorative one inside the card). For tables and interactive, import from @/components/ui/sparkline.
  • A series that starts at zero. A percent change from 0 is undefined, so the badge shows "–". Pass delta yourself or use deltaFormat="number", which prints last minus first.
  • Too many bars. Above 120 points, type="bar" and "win-loss" fall back to a line, with a warning in development. Aggregate daily data to weeks first.
  • width={0} in a parent without a width. A fill-width sparkline measures its parent; inside an auto-width inline element it has nothing to fill. Use a grid cell or a flex-1 box.
  • Green for a cost increase. Set invertTrend on costs, churn and response time, on both the sparkline and the badge (SparklineWithValue passes it through).

The dashboard side of this, KPI rows over a filtered table, is built end to end in the Next.js admin dashboard tutorial, and the dashboard library comparison covers which libraries ship KPI cards at all.

How do I add it to my project?

Run npx wingo-ui@latest add sparkline stat-card trend-badge. The CLI copies the source into components/ui, adds the helpers they import (the chart kit, number formatting, tones) and installs motion, d3-shape, d3-scale and lucide-react. All three are Pro components (pricing). If you build with Claude Code or Cursor, the MCP server lets the agent read these props instead of guessing them.

Components in this post

  • Sparkline

    A React sparkline: a word-sized chart for table cells, list rows, KPI tiles and running text, as a line, an area, bars or win / loss ticks.

    Pro
  • Stat Card

    A React stat card for dashboards: a label, a big number that counts up, a delta pill that knows good from bad, a sparkline and a goal bar.

    Pro
  • Trend badge

    A React trend badge, the delta chip for KPIs, table cells and leaderboards: an arrow, a signed change and a color that says if it is good.

    Pro

FAQ

What is a sparkline chart?

A sparkline is a tiny line or bar chart without axes, labels or a legend, sized to sit next to a word or a number. Edward Tufte named it and describes it as a word-sized graphic that can go anywhere a word or number can, such as a sentence, a table or a headline.

How do I add a sparkline to a table cell in React?

Render a fixed-size sparkline (for example 88 by 32 px) in the cell, next to the current value and a delta chip. Pass the same min and max to every row so a taller line means a larger number; with a separate scale per row, every line fills its box and the rows stop comparing.

Should a sparkline have a tooltip?

Only when people need exact values. A read-only sparkline with the last value printed beside it is enough for most tables; turn on inspection (interactive in the Wingo UI Sparkline) when readers want to check a week, and make it work with the keyboard and touch too.

How do I make a sparkline accessible?

Give it role="img" and an accessible name that states the trend in words, for example "Revenue, last 12 weeks: from $8,200 to $12,480, +52.2%". Do not rely on green and red alone: print the value and a signed change as text.

Is the Wingo UI Sparkline free?

No. The Sparkline, the Stat Card and the Trend Badge are Pro components. The Number format helper they share is free, and so is the Animated Counter that the Stat Card uses for its roll animation.

  • Sparkline
  • Charts
  • Dashboard
  • Accessibility
  • React

Share

SR

About the author

Serban Rusu

Founder of Wingo UI

Serban Rusu founded Wingo UI. He builds its component library, CLI and MCP server, and writes about React interfaces for phones and AI coding agents.

More from Serban
Keep reading

Related posts

All posts
Component guides

React Animated Number Counter: Rolling Odometer Digits

Build a React animated number counter that rolls each digit like an odometer, takes its separators from Intl, holds its width and respects reduced motion.

SRSerban Rusu·Oct 19, 2026·9 min read
Comparisons and alternatives

Best React Component Library for Dashboard Apps in 2026

The best React component library for dashboard apps in 2026: 7 libraries compared on data tables, charts, filters and app shells, with prices and picks.

SRSerban Rusu·Oct 16, 2026·13 min read
Build it: screens and apps

Nextjs Admin Dashboard Tutorial: 5 Screens, Phone-Ready

A nextjs admin dashboard tutorial for the App Router: app shell, KPI home, server-side data tables, settings and team pages, each one usable on a phone.

SRSerban Rusu·Oct 9, 2026·21 min read
Newsletter

Get new posts by email

New guides, tutorials and comparisons from the Wingo UI blog, sent when they are published.

No spam. Unsubscribe at any time.

WingoUI

Animated, configurable, mobile-first React components and blocks. Copy the source, make it yours, and let your coding agent build with it.

Product

  • Components
  • Templates
  • Pricing
  • AI agents
  • Theme generator

Resources

  • Docs
  • Blog
  • Changelog
  • Changelog RSS
  • llms.txt

Legal

  • Terms
  • Privacy
  • Refunds
  • License
  • Imprint

Component categories

  • Buttons & Actions
  • Inputs
  • Forms
  • Navigation
  • Overlays
  • Feedback
  • Data Display
  • Tables & Lists
  • Charts & Stats
  • Layout
  • Media
  • AI Kit
  • Text & Effects
  • Mobile
  • Commerce
  • Marketing Sections
  • Blocks
  • Hooks & Utilities

© 2026 Wingo UI

Wingo UI