Chart kit TypeScript helper for React
v1.0.2Updated in 1.6.0
A React chart toolkit: the palette, formatters, measuring container, axes, crosshair, tooltip, legend and data table charts share.
The demo is a small line chart assembled from the kit. Move the mouse over it for a crosshair and a tooltip that flips near the right edge. On a phone, tap a month to pin the readout above your finger, drag sideways to scrub (vertical drags still scroll the page), tap the same month again or anywhere outside to clear it. With the keyboard, Tab to the chart, then Left / Right walk the months, Home / End jump to the ends, PageUp / PageDown move by ten, Escape clears; a live region reads each point. Click or tap a legend entry to hide or show its series, hover or focus one to highlight it.
Chart kit is a Pro React helper in the React hooks and utilities category, written in TypeScript for React 19. It installs as source with npx wingo-ui@latest add chart-kit, together with useControllableState, useMediaQuery, Motion presets, Number format and Tones and the npm packages motion, d3-scale and d3-shape.
Add to a project
Requirements: React 19, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup
npx wingo-ui@latest add chart-kitChart kit is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans
Usage
Import ChartContainer from @/lib/chart-kit.
import {
ChartContainer,
ChartSvg,
ChartTooltip,
ChartInspectLayer,
chartLayout,
niceScale,
valueDomain,
useChartInspect,
formatChartValue,
} from "@/lib/chart-kit"
const data = [
{ month: "Jul", revenue: 106300 },
{ month: "Aug", revenue: 97500 },
{ month: "Sep", revenue: 128450 },
]
function Bars({ width, height }: { width: number; height: number }) {
const layout = chartLayout({ width, height, showYAxis: false })
const { scale: y } = niceScale(valueDomain(data.map((d) => d.revenue)), [layout.bottom, layout.top])
const step = layout.innerWidth / data.length
const positions = data.map((_, i) => layout.left + step * (i + 0.5))
const inspect = useChartInspect({ positions })
const i = inspect.activeIndex
return (
<>
<ChartSvg width={width} height={height}>
{data.map((d, index) => (
<rect key={d.month} x={positions[index] - 12} width={24} y={y(d.revenue)} height={y(0) - y(d.revenue)} rx={4} fill="var(--series-1)" />
))}
</ChartSvg>
<ChartInspectLayer controller={inspect} label="Revenue by month" />
<ChartTooltip
x={i == null ? null : positions[i]}
title={i == null ? "" : data[i].month}
items={i == null ? [] : [{ key: "v", label: "Revenue", value: formatChartValue(data[i].revenue, { format: "currency", locale: "en-US", currency: "USD" }), color: "var(--series-1)", shape: "rect" }]}
/>
</>
)
}
export function RevenueBars() {
return (
<ChartContainer aria-label="Revenue by month" height={200}>
{(size) => <Bars {...size} />}
</ChartContainer>
)
}API
valueFormatdefault"currency""number" | "compact" | "currency" | "percent"ChartFormatOptions.format in the demo: how values print in the tooltip, the ticks and the table.
localedefault"en-US"stringThe demo's locale for numbers and dates. Charts resolve theirs with useLocale.
curvedefault"monotone""monotone" | "linear" | "natural" | "step"ChartCurve passed to getCurve for the lines and areas.
tooltipModedefault"auto""auto" | "float" | "fixed"ChartTooltip mode: float beside the crosshair, fixed above the plot (the touch default), auto picks by pointer.
heightdefault240numberChartContainer height in px (reserved before measuring, so nothing shifts).
showGriddefaulttruebooleanDraws ChartGrid hairlines at the value ticks.
animateddefaulttruebooleanChartContainer animated: marks draw in when the chart scrolls into view.
loadingdefaultfalsebooleanChartContainer loading: a skeleton in the plot's shape (loadingShape bars | line | donut | gauge | grid).
emptydefaultfalsebooleanThe demo passes no data: ChartContainer empty shows ChartEmpty with labels.empty.
ChartContainer{ height?: number | string = 240; surface?: string = "var(--surface)"; animated?: boolean = true; loading?; loadingShape?; empty?; emptyState?; labels?: Partial<ChartLabels>; table?; header?; footer?; children: (size: { width; height }) => ReactNode } & div propsThe figure (role figure, aria-label from props): sets the palette vars and --chart-surface, measures its width, reserves the height before measuring, renders loading / empty in the same box, and always renders the table (so it is in the server html). useChart() inside gives { width, height, reduced, touch, revealed, animated }.
Parts
useChart
hookReads the chart context inside ChartContainer: { width, height, reduced, touch, revealed, animated }. Throws outside a container.
CHART_PALETTE
constantThe Tailwind arbitrary classes that set --series-1..8 and --series-other, with separate light and dark steps checked for color blindness.
SERIES_COLORS
constantThe eight categorical slots as css vars, var(--series-1) to var(--series-8), in their fixed order.
OTHER_COLOR
constantvar(--series-other), the gray used past the eighth series instead of a cycled hue.
TONE_CHART_COLORS
constantTone name to chart color: neutral is the foreground ink, the rest map to the brand and status tokens.
resolveChartColor
functionTurns "series-3", a tone, "other" or any css color into a fill; without one, the slot for the series' position.
seriesColor
functionThe palette slot for a 0-based series index, or OTHER_COLOR past the eighth.
tint
functionA transparent mix of a chart color at a percent, for area fills, heat cells and tracks.
formatChartValue
functionFormats one value for the tooltip and table as number, compact, currency (USD by default) or percent; null prints a dash.
formatChartTick
functionA short axis tick label: compact past 10,000 ("$128K", "1.3M"), whole percents.
formatChartLabel
functionFormats an x value for the axis, tooltip or table; ISO days and months become localized dates.
parseChartDate
functionParses "2026-09-24" or "2026-09" as a local calendar date (not UTC), or returns null.
inferSeries
functionLists the numeric keys of the first rows, minus the x key, as series when none are given.
toNumber
functionReturns a finite number as is and anything else as null, for reading data cells safely.
useChartSeries
hookResolves series with colors fixed by position, hidden state (controlled or not, the last one stays visible) and the highlighted series. Returns { all, visible, hidden, toggle, highlighted, setHighlighted }.
CHART_CURVES
constantThe d3 curve factory for each ChartCurve: linear, monotone, natural and step.
getCurve
functionThe d3 curve for a ChartCurve name, monotone when undefined.
stackData
functionA d3 stack over rows with offset none, expand (100% shares) or diverging (negatives below zero).
valueDomain
functionThe [min, max] of the values, widened to include zero when asked (bars and areas) and never empty.
niceScale
functionA nice linear scale and its ticks, about one tick per 56px of range.
barPath
functionThe svg path of a bar with a rounded data end and a square base, vertical or horizontal.
barPathReversed
functionbarPath flipped, for negative bars: the rounded end sits at the bottom or on the left.
estimateTextWidth
functionA deterministic width estimate for 11px tabular labels, so server and client reserve the same axis space.
thinLabels
functionWhich of n evenly spaced labels fit without colliding, counted back from the newest so the last one always shows.
useElementSize
hookA ref and the element's layout size from a ResizeObserver, 0 x 0 until mounted.
X_AXIS_HEIGHT
constantThe 24px reserved under the plot for the x axis labels.
chartLayout
functionThe plot rectangle inside the chart, with room for the measured y labels and the x axis.
DEFAULT_CHART_LABELS
constantThe English default strings: empty, loading, table caption, total, other, the inspect hint and legend toggles.
ChartSvg
componentThe aria-hidden svg drawing surface, sized to the container.
ChartGrid
componentHairline grid lines at the value ticks, horizontal or vertical, in a faint foreground tint.
ChartBaseline
componentA stronger line at one value, usually zero.
ChartReferenceLine
componentA dashed target or average line across the plot with an optional label.
ChartYAxis
componentThe value tick labels, 11px tabular and muted, on the start or end side.
ChartXAxis
componentThe x labels, thinned from the newest backwards so they never collide.
ChartCrosshair
componentThe vertical line that snaps to the inspected point.
ChartDot
componentA data point ringed in the surface color that grows when active.
ChartGradient
componentA linear gradient definition that fades a series color for area fills.
nearestIndex
functionThe index whose position is closest to x, by binary search over ascending positions.
useChartInspect
hookOne inspector for hover, tap and scrub, and arrow keys. Returns { activeIndex, setActiveIndex, source, layerId, handlers }.
ChartInspectLayer
componentThe focusable layer over the plot that receives pointer, touch and keys, with a live region for the keyboard readout.
ChartTooltip
componentThe readout of the inspected point: floats beside the crosshair or pins above the plot on touch, flipping near the edge.
ChartTooltipContent
componentThe tooltip's title, keyed rows and footer without the positioning, for custom popovers.
ChartKey
componentThe small swatch of a series: a line, dashed line, square or dot.
ChartLegend
componentKeys for two or more series with optional values, toggle buttons (aria-pressed) and hover or focus highlight.
ChartDataTable
componentThe table of numbers every chart ships, screen reader only unless visible is set.
ChartLoading
componentA skeleton in the chart's shape (bars, line, donut, gauge or grid) with an accessible label.
ChartEmpty
componentThe empty state shown in the plot's box, with an optional icon and message.
markTransition
functionA spring transition for bars and segments with a capped stagger per index.
DRAW_TRANSITION
constantThe ease-out tween that draws lines in through pathLength.
ChartSeries
type{ key, label?, color?, name? }: one series a chart reads from the data.
ChartFormatOptions
type{ format?, currency?, decimals?, locale? } for the value and tick formatters.
ChartLayout
typeThe plot rectangle: left, right, top, bottom, innerWidth, innerHeight and yAxisWidth.
ChartLabels
typeThe strings a chart can override: empty, loading, table, total, other, inspectHint and the legend toggles.
ChartTooltipItem
typeOne tooltip row: { key, label, value, color?, shape?, muted? }.
ChartLegendItem
typeOne legend entry: { key, label, color, value?, hidden?, shape?, name? }.
ChartContainerProps
typeProps of ChartContainer: height, surface, animated, loading, empty, labels, table, header, footer and a render function.
Examples
Series palette
The eight categorical slots and their names.
Formatters
Money, compact ticks, percents and dates in en-US.
Visible data table
ChartDataTable as a real table under the chart.
Loading and empty
The plot keeps its height in every state.
Pinned touch tooltip
tooltipMode fixed, the default on coarse pointers.
Files
- lib/chart-kit.tsx
FAQ
Is the Chart kit helper free?
The preview, props and docs are free; copying the source needs a Pro plan. See plans.
How do I install Chart kit?
Run npx wingo-ui@latest add chart-kit. It also adds the Wingo UI items it builds on (useControllableState, useMediaQuery, Motion presets, Number format and Tones) and the npm packages motion, d3-scale and d3-shape. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/chart-kit.
See also
Used in
More React hooks and utilities
Articles using this component
- React Funnel Chart: Conversion, Drop-off and Cohorts
Component guides9 min read
- React Charts Tailwind: 4 Charts and a Kit for Any Theme
Component guides10 min read