ChartCard
ImplementedCard with a header (title + range-pill radiogroup selector) and a line-chart body (unfilled polyline rendered by the Chart organism). Used for Revenue Overview.
components/organisms/ChartCard/ChartCard.tsxChartCard component.
ChartCard
design-system
ChartCard component preview and API reference.
Revenus
| Étiquette | Valeur |
|---|---|
| Lun | 1200 |
| Mar | 1800 |
| Mer | 1500 |
| Jeu | 2200 |
| Ven | 2800 |
| Sam | 2400 |
| Dim | 3100 |
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
titlestringCard heading. Also used as the region accessible-name fallback (named by the heading via aria-labelledby).
rangesChartCardRange[] — { 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.
activeRangestringid of the active range pill (controlled).
onRangeChange(id: string) => voidCalled 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.
ariaLabelstringAccessible-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.
chartReact.ReactNodeOptional custom chart body (§126 Wave 3 gap-2) — replaces the default line Chart for multi-series bodies.
srTableCaptionstringi18n 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.
srLabelHeaderstringi18n 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.
srValueHeaderstringi18n 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".
classNamestringAppended to the section classes for consumer layout control (grid column spans, widths).
Props
ChartCard
titlestring—rangesChartCardRange[] — { id: string; label: string }—data{ points: { x: number; y: number }[]; labels: string[] }—activeRangestring—Synced from source — no interface JSDoc yet; document on `ChartCard.tsx`.
onRangeChange(id: string) => void—Synced from source — no interface JSDoc yet; document on `ChartCard.tsx`.
ariaLabelstring—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).
chartReact.ReactNode—Custom chart body (§126 Wave 3 gap-2) — renders instead of the default line Chart for multi-series bodies. data is ignored when set.
srTableCaptionstring—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.
srLabelHeaderstring—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.
srValueHeaderstring—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"'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.
classNamestring—Appended to the section classes for consumer layout control (grid col spans, widths).
<ChartCard />Accessibility
Type
1 ruleARIA
1 ruleUsage
Import
import { ChartCard } from "@epasslive/design-system"Example 1
<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