Skip to main content

CartSummary

Implemented

Static cart/order recap aside for the checkout page — line items (label + optional detail) in a divided list, then a definition list of pre-formatted subtotal / fees / taxes (TPS+TVQ) / total rows and a full-width primary CTA (Button atom). Built-in labels are FR-CA by default (Recapitulatif, Sous-total, Frais, TPS+TVQ, Total, Confirmer et payer) with a full EN set via the locale prop (Order summary, Subtotal, Fees, Tax, Total, Confirm and pay). Not a timer: the legacy reservation-bar pattern (items/total/reservationMinutes/onCheckout) was never implemented. `variant='selection'` (2026-11-02) is the event page's live panel: a heading ('2 tickets') with the total and its note, the lines with a price and a trash IconButton each, an optional notice, and ONE primary CTA with onCta — a side panel that sticks below the site header from lg, and a bottom bar stuck to the viewport below lg that collapses to heading + total + chevron and expands to the lines.

Categoryorganisms
Sourcecomponents/organisms/cartsummary/CartSummary.tsx
AI HintUse on checkout/payment pages as the static order recap. Amounts arrive pre-formatted as strings — no currency math, validation, or state; compose with the payment form rather than recomputing totals. FR-CA labels default; locale="en" switches, ctaLabel overrides only the button. The CTA is the DS Button atom (primary/md/fullWidth) and ships without onClick — wire navigation via composition. For a slide-in cart with Drawer chrome use CartDrawer; for the full checkout panel (promo + payment methods) use CheckoutSummary. Do NOT pass items/reservationMinutes/onCheckout — that is the never-implemented legacy reservation-timer API. variant="selection" is the event page's live panel beside a list of row-mode TicketSelectors: make it a DIRECT child of a tall column (flex/grid item) so it can stick — beside the list from lg, as the collapsing bottom bar below lg.

Récapitulatif statique d'une commande (sous-total, frais, TPS+TVQ, total) utilisé dans la page de paiement. FR-CA : « Sous-total · Frais · TPS+TVQ · Total · Confirmer et payer ».

CartSummary

Organism — Commerce family (Family 7)

Composant d'affichage (non contrôlé). Affiche les lignes du panier sous forme de liste, un tableau récapitulatif avec sous-total, frais, taxes et total, et un bouton CTA localisé.

This component supports light and dark mode.

Props

Prop
Type
Default
Description
lines*
CartSummaryLine[]
—

Lignes affichées dans la liste.

subtotal*
string
—

Sous-total formaté.

fees*
string
—

Frais formatés.

taxes*
string
—

Taxes formatées (TPS + TVQ au Québec).

total*
string
—

Total formaté.

ctaLabel
string
—

Libellé du bouton CTA (défaut localisé).

locale
'fr' | 'en'
fr

Bascule des libellés.

Props

Preview

CartSummary

Prop
Type
Required
Default
Description
lines
CartSummaryLine[]
Required
—

Cart line items rendered as a divided list. CartSummaryLine = { id, label, detail? } — label is the primary line (heading token), detail an optional muted second line.

subtotal
string
Required
—

Pre-formatted subtotal amount (e.g. "144,00 $"). Display-only — the component performs no currency math.

fees
string
Required
—

Pre-formatted fees amount.

taxes
string
Required
—

Pre-formatted taxes amount; row label is TPS+TVQ (fr) / Tax (en).

total
string
Required
—

Pre-formatted grand total — rendered as the emphasized final dl row (heading token, ep-base).

ctaLabel
string
Optional
fr: "Confirmer et payer" / en: "Confirm and pay"

Overrides the CTA button label only; all other labels follow locale.

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

Switches every built-in label (heading, items, totals rows, CTA). 'fr' (default) keeps FR-CA copy; 'en' renders the English set.

variant
'summary' | 'selection'
Optional
'summary'

'selection' switches to the event-page panel and its own props (heading, totalNote, emptyMessage, notice, ariaLabel, expandLabel, ctaLabel, onCta, ctaDisabled, ctaLoading); subtotal/fees/taxes/locale do not apply there.

heading
ReactNode
Optional
—

'2 tickets' — translated and pluralised by the caller.

totalNote
ReactNode
Optional
—

Muted line under the total ('Taxes and service fees included').

emptyMessage
ReactNode
Optional
—

Shown instead of the list when there are no lines.

notice
ReactNode
Optional
—

Message above the CTA (e.g. an Alert saying why it is disabled). Not collapsed on a phone.

ariaLabel
string
Optional
—

Accessible name of the aside (translated).

expandLabel
string
Optional
—

Accessible name of the phone bar's expand toggle (translated); it carries aria-expanded + aria-controls.

onCta / ctaDisabled / ctaLoading
() => void / boolean / boolean
Optional
— / false / false

The selection CTA's click handler and states.

lines[].price / onRemove / removeLabel
string / () => void / string
Optional
—

Selection lines only: the line amount under the label, and a trash IconButton named by the translated removeLabel.

className
string
Optional
—

Appended to the root aside element.

Quick use:<CartSummary />

Accessibility

ARIA rolecomplementary

ARIA

1 rule

WCAG 1.3.1

Root is <aside aria-label="Recapitulatif" (fr) / "Order summary" (en)> — role complementary; line items in <ul role="list">; totals in a <dl> of dt/dd pairs so screen readers announce label/value pairs

a11y

1 rule

WCAG 1.4.3

Muted row labels (dt) read --ep-text-muted: 5.49:1 on --ep-surface-card (light); dark theme swaps the pair — both ≥ 4.5:1 AA at ep-sm size

i18n

1 rule

WCAG 3.1.2

All built-in strings localized FR-CA (default) / EN via the locale prop; no hardcoded English-only copy

Usage

Import

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

Example 1

tsxSnippet
<CartSummary lines={[{ id: "ga", label: "Billet GA", detail: "2 × 48,00 $" }, { id: "vip", label: "Billet VIP" }]} subtotal="144,00 $" fees="7,20 $" taxes="21,96 $" total="173,16 $" />

Example 2

tsxSnippet
<CartSummary lines={lines} subtotal="265,00 $" fees="18,55 $" taxes="39,86 $" total="323,41 $" locale="en" ctaLabel="Go to payment" />

Example 3

tsxSnippet
<CartSummary variant="selection" heading={t("ticketCount", { count })} total={money(total)} totalNote={t("totalNote")} lines={lines} emptyMessage={t("empty")} ariaLabel={t("ariaLabel")} expandLabel={t("expand")} ctaLabel={t("addToCart")} onCta={commit} ctaDisabled={count === 0} />

Anti-patterns

— Do not fetch data directly in organisms

— Avoid tight coupling to specific data sources

Design System v4.1.0 | ePassLive