Passer au contenu principal

StatTable

Implemented

Multi-section stats table with totals, subtotals per product type. Thuwan-mandated format: Total Available → Ticket Counts → Sales → ePassLive Fees → Transfer to Bank Account. DS-STAT-01 multi-column contract (one <th scope='col'> per declared column) when `columns` is supplied; legacy 2-column (Metric + Amount) when omitted. i18n: `locale` drives Intl.NumberFormat only (en-CA / fr-CA); chrome strings are overridable per prop.

Categoryorganisms
Sourcecomponents/organisms/StatTable/StatTable.tsx
AI HintUse for grouped statistics tables (per-product-type breakdowns, per-channel fee summaries). The legacy 2-column contract remains for simple Metric/Amount pages; the DS-STAT-01 multi-column contract is for breakdowns >2 numeric columns. All chrome strings are overridable per prop — pass French labels alongside `locale='fr'`.

StatTable component.

StatTable

design-system

StatTable component preview and API reference.

Indicateurs clés

Indicateurs clés
MetricAmount
Ventes
Revenus nets24 850,42 $
Revenus bruts27 430,00 $
Frais EP-962,18 $
Remboursements-617,40 $
Billets
Vendus1 284,00 $
Remboursés23,00 $
Compérage42,00 $
Total26 134,42 $

Props

Preview

StatTable

Prop
Type
Required
Default
Description
sections
StatSection[]
Required
—

Grouped rows. Each section renders a header row + its StatRow entries + a column-aligned Total in the tfoot.

columns
StatColumn[]
Optional
—

Optional multi-column header (DS-STAT-01). When omitted the table falls back to the legacy 2-column layout (Metric + Amount, one numeric cell per row).

currency
string
Optional
'CAD'

ISO currency code for Intl.NumberFormat.

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

BCP-47 locale for Intl.NumberFormat (en-CA | fr-CA). Does NOT translate chrome strings — pass the *Header / totalLabel / exportLabel / empty-* props for that.

onExport
() => void
Optional
—

Optional callback — renders a secondary Export button in the header when provided.

ariaLabel
string
Optional
'Statistics'

Accessible name of the stats region and the sr-only <caption> of the data table. Also rendered as the visible card heading. FR consumers pass e.g. 'Statistiques'.

metricHeader
string
Optional
'Metric'

Header of the label (first) column. FR consumers pass e.g. 'Métrique'.

amountHeader
string
Optional
'Amount'

Header of the numeric column in legacy 2-column mode (ignored when `columns` is supplied). FR consumers pass e.g. 'Montant'.

totalLabel
string
Optional
'Total'

Label of the tfoot total row. FR consumers pass 'Total' (same, override kept for completeness).

exportLabel
string
Optional
'Export'

Label of the export button (rendered only when `onExport` is supplied). FR consumers pass e.g. 'Exporter'.

emptyTitle
string
Optional
'No data available'

Title of the empty state. FR consumers pass e.g. 'Aucune donnée disponible'.

emptyMessage
string
Optional
'Statistics will appear here once sales are recorded.'

Body copy of the empty state. FR consumers pass e.g. 'Les statistiques apparaîtront ici dès les premières ventes.'

Quick use:<StatTable />

Accessibility

ARIA roletable

ARIA

3 rules

WCAG 1.3.1 (Info & Relationships)

Semantic <table> with <thead>/<tbody>/<tfoot> and sr-only <caption>

WAI-ARIA APG — table pattern

<th scope='col|row|rowgroup'> on every header cell (col for column headers, row for row labels, rowgroup for section title rows spanning the table)

DS-STAT-01 contract

Multi-column tfoot renders one Total cell per declared column (right-aligned, bold, tabular-nums)

validation

1 rule

NASA Rule 5

Numeric cells right-align with tabular-nums font feature for column-aligned decimal arithmetic

color

1 rule

DS-STAT-01 / DM-13

Section header row uses bg-ep-btn-primary (DM-13 colour swap, 5.70:1 AA both themes; was --ep-cyan 2.43:1 FAIL)

responsive

1 rule

WCAG 1.4.10 (Reflow)

Wide multi-column tables wrap in overflow-x-auto for WCAG 1.4.10 reflow (no horizontal clipping at 320 CSS px)

Usage

Import

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

Example 1

tsxSnippet
<StatTable sections={defaultSections} ariaLabel='Sales statistics' onExport={() => {}} />

Example 2

tsxSnippet
<StatTable sections={multiSections} columns={multiColumns} ariaLabel='Sales by product type' />

Example 3

tsxSnippet
<StatTable sections={defaultSections} locale='fr' ariaLabel='Statistiques de ventes' metricHeader='Métrique' amountHeader='Montant' totalLabel='Total' exportLabel='Exporter' />

Anti-patterns

— Do not pass both `value` and `values` on the same row — undefined behaviour (single-column and multi-column contracts are mutually exclusive per row).

— Do not hand-roll <table> for stats data — use StatTable for the scope/caption/currency contract (sr-only <caption>, <th scope>, tabular-nums, DM-13 section-header colour).

— Do not localize strings via `locale='fr'` alone — `locale` drives Intl only; pass the `*Header` / `totalLabel` / `exportLabel` / `emptyTitle` / `emptyMessage` props too.

— Do not use the legacy 2-column contract for breakdowns >2 channels — pass `columns[]` + per-row `values[]` instead (DS-STAT-01).

Design System v4.1.0 | ePassLive