skrewww

Content & Data

Bar Chart

Bar Chart is a single-series, static bar chart built on recharts — real proportional bar heights, month labels below, no Y-axis/gridlines/legend/tooltip.

Single component — no variants

betaReact AvailableFigma AvailableDocs Partial
React last updated
2026-07-18
Documentation last updated
2026-07-18
Accessibility target
WCAG 2.2 AA (target)
Version
0.1.0-beta

Known open questions

  • Multi-series support is deferred — not shown in the Figma reference and not built here; v1 is single-series only.
  • Interactivity (hover tooltips, legend interactivity) is deferred — v1 is deliberately static, per the approved v1 scope.
  • A Y-axis and gridlines beyond the existing X-axis month labels are deferred — not shown in the Figma reference.
  • Bar corner radius/spacing beyond fill color and the X-axis label treatment is this implementation's own decision, not something Figma specified.

Monthly signups

Single-series, static bar chart — real proportional bar heights, month labels below, no Y-axis/gridlines/legend/tooltip. The underlying data is also available to assistive tech via a visually-hidden table.

Signups by month

Monthly signups
LabelValue
Jan58
Feb95
Mar76
Apr128
May108
Jun140

Purpose

A single-series, static bar chart for comparing categorical values (e.g. monthly totals).

Anatomy

A recharts BarChart inside ResponsiveContainer (fluid width, fixed height — genuinely fills its parent, not a fixed pixel box), one Bar per datum filled with semantic/action/primary, and an XAxis rendering only text labels (axisLine and tickLine both disabled) in semantic/text/secondary. A visually-hidden (`sr-only`) data table with the same label/value pairs is rendered alongside, and the chart's own SVG is aria-hidden with role="img" + aria-label + aria-describedby pointing at the table — so the underlying data is genuinely available to assistive tech, not just implied by bar heights.

Variants and states

default

When to use

Comparing discrete categorical values at a glance where exact precision matters less than relative comparison.

When not to use

Multi-series comparisons, interactive drill-down, or trend-over-time data — use Line Chart for trends; multi-series is deferred for both.

Accessibility

role="img" with an accessible name, plus a visually-hidden (sr-only) data table with the same label/value pairs linked via aria-describedby — bar heights alone convey nothing to assistive tech.

Common mistakes

Treating "static" as "no accessibility work needed" — the hidden data table is required, not optional polish. Building multi-series or interactive (tooltip/legend) variants that are explicitly deferred for v1.

Properties

data ({ label, value }[]). label (accessible name / hidden table caption). height (fixed pixel height, default 240 — width is fluid, filling the parent).

Why ResponsiveContainer instead of fixed pixel dimensions?

A real consumer embeds this in a variable-width dashboard/card, so the chart should genuinely fill its parent — fixed dimensions were an earlier draft, justified partly by a jsdom/ResizeObserver test limitation that has a standard fix (a ResizeObserver polyfill in vitest.setup.ts) rather than a reason to constrain real-world sizing. Height stays a fixed prop (default 240) since chart height is typically design-determined, not fluid.

Why is there no Y-axis?

Figma's own "Bar Chart (example)" frame has no Y-axis, gridlines, legend, or tooltip — only bars and X-axis month labels. This component matches that reference exactly rather than inferring additional chrome Figma didn't show.

How is the underlying data exposed to screen readers?

A visually-hidden (sr-only) table with the same label/value pairs, linked to the chart via aria-describedby. Bar heights alone convey nothing to assistive tech, so this is a real accessibility mechanism, not optional polish.

Tokens used

semantic/action/primarysemantic/text/secondary

Component API

PropTypeDefaultDescription
data{ label: string; value: number }[]Single-series data. Multi-series is deferred.
labelstringAccessible name for the chart — also used as the hidden data table's caption.
heightnumber240Fixed pixel height. Width is fluid (ResponsiveContainer), filling the parent.

React example

Copy React example
import { BarChart } from "@/components/ui";

const monthlySignups = [
  { label: "Jan", value: 58 },
  { label: "Feb", value: 95 },
  { label: "Mar", value: 76 },
  { label: "Apr", value: 128 },
  { label: "May", value: 108 },
  { label: "Jun", value: 140 },
];

export function Example() {
  return <BarChart data={monthlySignups} label="Monthly signups" />;
}