Skip to main content

ChartCard

Implemented

Card with a header (title + range-pill radiogroup selector) and a line-chart body (unfilled polyline rendered by the Chart organism). Used for Revenue Overview.

Categoryorganisms
Sourcecomponents/organisms/ChartCard/ChartCard.tsx
AI HintUse for complex UI sections. Compose molecules and atoms into page sections.

ChartCard component.

ChartCard

design-system

ChartCard component preview and API reference.

Revenus

Accessibility

The range pills are a role="radiogroup" — each pill a role="radio" with aria-checked, the group labeled `${title} — ${suffix}` where the suffix is locale-aware (EN "range", FR "période") via the locale prop — FR labels are announced correctly (WCAG 1.3.1 / 4.1.2). Roving tabindex keeps exactly ONE tab stop (the checked pill, else the first); Arrow keys move focus AND select, and Home/End jump to the first/last pill without changing the selection, per the WAI-ARIA APG radio group pattern. Pills meet the 44×44 minimum tap target via --ep-tap-min (WCAG 2.5.5), and the active state is legible without color (inverted surface + font-semibold vs font-medium — WCAG 1.4.1). The card is a role="region" named by its heading via aria-labelledby — do not duplicate the title into ariaLabel (screen-reader users would hear it twice; all storefront consumers dropped redundant ariaLabel props in S6); an explicit ariaLabel is an override for the rare case the visible heading is not the right accessible name. When more than 6 ranges are passed, the extras are dropped and the clamp is disclosed twice, both strings locale-aware: an sr-only paragraph inside the group (announced by screen readers, WCAG 1.3.1) and the group's title tooltip for mouse hover ("Showing first 6 of N ranges"). The default body delegates to Chart (sr-only data table); when using the chart slot, bring your own accessible chart body.

Props

Prop
Type
Default
Description
title
string
—

Card heading. Also used as the region accessible-name fallback (named by the heading via aria-labelledby).

ranges
ChartCardRange[] — { id: string; label: string }
—

Range selector options rendered as a radiogroup (roving tabindex, Arrow/Home/End navigation). At most the first 6 are rendered — extras are dropped and the group carries a title tooltip disclosing the clamp. Pills meet the 44px tap target via --ep-tap-min.

activeRange
string
—

id of the active range pill (controlled).

onRangeChange
(id: string) => void
—

Called when a range pill is selected (click OR Arrow-Left/Right/Up/Down per WAI-ARIA APG radio group — arrows move focus AND select). Home/End move focus only, without selecting.

data
{ points: { x: number; y: number }[]; labels: string[] }
—

Line chart data for the default body. Ignored when `chart` is provided.

ariaLabel
string
—

Accessible-name override for the region. Default: no aria-label — the region is named by its heading (title) via aria-labelledby; an explicit ariaLabel switches to aria-label and drops the labelledby.

chart
React.ReactNode
—

Optional custom chart body (§126 Wave 3 gap-2) — replaces the default line Chart for multi-series bodies.

srTableCaption
string
—

i18n passthrough to the default Chart's sr-only data table caption (mirrors Chart). Chart renders title ?? srTableCaption, and ChartCard always passes its required title — the card title stays the caption; accepted for API parity with Chart. Ignored when `chart` is set.

srLabelHeader
string
—

i18n passthrough to the default Chart's sr-only table label-column header. English default "Label"; FR consumers pass e.g. "Étiquette". Ignored when `chart` is set.

srValueHeader
string
—

i18n passthrough to the default Chart's sr-only table value-column header. English default "Value"; FR consumers pass e.g. "Valeur". Ignored when `chart` is set.

locale
"en" | "fr"
—

Locale for the built-in chrome strings — the radiogroup aria-label suffix (EN "range", FR "période") and the range-clamp disclosure localize, so FR labels are announced correctly. Default "en".

className
string
—

Appended to the section classes for consumer layout control (grid column spans, widths).

Props

Preview

ChartCard

Prop
Type
Required
Default
Description
title
string
Required
—
No description.
ranges
ChartCardRange[] — { id: string; label: string }
Required
—
No description.
data
{ points: { x: number; y: number }[]; labels: string[] }
Required
—
No description.
activeRange
string
Required
—

Synced from source — no interface JSDoc yet; document on `ChartCard.tsx`.

onRangeChange
(id: string) => void
Required
—

Synced from source — no interface JSDoc yet; document on `ChartCard.tsx`.

ariaLabel
string
Optional
—

Accessible-name override for the card region. Default: no aria-label — the region is named by its h3 title via aria-labelledby; an explicit ariaLabel switches to aria-label and drops the labelledby. Do not duplicate the title into ariaLabel (all 3 storefront consumers dropped redundant ariaLabel props in the S6 conformance pass).

chart
React.ReactNode
Optional
—

Custom chart body (§126 Wave 3 gap-2) — renders instead of the default line Chart for multi-series bodies. data is ignored when set.

srTableCaption
string
Optional
—

i18n passthrough to the default Chart's sr-only table caption (mirrors Chart). Chart renders title ?? srTableCaption — the card title stays the caption; accepted for API parity with Chart.

srLabelHeader
string
Optional
—

i18n passthrough to the default Chart's sr-only table label-column header. English default "Label"; FR consumers pass e.g. "Étiquette". Unused when a chart slot is set.

srValueHeader
string
Optional
—

i18n passthrough to the default Chart's sr-only table value-column header. English default "Value"; FR consumers pass e.g. "Valeur". Unused when a chart slot is set.

locale
"en" | "fr"
Optional
'en'

Locale for the built-in chrome strings (radiogroup aria-label suffix + range-clamp disclosure). FR consumers pass "fr" — accessible names and the clamp disclosure localize. English default.

className
string
Optional
—

Appended to the section classes for consumer layout control (grid col spans, widths).

Quick use:<ChartCard />

Accessibility

ARIA roleregion

Type

1 rule

NASA Rule 2 + 5

5 of 12 props required; ranges clamped to the first 6 (MAX_RANGES — no minimum enforced)

ARIA

1 rule

WCAG 1.1.1

Chart wrapper must have role='region' and aria-label; chart SVG itself must be aria-hidden (text alternative provided separately)

Usage

Import

tsxSnippet
import { ChartCard } from "@epasslive/design-system"

Example 1

tsxSnippet
<ChartCard title="Revenue" ranges={ranges} activeRange={activeRange} onRangeChange={setActiveRange} data={data} locale={chartLocale} srLabelHeader={t("srLabelHeader")} srValueHeader={t("srValueHeader")} />

Anti-patterns

— Do not fetch data directly in organisms

— Avoid tight coupling to specific data sources

Design System v4.1.0 | ePassLive