Chart
Recharts wrapper with tokens.
Import
tsx
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@cooud-ui/ui";
bash
npx cooud-ui add chart
Recharts wrapper with tokens.
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@cooud-ui/ui";
npx cooud-ui add chart
A recharts BarChart composed inside ChartContainer. The ChartConfig maps each series to a theme token, exposed to bars as `var(--color-*)`.
const chartConfig = {revenue: { label: "Revenue", color: "var(--cooud-primary)" },profit: { label: "Profit", color: "var(--cooud-info)" },} satisfies ChartConfig;const chartData = [{ month: "Jan", revenue: 4200, profit: 1400 },{ month: "Feb", revenue: 3800, profit: 1100 },{ month: "Mar", revenue: 5200, profit: 1900 },{ month: "Apr", revenue: 4900, profit: 1700 },{ month: "May", revenue: 6100, profit: 2400 },{ month: "Jun", revenue: 7300, profit: 3100 },];return (<ChartContainer config={chartConfig} className="h-64 w-full"><BarChart accessibilityLayer data={chartData}><CartesianGrid vertical={false} /><XAxis dataKey="month" tickLine={false} tickMargin={10} axisLine={false} /><ChartTooltipcursor={{ fill: "var(--cooud-fg)", fillOpacity: 0.05, radius: 8 }}content={<ChartTooltipContent />}/><Bar dataKey="revenue" fill="var(--color-revenue)" radius={4} /><Bar dataKey="profit" fill="var(--color-profit)" radius={4} /></BarChart></ChartContainer>);
A traffic-sources donut. Each slice maps to a theme token via the ChartConfig and renders through `Cell`, with a legend and tooltip wired to the same config.
const chartConfig = {visitors: { label: "Visitors" },direct: { label: "Direct", color: "var(--cooud-chart-1)" },organic: { label: "Organic", color: "var(--cooud-chart-2)" },referral: { label: "Referral", color: "var(--cooud-chart-3)" },social: { label: "Social", color: "var(--cooud-chart-4)" },email: { label: "Email", color: "var(--cooud-chart-5)" },} satisfies ChartConfig;const chartData = [{ source: "direct", visitors: 4200, fill: "var(--color-direct)" },{ source: "organic", visitors: 3100, fill: "var(--color-organic)" },{ source: "referral", visitors: 1900, fill: "var(--color-referral)" },{ source: "social", visitors: 1400, fill: "var(--color-social)" },{ source: "email", visitors: 800, fill: "var(--color-email)" },];return (// Data is exposed to assistive tech via the label; the SVG internals (recharts// tags each sector role="img" with no name) are hidden so they're not announced.<divrole="img"aria-label="Donut chart of traffic sources by visitors: Direct 4,200, Organic 3,100, Referral 1,900, Social 1,400, Email 800."className="h-64 w-full"><div aria-hidden="true" className="h-full w-full"><ChartContainer config={chartConfig} className="h-full w-full"><PieChart><ChartTooltip content={<ChartTooltipContent hideLabel />} /><Piedata={chartData}dataKey="visitors"nameKey="source"innerRadius={64}outerRadius={98}paddingAngle={3}cornerRadius={6}strokeWidth={0}rootTabIndex={-1}>{chartData.map((entry) => (<Cell key={entry.source} fill={entry.fill} />))}<Labelcontent={({ viewBox }) => {if (!viewBox || !("cx" in viewBox) || !("cy" in viewBox)) return null;const { cx, cy } = viewBox;return (<text x={cx} y={cy} textAnchor="middle" dominantBaseline="middle"><tspan x={cx} y={cy} className="fill-fg font-semibold text-2xl">11.4K</tspan><tspan x={cx} y={(cy ?? 0) + 22} className="fill-fg-tertiary text-xs">Visitors</tspan></text>);}}/></Pie><ChartLegend content={<ChartLegendContent nameKey="source" />} /></PieChart></ChartContainer></div></div>);
A two-series radar comparing Current vs Target across six metrics. Each Radar reads its fill and stroke from the config token, so themes recolor both shapes at once.
const chartConfig = {current: { label: "Current", color: "var(--cooud-primary)" },target: { label: "Target", color: "var(--cooud-info)" },} satisfies ChartConfig;const chartData = [{ metric: "Speed", current: 86, target: 95 },{ metric: "Reliability", current: 72, target: 90 },{ metric: "Coverage", current: 91, target: 88 },{ metric: "Security", current: 78, target: 96 },{ metric: "Usability", current: 84, target: 80 },{ metric: "Support", current: 69, target: 85 },];return (<divrole="img"aria-label="Radar chart comparing Current vs Target across six metrics — Speed 86/95, Reliability 72/90, Coverage 91/88, Security 78/96, Usability 84/80, Support 69/85."className="h-64 w-full"><div aria-hidden="true" className="h-full w-full"><ChartContainer config={chartConfig} className="h-full w-full"><RadarChart data={chartData}><ChartTooltip content={<ChartTooltipContent />} /><PolarGrid /><PolarAngleAxis dataKey="metric" /><Radar dataKey="current" fill="var(--color-current)" fillOpacity={0.6} stroke="var(--color-current)" /><Radar dataKey="target" fill="var(--color-target)" fillOpacity={0.15} stroke="var(--color-target)" /><ChartLegend content={<ChartLegendContent />} /></RadarChart></ChartContainer></div></div>);
Visitors-by-device drawn as concentric radial bars with rounded ring caps. The tracked `background` ring and `cornerRadius` give each device a clean gauge read.
const chartConfig = {visitors: { label: "Visitors" },desktop: { label: "Desktop", color: "var(--cooud-chart-1)" },mobile: { label: "Mobile", color: "var(--cooud-chart-2)" },tablet: { label: "Tablet", color: "var(--cooud-chart-3)" },other: { label: "Other", color: "var(--cooud-chart-4)" },} satisfies ChartConfig;const chartData = [{ device: "desktop", visitors: 5200, fill: "var(--color-desktop)" },{ device: "mobile", visitors: 4100, fill: "var(--color-mobile)" },{ device: "tablet", visitors: 1800, fill: "var(--color-tablet)" },{ device: "other", visitors: 900, fill: "var(--color-other)" },];return (<divrole="img"aria-label="Radial bar chart of visitors by device: Desktop 5,200, Mobile 4,100, Tablet 1,800, Other 900."className="h-64 w-full"><div aria-hidden="true" className="h-full w-full"><ChartContainer config={chartConfig} className="h-full w-full"><RadialBarChart data={chartData} innerRadius={32} outerRadius={110}><ChartTooltip content={<ChartTooltipContent hideLabel nameKey="device" />} /><PolarGrid gridType="circle" radialLines={false} stroke="none" /><RadialBar dataKey="visitors" background cornerRadius={8} /><ChartLegend content={<ChartLegendContent nameKey="device" />} /></RadialBarChart></ChartContainer></div></div>);