Overview
Charts use the aSaaSin Chart wrapper around Recharts. Use our wrapper to get consistent theming, responsive layout, tooltip/legend UI, and dark-mode colors from CSS variables.
Helpful references:
- shadcn/ui Chart docs - The wrapper patterns we follow: how to use the Chart container, tooltip, and legend together with Recharts.
- Theming guidance - How to drive series colors with CSS variables and support light/dark modes (matches our
ChartConfigapproach). - Recharts documentation - Reference for chart primitives, props, and examples you compose inside
ChartContainer(Line/Bar/Area/Pie, axes, grids).
Imports
Import from @/components/ui/Chart:
ChartContainer— context + responsive wrapper + CSS-var injectorChartTooltip,ChartTooltipContent— tooltip primitivesChartLegend,ChartLegendContent— legend primitivesChartStyle— internal style injector (added byChartContainer)ChartConfig— config type for series mapping
Compose Recharts primitives inside ChartContainer (e.g., LineChart, BarChart, PieChart, AreaChart, CartesianGrid, XAxis, Line, Bar, Pie, Label).
Series and colors
Define a ChartConfig where each series key maps to a label and a color. ChartContainer injects CSS variables like --color-desktop, --color-mobile scoped to the chart.
Two ways to provide color:
- Single color:
color: 'hsl(var(--chart-1))' - Theme map:
theme: { light: 'hsl(var(--chart-1))', dark: 'hsl(var(--chart-2))' }
Then use the injected vars in Recharts elements: stroke="var(--color-desktop)", fill="var(--color-mobile)". Gradients can reference the same variables. You can also set label and icon per series for tooltips/legend.
import type { ChartConfig } from '@/components/ui/Chart';
export const chartConfig = {
desktop: { label: 'Desktop', color: 'hsl(var(--chart-1))' },
mobile: { label: 'Mobile', color: 'hsl(var(--chart-2))' },
} satisfies ChartConfig;Layout and responsiveness
Wrap your chart with ChartContainer. It renders a ResponsiveContainer and normalizes Recharts internals (axis ticks, grid, cursors) to match the theme. Control size via parent layout or className (e.g., fixed height or aspect-square). accessibilityLayer on Recharts charts is supported.
'use client';
import * as React from 'react';
import { CartesianGrid, Line, LineChart, XAxis } from 'recharts';
import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/Chart';
import { chartConfig } from '@/charts/config';
const data = [
{ month: 'Jan', desktop: 12500, mobile: 8500 },
{ month: 'Feb', desktop: 14800, mobile: 9600 },
];
export function MinimalLine() {
return (
<ChartContainer config={chartConfig} className="w-full h-[240px]">
<LineChart data={data} accessibilityLayer margin={{ left: 12, right: 12 }}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} />
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
<Line dataKey="desktop" type="monotone" stroke="var(--color-desktop)" strokeWidth={2} dot={false} />
<Line dataKey="mobile" type="monotone" stroke="var(--color-mobile)" strokeWidth={2} dot={false} />
</LineChart>
</ChartContainer>
);
}Tooltip
Use ChartTooltip with ChartTooltipContent. Key props:
indicator:'dot' | 'line' | 'dashed'(defaultdot)hideLabel,hideIndicatorlabelKey,nameKeylabelFormatter,formatter
Labels and colors resolve from ChartConfig, so you don’t duplicate strings or colors.
Legend
Use ChartLegend with ChartLegendContent. Props: verticalAlign ('top' | 'bottom'), hideIcon, nameKey. Each item maps to the series label/icon from ChartConfig, with an automatic color swatch.
Usage patterns
- Line / Bar: map each data key to a series in
ChartConfig, thenstroke="var(--color-key)"orfill="var(--color-key)". - Pie / Donut: each datum may carry
fill: 'var(--color-key)'; tooltip labels come from config. - Area with gradient: define a
<linearGradient>and usestopColor="var(--color-key)", thenfill="url(#…)"andstroke="var(--color-key)". - Interactive ranges: filter
datain state (e.g., 7d / 30d / 90d); the wrapper keeps colors and layout in sync.
Data shape
- Use stable series keys (
desktop,mobile,visitors, …) and reuse them inChartConfig. - X values can be strings or dates; format with
tickFormatter/labelFormatter. - For donut charts, include
fillper row or rely on the series variables.
Accessibility and theming
Colors come from CSS tokens (--chart-1…5) and switch with .dark. Tooltip/legend text uses your theme fonts; axes and grid colors are normalized by the wrapper. For different light/dark colors, use the theme map in ChartConfig.
When to choose
- One or two time-series - Line
- Category totals - Bar
- Part-to-whole - Pie/Donut
- Emphasize totals with smooth fill - Area (gradient)
Notes
- Keep series color logic in
ChartConfig; avoid hardcoded hex in Recharts props. - Prefer short tick labels; use
minTickGapandtickFormatterto prevent overlap. - For stacked areas/bars, share a
stackIdacross series.