TanStack chart
Responsive, accessible SVG charts built with TanStack Charts and registry theme tokens.
The line-and-area example uses a decorative area, so only the line owns focus points. This avoids duplicate keyboard stops and tooltip rows.
Installation
npx shadcn@latest add @redpanda/tanstack-chartpnpm dlx shadcn@latest add @redpanda/tanstack-chartyarn dlx shadcn@latest add @redpanda/tanstack-chartbunx shadcn@latest add @redpanda/tanstack-chartnubx shadcn@latest add @redpanda/tanstack-chartaube dlx shadcn@latest add @redpanda/tanstack-chartThe registry pins @tanstack/charts to 1.1.0, the version verified against this component’s styling contract.
This is a separate component: existing Recharts charts and their APIs are unchanged.
When to use
Use TanStackChart for new charts that need TanStack’s typed marks, scales, layouts, and interactions.
It adds registry palette, tooltip, and focus-ring styling to the native SVG React adapter without inventing a chart-type configuration API.
Keep using ChartContainer for existing Recharts compositions; the two components do not share definitions or tooltip APIs.
Usage
Define marks and scales with TanStack Charts, then pass the definition to the component:
'use client';
import { barY, defineChart } from '@tanstack/charts';import { scaleBand } from '@tanstack/charts/scales/band';import { scaleLinear } from '@tanstack/charts/scales/linear';import { tooltip } from '@tanstack/charts/tooltip';
import { TanStackChart } from '@/components/redpanda-ui/components/tanstack-chart';
const rows = [ { topic: 'Orders', messages: 120 }, { topic: 'Payments', messages: 80 },];
const definition = defineChart({ marks: [barY(rows, { x: 'topic', y: 'messages' })], scales: { x: { scale: () => scaleBand<string>().padding(0.2), axis: { ticks: { line: false } }, }, y: { scale: scaleLinear, nice: true, grid: true, axis: { label: 'Messages per second' }, }, }, tooltip,});
export function TopicChart() { return ( <TanStackChart ariaLabel="Message rate by topic" definition={definition} height={280} initialWidth={640} /> );}Scale factories infer domains from your data. A configured scale instance keeps its authored domain.
Leave pixel ranges to TanStack Charts. Version 1.1.0’s axis.ticks.line: false hides tick stubs while retaining labels.
Examples
Interactive bars
Click a bar or focus the chart and use arrow keys and Enter to select a topic.
onSelect, onFocusChange, and onFocusGroupChange retain the definition’s inferred source-row and axis-value types.
Compressed swarm
Version 1.1.0 adds dodgeY({ fit: 'compress' }) to keep crowded offsets inside the plot without changing the measured values or dot radii.
Compression can overlap dots. Give repeated measurements unique keys, and reduce the radius if a dot is larger than the available plot height.
Props and ownership
TanStackChartProps preserves the native SVG adapter props:
| Prop | Purpose |
|---|---|
definition |
Required typed chart definition; owns marks, scales, theme, tooltip, focus, keyboard behavior, and animation. |
ariaLabel |
Required accessible name describing the metric and comparison. |
ariaDescription |
Optional SVG description with context, units, or a summary. |
height / aspectRatio |
Fixed height or width-to-height ratio; native default height is 320 pixels. |
initialWidth |
Deterministic initial width for responsive server rendering; defaults to 640 pixels. |
idPrefix |
Optional stable SVG resource prefix; keep it identical on server and client, and unique across coordinated roots. |
width |
Fixed width; omit for responsive charts. |
className / style |
Host customization; CSS variables can override the scoped chart palette and tooltip tokens. |
onSelect / onFocusChange |
Typed callbacks for activation and focus. |
onFocusGroupChange |
Typed callback for the group of points sharing the focused axis value. |
The default adapter remains SVG-only. For Canvas rendering or React tooltip bodies, use TanStack’s explicit renderer or tooltip entry points and apply your application’s styling there.
Themes and accessibility
The component maps --ts-chart-1 through --ts-chart-5 to the registry chart colors and --ts-chart-6 to the contrasting neutral strong color.
Tooltips use registry typography, popover, border, radius, and shadow tokens. Focus dots use the background token. Theme changes follow CSS inheritance without rebuilding definitions or resetting focus.
- Provide a meaningful name, visible units, and a summary or data table when readers need exact values.
- Keep native keyboard behavior enabled. Arrow keys inspect points; Enter or Space activates them; Escape dismisses pinned tooltips.
- Keep palette overrides within the chart container. Portaled tooltip fallbacks outside that container need tokens on a shared ancestor or tooltip class.
- Fetching, loading, errors, and empty-state messaging belong to the consuming application; an empty definition alone does not explain missing data.
Dynamic data and server rendering
Keep static definitions at module scope. For changing data, create a new definition when captured values change and preserve its identity otherwise. React Compiler handles memoization in this project; consumers without it should follow TanStack’s framework memoization guidance.
For React Server Component applications, define charts inside a 'use client' module and pass serializable data from the server, not definitions containing functions or scale instances.
The component still server-renders SVG. Use identical data, formatters, initialWidth, and height on server and client to avoid hydration mismatches.