Charts

The charts & graphs kit — Recharts under a tokenized container layer. Lazy-loaded, SSR-safe, and re-themed by the --chart-* tokens in light and dark. Line, area, bar, pie, radar, scatter, sparklines, plus dashboard compositions.

Lazy-loadedSSR-safeToken-themedReduced-motion awareRecharts under the hood

The charts kit (@package/web-ui/charts) is Recharts under a thin, tokenized container layer. Recharts is code-split behind a single dynamic import, so it never enters the base bundle — a chart renders a token ChartSkeleton on the server and while the chart chunk loads, then hydrates on the client. Series colors come from the --chart-1…--chart-5 tokens (defined light and dark), surfaced per-chart as--color-<series> by ChartContainer/ChartStyle, so every chart re-themes with the system and the theme toggle for free. Each chart fills a ResponsiveContainer inside an aspect-ratio box, so it fits its column and never overflows the page; wide legends scroll in their own container. Entry animation is disabled under prefers-reduced-motion. Toggle the theme (top right) to see light and dark both hold up.

Line & area

LineChart and AreaChart (incl. stacked). Series colors come from the --chart-* tokens via ChartContainer/ChartStyle, so tooltips, legend, and fills all re-theme with light/dark for free.

  • Card
  • CardHeader
  • CardTitle
  • CardDescription
  • CardContent
Line
Two series, smoothed, with a legend.
Area · stacked
Cumulative band with token gradient fills.

Bar — grouped, stacked, horizontal

BarChart in its three layouts. Every bar fills a ResponsiveContainer inside the aspect-ratio frame, so charts fit their box and never overflow the body.

  • Card
  • CardHeader
  • CardTitle
  • CardDescription
  • CardContent
Bar · grouped
Side-by-side series with rounded caps.
Bar · stacked
Segments stack into one column per period.
Bar · horizontal
Categories down the axis — good for long labels.

Pie & donut

PieChart sizes each slice by value and colors it by name from the token palette. Pass a donut ratio to cut the center hole.

  • Card
  • CardHeader
  • CardTitle
  • CardDescription
  • CardContent
Pie
Slices sized by value, colored by name.
Donut
A pie with an inner radius for a center figure.

Radar & scatter

RadarChart compares profiles across shared axes; ScatterChart plots X/Y points and can size them by a third value (a bubble chart).

  • Card
  • CardHeader
  • CardTitle
  • CardDescription
  • CardContent
Radar
Compare profiles across shared axes.
Scatter · bubble
X/Y points sized by a third value (seats).

Sparklines

Compact inline trends — line, area, or bar — with no axes, grid, tooltip, or legend. Sized by height, so they hug a stat tile or a table cell.

  • Badge
Sparkline · Line
Sparkline · Area
Sparkline · Bar

Dashboard compositions

The pieces we drop into apps: StatSparkCard (a StatCard with an inline sparkline), MetricTile (value + directional delta + mini-trend), and KpiGrid (a mobile-first KPI grid). Direction is an icon, never color alone.

  • Badge
StatSparkCard · KPI gridcomposition
Revenue
$48.2k+12.5%
Active users
12,480+8.2%
Churn
1.8%-0.4%
p95 latency
150ms-16%
MetricTile · compact rowcomposition
MRR$41.0k+5.1%
Signups1,204+18%
Open tickets370%

Loading — the SSR fallback

ChartSkeleton is what every chart renders on the server, before hydration, and while the lazy Recharts chunk loads — so the layout never jumps. Token-only, shaped to hint at the chart to come.

  • Badge