Passer au contenu principal

Atomes

52 primitives d’atomes — boutons, champs, badges, typographie — qui composent chaque molécule du système.

Les plus petites primitives d’interface. Chaque atome possède un élément DOM, ses jetons et son contrat d’accessibilité — il ne récupère jamais de données et ne connaît jamais les autres atomes.

52 implémentés•0 planifiés
Pourquoi

Pourquoi les atomes

Les atomes sont les plus petites unités autonomes du système de design ePassLive — boutons, champs, badges, avatars, tags. Chaque atome possède exactement un élément DOM, ses jetons de design et son contrat d'accessibilité ; il ne récupère jamais de données et ne connaît jamais les autres atomes. Utilise un atome dès que le besoin d'interface se nomme en un seul mot — « un bouton », « un prix », « un statut ». Compose les atomes en molécules et en organismes plutôt que de les restyler surface par surface. Garantie du système de design : chaque atome est livré conforme WCAG 2.2 AA, thématisé par le même jeu de jetons en mode clair et sombre, et couvert par des tests unitaires avec assertions ARIA. Si un assemblage se répète sur trois surfaces ou plus, promeus-le en molécule — ne fork jamais l'atome.

Implémentés

Avatar

Circular user avatar with initials fallback and optional image. Sizes: sm (32px), md (40px), lg (56px), xl (80px).

Ouvrir le composant

Badge

Numeric count badge for notification and nav counts. Count-based API (number or max+), never children. Five semantic variants on ADR-027 tint/fg pairs — WCAG 2.2 AA (≥4.5:1) in light and dark themes.

Ouvrir le composant

Barcode

QR (ISO/IEC 18004) or Code-128 B (ISO/IEC 15417) symbol — SVG-rendered for crisp scaling. Rendered on every issued ticket and at order lookup via the storefront QrCode facade (ConfirmationView, OrderLookupForm). Decorative when paired with text; meaningful when sole identifier.

Ouvrir le composant

Button

Primary interactive button — variants: primary (teal CTA), secondary (outlined), ghost (text-only), danger (destructive). Sizes: sm/md/lg all enforce WCAG 2.5.5 44px tap-min (var(--ep-tap-min)); size changes padding and font-size, not height.

Ouvrir le composant

Caption

Small muted caption text (ep-xs, text-muted) for figure captions, helper lines and secondary annotations. Polymorphic via `as`.

Ouvrir le composant

Checkbox

Tri-state checkbox with label. 18×18 box, 2px teal border, solid teal fill with a white check glyph when checked. Indeterminate state supported. Use for selections; use Switch for immediate on/off settings.

Ouvrir le composant

Surface

The generic bordered, token-backed box that domain cards and panels compose. Use instead of hand-writing rounded/border/background utilities at the call site; carries no content structure of its own.

Ouvrir le composant

Chip

Selectable filter chip — multi-select group. Like a small Pill but with optional leading icon and selected/unselected visual states.

Ouvrir le composant

ColorSwatch

Color preview block — 24×24 rounded square with hex/RGB tooltip. Used in design system docs and theme editor.

Ouvrir le composant

Divider

Horizontal 1px divider in --c-border-light. Used inside stat cards, table rows, side cards.

Ouvrir le composant

Icon

Icon system with five atoms per ADR-022: PhosphorIcon (Admin-UI, 242 canonical names incl. 9 ADR-022-amend-01 EXTRAS + 25 Figma aliases, provenance in PHOSPHOR_ICON_SOURCES), VuesaxIcon (Storefront, 660 names, DS-ICONO-004), BrandIcon (~50 brands, DS-ICONO-005), FlagIcon (13 province flags, google/region-flags Public Domain), AlertIcon (variant-driven Phosphor wrapper — error/warning/info/success — for role=alert slots, ADR-026 + DS-ICONO-006b). ADR-021 size convention (7 sizes + stroke/LARGE_GRAPHIC/brand exceptions). Always aria-hidden unless the sole label. ICONO-ADOPT run (2026-08-17) migrated all dashboard/admin SVG to PhosphorIcon, all storefront public SVG to VuesaxIcon, Footer social letters to BrandIcon, and province flags to google/region-flags.

