Chart
Recharts wrappers with themed grid, tooltip and legend. A config maps each series to a label, icon and color exposed as CSS variables.
Playground
<ChartContainer config={salesConfig} className="aspect-auto h-[360px] w-full">
<BarChart
accessibilityLayer
data={salesData}
barCategoryGap={10}
margin={{ top: 12, left: 0, right: 24 }}
>
<CartesianGrid vertical={false} strokeDasharray="4 4" />
<XAxis
dataKey="date"
tickLine={false}
axisLine={false}
tickMargin={12}
interval={0}
tickFormatter={formatSalesAxis}
/>
<YAxis
tickLine={false}
axisLine={false}
tickMargin={8}
width={40}
domain={[0, 24000]}
ticks={salesTicks}
tickFormatter={(value) => (value === 0 ? "0" : `${value / 1000}k`)}
/>
<ChartTooltip
cursor={<ChartCursor />}
content={<ChartTooltipContent labelFormatter={formatSalesDate} />}
/>
<Bar dataKey="sales" fill="var(--color-sales)" barSize={14} radius={[2, 2, 0, 0]} />
</BarChart>
</ChartContainer>Preview
Wrap any recharts chart in ChartContainer with a config. Each config key becomes a --color-* CSS variable scoped to the chart, referenced from the series fill.
const chartConfig = {
sales: { label: "Sales", color: "var(--chart-7)" },
} satisfies ChartConfig
<ChartContainer config={chartConfig} className="aspect-auto h-[360px] w-full">
<BarChart
accessibilityLayer
data={salesData}
barCategoryGap={10}
margin={{ top: 12, left: 0, right: 24 }}
>
<CartesianGrid vertical={false} strokeDasharray="4 4" />
<XAxis
dataKey="date"
tickLine={false}
axisLine={false}
tickMargin={12}
interval={0}
tickFormatter={formatSalesAxis}
/>
<YAxis
tickLine={false}
axisLine={false}
tickMargin={8}
width={40}
domain={[0, 24000]}
ticks={salesTicks}
tickFormatter={(value) => (value === 0 ? "0" : `${value / 1000}k`)}
/>
<ChartTooltip
cursor={<ChartCursor />}
content={<ChartTooltipContent labelFormatter={formatSalesDate} />}
/>
<Bar dataKey="sales" fill="var(--color-sales)" barSize={14} radius={[2, 2, 0, 0]} />
</BarChart>
</ChartContainer>Installation
npx shadcn@latest add https://espresso-base-ui.vercel.app/r/chart.jsonUsage
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartStyle,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/components/ui/chart"
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"const config = {
sales: { label: "Sales", color: "var(--chart-7)" },
} satisfies ChartConfig
<ChartContainer config={config}>
<BarChart accessibilityLayer data={data}>
<Bar dataKey="sales" fill="var(--color-sales)" />
</BarChart>
</ChartContainer>Chart config
ChartConfig maps each data key to a label, an optional icon component, and either a single color or a per-theme theme record. ChartStyle (rendered automatically by the container) emits the values as --color-* variables, switching the theme record under the .dark selector.
const config = {
desktop: {
label: "Desktop",
theme: { light: "#2563eb", dark: "#60a5fa" },
},
mobile: {
label: "Mobile",
color: "var(--chart-5)",
},
} satisfies ChartConfigTooltip
ChartTooltip is the recharts Tooltip with position animation disabled; pass ChartTooltipContent as its content to get config-driven labels, indicator dots and formatted numeric values. The indicator can be a dot, a line or dashed, and the label row can be hidden or reformatted.
<ChartTooltip
cursor={false}
content={
<ChartTooltipContent
indicator="line"
labelFormatter={(value) => "Month: " + value}
/>
}
/>Legend
ChartLegend re-exports the recharts Legend; give it ChartLegendContent to render color chips (or the config's icons) with labels from the chart config.
<ChartLegend content={<ChartLegendContent />} />API reference
ChartContainer provides the config through context – ChartTooltipContent and ChartLegendContent must render inside it. The exported ChartConfig type keeps configs type-safe with satisfies.
ChartContainer
| Prop | Type | Default | Description |
|---|---|---|---|
| config | ChartConfig | – | Required. Maps series keys to label, icon and color / theme. Shared with tooltip and legend content via context. |
| children | ReactElement | – | A single recharts chart, rendered inside a ResponsiveContainer. |
| initialDimension | { width: number; height: number } | { width: 320, height: 200 } | Initial size for the ResponsiveContainer before measurement (avoids SSR layout jumps). |
ChartTooltipContent
| Prop | Type | Default | Description |
|---|---|---|---|
| indicator | "dot" | "line" | "dashed" | "dot" | Shape of the per-series color indicator. |
| hideLabel | boolean | false | Hide the tooltip's heading row. |
| hideIndicator | boolean | false | Hide the color indicator next to each series. |
| labelFormatter | (value, payload) => ReactNode | – | Custom renderer for the heading row. |
| formatter | (value, name, item, index, payload) => ReactNode | – | Fully custom renderer for each series row, replacing the default indicator + label + value. |
| nameKey | string | – | Payload key used to look up each series in the chart config (defaults to the series name / dataKey). |
| labelKey | string | – | Payload key used to look up the heading label in the chart config. |
ChartLegendContent
| Prop | Type | Default | Description |
|---|---|---|---|
| hideIcon | boolean | false | Show the plain color chip even when the config defines an icon. |
| verticalAlign | "top" | "bottom" | "bottom" | Where the legend sits – controls whether spacing is added above or below. |
| nameKey | string | – | Payload key used to look up legend items in the chart config. |
| Component | Description |
|---|---|
| ChartContainer | Root wrapper (data-slot="chart", plus a unique data-chart id). Applies all recharts overrides and renders ChartStyle + ResponsiveContainer. |
| ChartTooltip | recharts Tooltip with isAnimationActive defaulted to false so the tooltip doesn't replay from the origin on hover-driven re-renders. |
| ChartTooltipContent | Themed tooltip panel – reads labels, icons and colors from the chart config. |
| ChartLegend | Alias of the recharts Legend component. |
| ChartLegendContent | Themed legend row of color chips / icons with config labels. |
| ChartStyle | Emits the config's colors as scoped --color-* CSS variables per theme; rendered automatically by ChartContainer. |
Accessibility & styling hooks
Pass recharts' accessibilityLayer prop to your chart for keyboard navigation and screen-reader access to the data. The container scopes its color variables with a data-chart id and tags itself data-slot="chart"; series colors resolve per theme, so charts restyle automatically in dark mode. Reference any config key anywhere inside the chart as var(--color-key) – fills, strokes, even per-cell colors.