Ballmac UI home

Chart Frame

The card around a Recharts chart: a Table view with CSV download, a legend that toggles series, patterns so series differ by more than color, a summary for screen readers, and loading, empty and error states.

Response time

Milliseconds, per week

6 points. Median: from 118 ms in W1 to 98 ms in W6; highest 121 ms in W2, lowest 98 ms in W6. 95th percentile: from 242 ms in W1 to 205 ms in W6; highest 251 ms in W2, lowest 205 ms in W6.

Installation

$ pnpm dlx shadcn@latest add @ballmac/chart-frame

Usage

import { ChartFrame, ChartTable, describeChart, niceScale, domainTicks } from "@/components/ballmac/chart-frame"

The full example is in the Code tab above.

Examples

Loading

Response time

Milliseconds, per week

Loading Response time

No data yet

Response time

Milliseconds, per week

No requests yet

Response times appear after the first request.

Could not load

Response time

Milliseconds, per week

API reference

PropTypeDefault
title*

The chart's name. It heads the frame and names the figure for screen readers.

string—
descriptionstring—
data*

The rows the chart draws. The table, the CSV and the written summary are made from them.

ChartRow[]—
xKey*

The key of each row's category (the x axis).

string—
series*

What the legend lists and what colors the chart: one entry per number.

ChartSeries[]—
children*

Draws the chart. Return a Recharts chart (`AreaChart`, `BarChart`…) and use what `chart` gives you.

(chart: ChartFrameContext) => React.ReactElement—
legend

"toggle": a legend whose items switch series on and off. "static": a plain legend. "none". Defaults to "toggle" with two or more series.

"toggle" | "static" | "none"—
tableView

Show the Chart and Table switch. Defaults to true.

booleantrue
patterns

`true` always draws patterns as well as colors. "toggle" adds a switch for it.

boolean | "toggle"—
summary

The sentence screen readers get. It is written from the data when you leave it out.

string—
summaryMode

How the summary reads the data: as a trend over `xKey`, as a ranking of categories, or as shares of a whole.

"trend" | "ranking""trend"
valueFormatter

Writes a number in the tooltip, the table and the summary.

(value: number, seriesKey: string) => string—
categoryFormatter

Writes a category in the table and the summary.

(value: unknown) => string—
aspect

The shape of the plot.

"video" | "wide" | "panorama" | "square" | "tall""video"
actions

Controls beside the view switch, for example a range picker.

React.ReactNode—
footer

Content under the chart.

React.ReactNode—
skeleton

What shows while loading: a shape that matches the chart, or your own node.

"area" | "bars" | "donut" | "lines" | "radar" | React.ReactNode"area"
table

Replace the table with your own columns and rows, for charts whose data is not a simple series per column.

{ columns: TableColumn[]; rows: ChartRow[] }—
downloadName

Names the downloaded file (without .csv). Pass `false` to hide the download button.

string | false—
categoryLabel

The first column's header in the table.

string—
localestring—
chartClassName

Extra classes for the chart area.

string—
columns*TableColumn[]—
rows*ChartRow[]—

Also accepts the standard attributes of its root element.

Accessibility

KeyAction
Tab, Enter / SpaceEach legend item is a button that switches its series off or on (at least one stays on)
Chart / Table switchShows the same numbers as an accessible table with row and column headers, and a CSV download
Screen readersThe figure has a name and a summary written from the data (first to last, highest and lowest, or a ranking); pass summary to say what it means
PatternsSeries are filled with stripes, dots and hatching as well as color, so color is never the only signal

Quality scorecard

7/7

Every applicable check passes

Measured in Chromium 153.0.8010.12 on October 19, 2026, on version 1.0.0, across 4 examples.

How we measure
  • Passed: Accessibility scan

    No serious or critical issues in light and dark, on a phone and a desktop (axe-core 4.13.0, WCAG 2.1 AA and best-practice rules).

  • Passed: Small screens

    No sideways scrolling at 360, 390 or 1280 px wide.

  • Passed: Reduced motion

    Every endless animation stops when the visitor asks for less motion.

  • Not applicable: Right to left

    Not mirrored by design: Recharts draws its axes in SVG coordinates, which do not mirror.

  • Passed: Clean console

    No console errors or React hydration errors while loading.

  • Passed: Keyboard

    5 tab stops, each showing a visible change when it takes focus. 4 documented keys.

  • Passed: Loading, empty and error

    Ships loading, empty, error states, each with an example.

  • Passed: Automated tests

    Covered by chart-frame.test.tsx.

  • For information: Footprint

    8.3 KB of source (gzip) in 1 file. Installs motion, lucide-react.

Automated checks find a subset of problems and do not replace testing with a screen reader and a keyboard in your own app. What they miss.

Use with AI

Wrap any Recharts chart: <ChartFrame title description data xKey series={[{ key, label }]}>{(chart) => <LineChart>…</LineChart>}</ChartFrame>. Use chart.color(key) for strokes, chart.fill(key) for fills, chart.isHidden(key) for `hide`, chart.defs in <defs>, chart.animate for isAnimationActive and chart.rtl to reverse the x axis. The frame adds a Chart/Table switch, a CSV download, a toggling legend, optional patterns, a written summary and state handling. Prefer the ready-made ChartArea, ChartBar, ChartLine, ChartPie, ChartRadar, ChartRadial or ChartScatter when one fits. With the shadcn MCP server set up (guide), ask your agent:

Add the Ballmac UI Chart Frame (@ballmac/chart-frame) to this project with the shadcn MCP, then use it where it fits.

Use it for

  • Any chart that people need to read, compare or export
  • A custom Recharts chart that should be accessible and handle loading and errors

Not for

  • A tiny inline trend (use sparkline)
  • A single ring value (use progress-ring)

Registry JSON: https://ui.ballmac.com/r/chart-frame.json

Credits

Free to use in personal and commercial projects.

Ballmac UI Pro

Need the whole screen, not one piece?

150 premium blocks (dashboards, settings, calendars, mail, shops, onboarding), a private shadcn registry and Figma tokens. Blocks that show data come with loading, empty and error states built in.

Not ready? Try three Pro blocks free

Leave your email and the blocks appear right here, ready to copy. Yours to use in any project.