Docs

Theming

Charts follow your shadcn tokens for text, surfaces and fonts, with a colour order you can override at every level.

Colours

A series takes the first colour that applies:

  1. A colour in config for that key: color, theme (light and dark), or colors (gradient stops). TypeScript accepts only one of the three. shadcn's ChartConfig entries work as they are.
  2. --bc-series-N, if you set it.
  3. The theme's own palette (the default), checked at 3:1 contrast or better against the surface in light and dark.
  4. Your --chart-1…5, when you opt in with palette="shadcn" or the class bc-use-shadcn-colors on any ancestor.

A series keeps its colour when others are hidden or reordered: its N is its position in config. To build a palette, the colour tools check contrast and colour-blind safety.

import type { ChartConfig } from "@/components/beautiful-charts/core/contracts";

export const config = {
  revenue: { label: "Revenue", color: "var(--chart-1)" }, // one colour
  costs: { label: "Costs", theme: { light: "#b42318", dark: "#f97066" } }, // per theme
  margin: { label: "Margin", colors: { light: ["#c7d2fe", "#4338ca"] } }, // gradient stops
} satisfies ChartConfig;

/* Recolour every chart in a section, without touching props. */
.billing {
  --bc-series-1: oklch(0.55 0.2 264);
  --bc-series-2: oklch(0.62 0.15 160);
  --bc-radius: 12px;
  --bc-font-mono: "JetBrains Mono", ui-monospace, monospace;
}

/* Use your shadcn --chart-1..5 everywhere under this element. */
<section className="bc-use-shadcn-colors">...</section>

Dark mode and your tokens

Text, hairlines, surface, good and bad tones, focus ring, fonts and radius follow your shadcn tokens, each with a --bc-* override. Dark mode applies under .dark or [data-theme="dark"], and a .light section inside a dark page stays light. HSL-channel tokens (Tailwind 3) work with the bc-hsl-tokens class on <html>.

Styling hooks

className goes on the card, and classes you pass always win. Every part carries a data-slot (chart-title, chart-legend, chart-plot, chart-tooltip, chart-table and so on), and the root carries data-state and data-density. Theme rules sit inside :where(), so .my-chart [data-slot="chart-title"] overrides them without !important. For anything deeper, edit the installed source: it's yours.

Themes

A theme restyles every chart and block: type, marks, texture and motion. Instrument is free and MIT. Riso prints in spot inks with overprint and grain. Clay is soft and pressed, with springy motion. Every Pro component takes exactly the props of its Instrument version:

// Instrument (free)
import { AreaChart } from "@/components/beautiful-charts/themes/instrument/recharts/area-chart";
// Riso or Clay (Pro): the same props, a different folder
import { AreaChart } from "@/components/beautiful-charts/themes/riso/recharts/area-chart";

See them side by side on the themes page, or switch the theme on any component's page.