Components
- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input OTP
- Input Group
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Toggle Group
- Tooltip
- New Component
Elements
Charts
Icons
Monthly activity
User growth
import { Area, AreaChart, Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts";
import type { ChartConfig } from "@/components/ui/chart";
import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart";
const barData = [
{ components: 12, installs: 84, month: "Jan" },
{ components: 18, installs: 130, month: "Feb" },
{ components: 24, installs: 198, month: "Mar" },
{ components: 31, installs: 240, month: "Apr" },
{ components: 38, installs: 312, month: "May" },
{ components: 45, installs: 390, month: "Jun" },
];
const barConfig = {
components: { color: "var(--color-primary)", label: "Components" },
installs: { color: "var(--color-muted-foreground)", label: "Installs" },
} satisfies ChartConfig;
const areaData = [
{ month: "Jan", users: 420 },
{ month: "Feb", users: 680 },
{ month: "Mar", users: 910 },
{ month: "Apr", users: 1240 },
{ month: "May", users: 1580 },
{ month: "Jun", users: 2100 },
];
const areaConfig = {
users: { color: "var(--color-primary)", label: "Active users" },
} satisfies ChartConfig;
export const ChartDemo = () => (
<div className="flex flex-col gap-8">
{/* Bar chart */}
<div className="flex flex-col gap-2">
<p className="text-sm font-medium">Monthly activity</p>
<ChartContainer config={barConfig} className="h-52">
<BarChart data={barData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} />
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
<Bar dataKey="components" fill="var(--color-components)" radius={4} />
<Bar dataKey="installs" fill="var(--color-installs)" radius={4} />
</BarChart>
</ChartContainer>
</div>
{/* Area chart */}
<div className="flex flex-col gap-2">
<p className="text-sm font-medium">User growth</p>
<ChartContainer config={areaConfig} className="h-52">
<AreaChart data={areaData}>
<defs><linearGradient id="fillUsers" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="var(--color-users)" stopOpacity={0.3} />
<stop offset="95%" stopColor="var(--color-users)" stopOpacity={0} />
</linearGradient></defs>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} />
<ChartTooltip content={<ChartTooltipContent />} />
<Area
type="monotone"
dataKey="users"
stroke="var(--color-users)"
fill="url(#fillUsers)"
strokeWidth={2}
/>
</AreaChart>
</ChartContainer>
</div>
</div>
);ChartConfig
ChartConfig maps each data key to a label and a color. Colors are injected as CSS variables (--color-{key}) scoped to the chart container, so Recharts stroke and fill can reference them as var(--color-{key}).
import type { ChartConfig } from "@/components/ui/chart";
const config: ChartConfig = {
revenue: {
label: "Revenue",
color: "hsl(var(--chart-1))",
},
expenses: {
label: "Expenses",
color: "hsl(var(--chart-2))",
},
};Use the theme key instead of color to supply different values per color scheme.
const config: ChartConfig = {
revenue: {
label: "Revenue",
theme: {
light: "#2563eb",
dark: "#60a5fa",
},
},
};Bar chart
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts";
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
<ChartContainer config={config} className="h-64 w-full">
<BarChart data={data}>
<CartesianGrid strokeDasharray="3 3" vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<YAxis tickLine={false} axisLine={false} />
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
<Bar dataKey="revenue" fill="var(--color-revenue)" radius={4} />
<Bar dataKey="expenses" fill="var(--color-expenses)" radius={4} />
</BarChart>
</ChartContainer>Area chart
Use a gradient fill for an area chart by defining a <defs> linearGradient and referencing it via url(#id).
import { Area, AreaChart, CartesianGrid, XAxis } from "recharts";
<ChartContainer config={config} className="h-64 w-full">
<AreaChart data={data}>
<defs>
<linearGradient id="fillRevenue" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="var(--color-revenue)" stopOpacity={0.3} />
<stop offset="95%" stopColor="var(--color-revenue)" stopOpacity={0} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<ChartTooltip content={<ChartTooltipContent />} />
<Area
dataKey="revenue"
type="natural"
stroke="var(--color-revenue)"
fill="url(#fillRevenue)"
/>
</AreaChart>
</ChartContainer>Tooltip
ChartTooltipContent wraps Recharts' custom tooltip slot with design-system styles. Control the indicator shape with the indicator prop.
{/* Dot indicator (default) */}
<ChartTooltip content={<ChartTooltipContent indicator="dot" />} />
{/* Line indicator */}
<ChartTooltip content={<ChartTooltipContent indicator="line" />} />
{/* Dashed line indicator */}
<ChartTooltip content={<ChartTooltipContent indicator="dashed" />} />
{/* Hide the label row */}
<ChartTooltip content={<ChartTooltipContent hideLabel />} />Legend
ChartLegendContent renders labeled color swatches for each series in the config.
{/* Show legend */}
<ChartLegend content={<ChartLegendContent />} />
{/* Hide the series icon */}
<ChartLegend content={<ChartLegendContent hideIcon />} />Props
ChartContainer
| Prop | Type | Default | Description |
|---|---|---|---|
config | ChartConfig | — | Required. Maps keys to labels and colors |
initialDimension | { width?: number; height?: number } | — | Initial size hint for server rendering |
className | string | — | Additional CSS classes. Set a height (e.g. h-64) |
ChartTooltipContent
| Prop | Type | Default | Description |
|---|---|---|---|
hideLabel | boolean | false | Hide the category label row |
hideIndicator | boolean | false | Hide the color swatch/indicator |
indicator | "dot" | "line" | "dashed" | "dot" | Shape of the per-series color indicator |
nameKey | string | — | Override which key is used as the series name |
ChartLegendContent
| Prop | Type | Default | Description |
|---|---|---|---|
hideIcon | boolean | false | Hide the color icon next to each label |
nameKey | string | — | Override which key is used as the series name |
Usage
import { Bar, BarChart, XAxis } from "recharts";
import type { ChartConfig } from "@/components/ui/chart";
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
const config: ChartConfig = {
sales: { label: "Sales", color: "hsl(var(--chart-1))" },
};
const data = [
{ month: "Jan", sales: 186 },
{ month: "Feb", sales: 305 },
{ month: "Mar", sales: 237 },
];
export function SalesChart() {
return (
<ChartContainer config={config} className="h-48 w-full">
<BarChart data={data}>
<XAxis dataKey="month" tickLine={false} axisLine={false} />
<ChartTooltip content={<ChartTooltipContent />} />
<Bar dataKey="sales" fill="var(--color-sales)" radius={4} />
</BarChart>
</ChartContainer>
);
}Specs
# Mint — Chart Specs
## Component
- name: chart
- file: registry/mint/chart.tsx
- installs to: components/ui/chart.tsx
- dependencies: recharts
- registryDependencies: none
## What is it
A composable Recharts integration that handles color theming and layout boilerplate.
ChartContainer wraps Recharts' ResponsiveContainer and injects per-series colors as
scoped CSS custom properties. Use it whenever you need a consistently themed chart;
do not use it if you need a fully custom Recharts setup that manages its own container.
## Visual identity
Tooltip floats on the page background with a soft, glassy border and xl shadow,
now with Mint's generous rounded corners, giving it a card-like appearance.
Legend swatches use 2px-rounded squares. Axis tick text is rendered in
--muted-foreground to keep it recessive. Series colors come entirely from
ChartConfig, so each theme can define its own palette — the chart component
itself carries no fixed color bias.
## Design tokens
--muted-foreground: oklch(0.52 0.06 155) / oklch(0.6 0.06 155) — axis tick text, series labels in tooltip
--border: oklch(0.88 0.04 155 / 60%) / oklch(0.32 0.05 155 / 40%) — tooltip border, cartesian grid lines
--background: oklch(1 0 0) / oklch(0.145 0 0) — tooltip surface (bg-background)
--foreground: oklch(0.145 0 0) / oklch(0.985 0 0) — tooltip value text
--muted: oklch(0.96 0.02 155) / oklch(0.2 0.03 155) — tooltip cursor rectangle fill
## Sub-components
- ChartContainer → root div; wraps ResponsiveContainer and provides ChartContext
- ChartStyle → injects scoped --color-{key} CSS vars per ChartConfig entry
- ChartTooltip → re-export of recharts Tooltip (pass as the tooltip prop)
- ChartTooltipContent → styled tooltip body with indicator, label, and value rows
- ChartLegend → re-export of recharts Legend (pass as the legend prop)
- ChartLegendContent → styled legend row with color swatches and labels
## External dependencies
- recharts: provides ResponsiveContainer, Tooltip, Legend, and all chart primitives
## States
- active tooltip: ChartTooltipContent renders only when active=true and payload is non-empty
- nestLabel: when payload has exactly one item and indicator is not "dot", the category
label moves inside the value row instead of appearing above it
## Conventions
- Always set an explicit height on ChartContainer (e.g. h-48, h-64); width defaults to 100%
- Pass all chart data to the Recharts chart component (BarChart, AreaChart, etc.) — not to ChartContainer
- Do not nest a second ResponsiveContainer inside ChartContainer
- Use hsl(var(--chart-1)) through hsl(var(--chart-5)) in ChartConfig for theme-consistent series colors
- Use the theme key instead of color in ChartConfig when light and dark values must differ
- Use nameKey on ChartTooltipContent / ChartLegendContent to disambiguate series when dataKey differs from the config key
- Sub-components expose data-slot="chart" on ChartContainer for CSS targetingInstallation
$ npx shadcn add \https://gin-design.vercel.app/chart