Ouvrir le composant

IconButton

40×40 circular icon-only button. Used in header for notifications, settings, theme toggle. Dark variant in light mode (#1A2332 bg / white fg), neutral in dark mode.

Ouvrir le composant

Input

Text input with label, helper, error, and disabled states. Focus indication is painted by the wrapper via `focus-within:ring-2 ring-ep-teal border-ep-teal`; the inner `<input>` carries `focus:outline-none` so the browser's default outline does not stack. Required for all forms. ADR-071: exactly one focus indicator per field group, owned by the chrome container — chromeless mode never self-rings by default; `focusRing="self"` is the opt-in for bare fields with no parent focus chrome. Every `ring-offset-2` carries `ring-offset-ep-bg`.

Ouvrir le composant

InputOTP

Multi-digit OTP input. Auto-advance between digits, paste support.

Ouvrir le composant

InputPhone

Phone number input with country code selector. Format validation.

Ouvrir le composant

Kbd

Keyboard key indicator — 20×20 with monospace font, 1px border, 4px radius. Used in shortcuts hints.

Ouvrir le composant

Label

Form control label with htmlFor binding and optional required marker (asterisk, aria-hidden, semantic-error color).

Ouvrir le composant

Logo

Original ePassLive logo with 4 elements: QR Code (mode-adaptive), Code Scanner Frame (mode-adaptive), Teal 'e' lettermark (brand-locked), PSSLIVE wordmark (mode-adaptive). Theme-aware via --logo-fg token.

Ouvrir le composant

PriceTag

Formatted price — locale-aware currency display. Sizes: sm/md/lg. Variants: default / strikethrough / from-prefix.

Ouvrir le composant

Radio

Radio button for a radio group. Wrapped by RadioGroup which manages arrow-key navigation between siblings.

Ouvrir le composant

SeasonPassBadge

Season-pass loyalty tier badge — tier-colored diamond + label pill (gold/silver/bronze/platinum). Describes WHO the holder is; distinct from CategoryPill (ticket tier) and StatusBadge (lifecycle state). Exported from the barrel; role=img with derived aria-label.

Ouvrir le composant

Skeleton

Loading skeleton — radius matched to whatever it's skeletonizing. Use while Server Components fetch data.

Ouvrir le composant

Select

Native select with visible label, helper text, and error state. Focus indication painted by the wrapper (focus-within ring); custom chevron. aria-describedby wired to helper/error. WCAG 2.5.5 tap-min enforced by wrapper height.

Ouvrir le composant

Spinner

Loading indicator — teal ring with rotating segment. Sizes: sm (16), md (24), lg (40). aria-label or aria-labelledby required when no visible label.

Ouvrir le composant

Switch

Toggle switch — 36×20 pill, teal when on, neutral when off. role='switch' with aria-checked.

Ouvrir le composant

Tag

Removable label chip — used in filter bars, multi-select displays, taxonomy. Has a × button with aria-label='Remove {label}'.

Ouvrir le composant

Textarea

Multi-line text input with fixed rows (default 4) and resize-y — it does NOT auto-grow. Optional char counter, helper text, and error state. Focus indication is painted directly via `focus:ring-2 focus:ring-ep-teal focus:border-ep-teal`; `focus:outline-none` suppresses the browser's default outline so a single focus indicator is visible. Same label/error/required contract as Input. Note: the props array below is partial — showCounter, helperText, error, and required are documented in the interface string but not yet mirrored as props rows.

Ouvrir le composant

LanguageToggle

Header language switcher. Shows the TARGET language token (e.g. "EN" while FR is active); when onChange is provided, toggles FR⇄EN. aria-label always announces the current language and the action so the single visible token stays unambiguous to assistive tech.

Ouvrir le composant

NavLink

Primary-navigation anchor with a built-in active-state underline indicator. Bundles label + indicator (atom convention). Presentational: the consumer decides `active` (e.g. from the current route) so the atom stays framework-agnostic.

Ouvrir le composant

SocialIconButton

Circular icon link for social profiles. Bundles the icon with its required accessible label so an icon-only control is never shipped without its text alternative. Opens in a new tab (target=_blank, rel=noopener noreferrer).

Ouvrir le composant

BrandSurface

ADR-031 accent surface atom — one of the three valid accent contexts. Tinted variant (10% accent fill + 50% border, radius-lg) for light backgrounds; pill variant (solid surface-card fill + 50% border + shadow, radius-full) for surfaces over images/photos where bare tints vanish (§89.1). Attaches a brand hue to a stable identity.

Ouvrir le composant

BrandRibbon

ADR-031 decorative 4-hue gradient strip (teal → indigo → amber → pink) — one of the three valid accent contexts. The bookend pattern: a 4px strip above the header and a matching strip at the top of the footer. Always aria-hidden + role=presentation; theme-stable (all four hues are non-swapping tokens).

Ouvrir le composant

AccentUnderline

ADR-031 short decorative brand-accent underline (h-0.5 w-6 rounded-ep-full) for section headings — one of the three valid accent contexts. Signals the heading's stable identity (the FooterColumn pattern). Always aria-hidden; the heading carries the semantics.

Ouvrir le composant

Body

Paragraph-level body text (text-ep-sm/base/lg scale, text-ep-text-body color, SECONDARY font slot by default). Renders a semantic <p>; polymorphic via as for span/div inline usage.

Ouvrir le composant

H1

Level 1 heading for page titles.

Ouvrir le composant

H2

Level 2 heading for major sections.

Ouvrir le composant

H3

Level 3 heading for subsections.

Ouvrir le composant

H4

Level 4 heading for nested sections.

Ouvrir le composant

H5

Level 5 heading.

Ouvrir le composant

H6

Level 6 heading.

Ouvrir le composant

Pre

Preformatted text block.

Ouvrir le composant

Overline

Small uppercase label text.

Ouvrir le composant

TextLink

Inline text link with variants.

Ouvrir le composant

Code

Inline code formatting.

Ouvrir le composant

Blockquote

Block-level quotation.

Ouvrir le composant

Heading

Polymorphic heading component H1-H6.

Ouvrir le composant

FormField

Label + control wrapper atom. Binds label htmlFor to the child control via cloneElement (injects id, aria-describedby, aria-invalid), renders required asterisk, hint paragraph, and role=alert error paragraph with AlertIcon fallback. Supports read-only display mode (label above rendered value, mono code option) and flex width slots for FormRow composition.

Ouvrir le composant

FormFieldError

Standalone inline validation-error atom: renders the message in a role=alert paragraph with semantic-error color. Renders nothing when message is empty.

Ouvrir le composant

PageSizeDropdown

Inline pagination size selector atom (DS-CORR-11-09). Borderless button trigger (current value + chevron) opening a popover listbox of page sizes. Designed for pagination footers ('Showing [8 v] out of 312'). Full keyboard support: Enter/Space opens, arrows navigate (wrapping), Escape closes, Home/End jump.

Ouvrir le composant

StatusBadge

Semantic status badge with icon slot. Variants: success, warning, error, info, neutral, refunded. Locked icon mapping (Check/Clock/X/Info/Minus/RotateCcw). WCAG 1.4.1: label always required.

Ouvrir le composant

TouchTargetEnforcer

A11y utility wrapper (DS-CORR-08-10) enforcing the 44×44px tap-target floor (WCAG 2.5.5). Wraps any interactive child (button/a/label) in an inline-flex span using the --ep-tap-min CSS variable via tapTargetStyle; negative margins compensate so the wrapper never expands the visual footprint — it is purely a hit-area expander.

Ouvrir le composant

ThemeToggle

Light/dark theme toggle button. Persists choice to localStorage (key per app) and swaps the html class. aria-pressed reflects the current theme.

Ouvrir le composant
Atomes — Système de design — ePassLive