Molécules
90 composites d’atomes — champs de formulaire, sélecteurs de recherche, éléments de navigation.
Des composites d’atomes. Champs de formulaire, sélecteurs de recherche, éléments de navigation et autres petites unités interactives.
Implémentés
SelectionCard
Shows the entity a picker has selected, with a divided action rail on the trailing edge. Use when a chosen value needs confirming (two venues can share a name) or acting on (edit, clear). Composes Surface.
Ouvrir le composantListbox
Inline ARIA selection widget with full keyboard support (WAI-ARIA Listbox pattern 1.2). Single and multiple selection modes, option groups, and custom option rendering.
Ouvrir le composantRadioGroup
Radio group container — wraps Radio atoms with shared name, controlled value, roving tabindex, and arrow-key navigation. Provides role="radiogroup" semantics.
Ouvrir le composantSearchSelect
Async typeahead search input with debounced server-side querying, optional inline create, keyboard navigation, and ARIA combobox semantics. Generic — takes a fetcher callback, not a hardcoded endpoint.
Ouvrir le composantValuePropsStrip
Horizontal strip of 3-4 value proposition items with icon, heading, and description. Used in storefront landing pages to communicate trust signals (secure payment, instant delivery, etc.).
Ouvrir le composantAccordion
Vertical stack of expandable sections. Single or multi-expand modes. Each header is a button with aria-expanded.
Ouvrir le composantActivityItem
Activity feed row — a semantic <li> with an 8px tone dot, a bold actor name, action text and a muted relative time in a <time> element. Consumers own the surrounding list (and any aria-live region).
Ouvrir le composantAlert
Inline alert (success, error, warning, info) — distinct from Banner. Used for form validation, system messages.
Ouvrir le composantAvatarGroup
Stacked avatar list — up to max (default 3) initial circles overlapping by -8px, remaining members collapsed into a "+N" overflow chip. The wrapper is a single role="img" with one accessible description. Used for attendees, collaborators, team members.
Ouvrir le composantBadgeGroup
Cluster of removable label badges with overflow handling. Renders its own label chips — does not compose the Badge atom.
Ouvrir le composantBreadcrumbs
Hierarchical path indicator with separator. Last item is current page (aria-current='page'). variant='bar' absorbs the former BreadcrumbBar molecule (Wave 3 Tier-1 / L2-M3).
Ouvrir le composantButtonGroup
Group of related buttons with role=group semantics. Declarative items mode (array of ButtonGroupItem with optional icon + hidden) or slot mode (caller-provided children). Aligns start/end, wraps responsively.
Ouvrir le composantColorPicker
Per-event brand color picker — a controlled native color input with an optional preset palette row. Replaces legacy color-picker.xsl. API under revision: preset palette rendering and keyboard navigation are not yet implemented.
Ouvrir le composantCopyButton
Button that copies a value to clipboard and shows a brief checkmark + 'Copied' feedback. Uses navigator.clipboard API.
Ouvrir le composantDatePicker
Native <input type="date"> wrapper with ISO value normalization — accepts string | Date, emits yyyy-mm-dd strings. The browser owns the calendar popup, keyboard navigation and locale formatting.
Ouvrir le composantDateRangePicker
Controlled pair of native date inputs (start → end) for range capture. Live onChange emits { start, end } when either input changes. Container is role='group' labelled by the visible label (htmlFor → start input) or ariaLabel fallback; each input carries its own accessible name from startLabel/endLabel. Error is aria-describedby-wired + aria-invalid on inputs. Not a calendar — for dashboard range filters use StatisticsDateFilter; for visual month-grid use Calendar.
Ouvrir le composantEmptyState
Empty/zero-state placeholder — icon slot + required title + optional description and action node. default/compact/centered/info variants. The fleet's most-consumed molecule (lists, tables, search results).
Ouvrir le composantHeroSearch
Homepage hero search — GET form (what + where) with a submit button; stacks vertically on mobile. An optional third « Quand » segment (ADR-057) renders when whenPlaceholder is supplied. Either field can be turned into a DS combobox with the optional onSearch (What) / onLocationSearch (Where, ADR-074) / onSelectSuggestion / suggestionLabels API; the outer GET form always stays the no-JS fallback.
Ouvrir le composantLanguageSwitcher
EN/FR bilingual toggle with instant language switch — inline EN | FR pair (header default) or compact single button showing the target locale (ADR-038: fab retired). Controlled and stateless: the consumer owns URL-segment navigation and the document language.
Ouvrir le composantNewsletter
Newsletter signup molecule (ADR-069 / plan T5): first name, last name, email, Canadian postal code, a persona choice (buyer / organizer), optional interest options and a required consent checkbox. Ships ZERO hardcoded copy — every title, label, placeholder, CTA, success/error message and the consent string is a prop. The consent box is unticked by default (Law 25 / GDPR). Used in the storefront footer modal and dedicated landing blocks.
Ouvrir le composantNewsletterSlotTrigger
Newsletter slot trigger (ADR-069 / plan T6, decision D17): a tiny client component that renders a real <button type="button"> and dispatches the DOM CustomEvent 'ep:newsletter-open' on window (detail: { source }). It bridges the server/client boundary for server-rendered slots such as FooterStub, where a function prop cannot cross — the consumer listens for the event and opens its modal. Ships no hardcoded copy: the CTA label and the accessible name are props.
Ouvrir le composantNotification
Notification item — avatar/icon + title + body + timestamp + unread dot. Used in notification dropdown and feed.
Ouvrir le composantPagination
Page-number navigator with prev/next — button pager by default, <a href> SEO mode via href. Computes totalPages from totalItems/pageSize and hides itself when there is ≤1 page.
Ouvrir le composantLoadingOverlay
Non-dismissible busy treatment — covers a region or the viewport, blocks interaction and announces what is happening. Reuses the Modal scrim family. Not a dialog: no close, no focus trap.
Ouvrir le composantProgressBar
Horizontal progress indicator — 6px height, 3px radius. Fill is teal→blue gradient. ARIA progressbar with valuenow/min/max.
Ouvrir le composantPromoCodeValidator
Promo-code entry molecule with an embedded async validation state machine (idle → validating → valid / invalid). Renders input + Apply + a live-region feedback line; the result is a {valid, message} text line — no discount/expiry/terms display. Used in checkout.
Ouvrir le composantRating
Star rating display + input. Read-only (display) or interactive (input). 5 stars by default, half-stars supported.
Ouvrir le composantRefundStatusTracker
Read-only refund-progress tracker for order history — status pill + summary line (id, dates, reason) + 5-stage linear track with terminal rejected branch; live-region announcement; consumer-supplied localized labels.
Ouvrir le composantRichTextEditor
Rich text editor for event descriptions. Replaces TinyMCE. TipTap/Lexical wrapper.
Ouvrir le composantSkipLink
Skip-to-main-content link. Hidden off-screen at top:-40px, slides down on focus. WCAG 2.4.1 Bypass Blocks.
Ouvrir le composantSlider
Range slider — single or dual thumb. 4px track, 20px thumb. Keyboard arrow keys, ARIA slider pattern.
Ouvrir le composantStatCard
KPI metric card — 40×40 colored icon + trend pill + 28px/800 value + 12px muted label. White card with 1px border, hover lift -2px + card shadow.
Ouvrir le composantStepper
Horizontal step indicator — 3-6 steps with state (complete/current/upcoming). Used in checkout, multi-step forms, onboarding.
Ouvrir le composantTabs
Horizontal tab group with underline indicator. WAI-ARIA tabs pattern: role='tablist', roving tabindex, ArrowLeft/Right to navigate. variant='href' renders the former TabsTrigger link-mode strip (anchor or button tabs, underline or pills appearance) — TabsTrigger was merged into Tabs (Wave 3 Tier-1, L3-M3).
Ouvrir le composantThemeInitScript
Pre-hydration FOUC prevention script — server-rendered blocking inline <script> that reads a localStorage theme key (plus optional legacy keys, in read order) and stamps data-theme on <html> before first paint. Consolidates the storefront (DS-CORR-09-07), client-portal (DM-09) and docs-shell (DM-08) copies (W2).
Ouvrir le composantTimePicker
Typeable time combobox over a 15-minute grid (separate from date). Used for event start time, doors time, and any range with min/max. E11-INTK-1 rewrite — the list opens on click/focus and the field accepts free text (`7:30 pm`, `1930`, `19:30` all normalise to `19:30`). Out-of-range options are GREYED rather than hidden so the producer sees the constraint.
Ouvrir le composantToast
Ephemeral notification card — 4 variants (success/info/warning/error). Card-only: positioning, stacking and dismissal timing belong to the consuming container (no DS container molecule yet). error announces via role='alert' + aria-live='assertive'; the other variants via role='status' + aria-live='polite'.
Ouvrir le composantTooltip
Hover/focus tooltip portaled to document.body as a <div role='tooltip'> (role='dialog' when interactive), linked to its single trigger via aria-describedby. No show/hide delay exists and the portaled surface is positioned against the viewport, not the anchor — surface positioning is being overhauled (tracked).
Ouvrir le composantWidgetCard
Generic dashboard card surface — header (title + subtitle + right-aligned action slot) over a body slot, optional footer after. Variants: chart (bordered, 16px rhythm), side (borderless rail, 14px rhythm), accent (theme-stable dark surface + inverse text).
Ouvrir le composantSearchBar
Thumb-zone search trigger for mobile layouts (HV2 / R5, ADR-058). A plain button (no state, no navigation) that opens the DS SearchSheet; carries the 56px bar height, the 44px tap-target floor and a semantic focus ring (ADR-071: outset recipe with ring-offset-ep-bg). Pairs with SearchSheet; the consumer owns what 'open' does.
Ouvrir le composantCategoryChip
One primary event-category filter chip (SEARCH-03). Presentation only: composes the Chip atom, so it inherits the native-button contract, aria-pressed, the 44px tap target and the theme-stable selected colours. Data, i18n and routing live in the consumer.
Ouvrir le composantCategoryChipRow
Single-select event-category chip row (SEARCH-03, Pattern A: one category per event). Owns layout, the aria group and the All semantics; the consumer owns data, i18n and navigation. Selecting the active category or All reports null.
Ouvrir le composantCityChip
One city in the multi-select city facet (SEARCH-05). Presentation only: composes the Chip atom and optionally announces the result count. Cookie, URL and navigation stay in the consumer.
Ouvrir le composantCitySelector
Multi-select city facet (SEARCH-05, ADR-055). All-cities chip clears the selection, toggling the last city off returns to All, and the selection is capped (default 5) with unselected chips disabled at the cap. Router-agnostic and i18n-free: the consumer injects copy, cookie persistence and URL updates. Handles loading, empty and error+retry states.
Ouvrir le composantMenu
Dropdown command list. Context menu or navigation menu with items, separators (item.divider), custom content rows (item.content — search fields, rich blocks), and submenus. Header's responsive MoreMenu overflow composes this molecule (L8b, Wave 3 Tier-2).
Ouvrir le composantFormSection
Dashboard form section with title + description + sibling divider. Replaces the um-form-section CSS layout system.
Ouvrir le composantFormRow
Dashboard form row layout — flex-wrap row with a tokenized gap, replaces um-form-row CSS. Wraps when children no longer fit but does NOT stack on narrow viewports; use ResponsiveFieldGroup for mobile-first stacking.
Ouvrir le composantSettingsPanel
A settings surface's full anatomy: optional panel title, a stack of titled concerns (rendered through FormSection) and an optional actions footer. Chrome-less composition extracted from the 11 dashboard/portal sites that hand-rolled it.
Ouvrir le composantAudioPlayer
Inline audio player — custom compact/expanded UI with play/pause, seek via keyboard (Space, ←→ ±5s, ↑↓ volume), and an error fallback alert. No pointer scrubbing yet (slider is keyboard-only). Autoplay is guarded by prefers-reduced-motion and gesture-blocked autoplay currently surfaces as the error state (tracked).
Ouvrir le composantCardGrid
Responsive grid wrapper that renders an array of items as cards via a caller-supplied render function. Supports 1–4 columns and three gap scales, with an empty-state message when the list is empty.
Ouvrir le composantCategoryPill
Ticket-category pill (Diamond, Platinum, Silver, Gold, CAT 1/2/3). Distinct from StatusBadge (state) — encodes categorization only. Tints derived via color-mix() from existing CSS variables so dark-mode adapts automatically.
Ouvrir le composantFilterChipGroup
Filter row composing the Chip atom. Active chips use the canonical DS selected-control idiom (theme-stable 5.70:1 contrast). Supports single- and multi-select modes; optional count badges are announced by SR.
Ouvrir le composantSearchInput
WAI-ARIA combobox with a grouped Top-N typeahead (SEARCH-04, ADR-049). The DS owns debounce, keyboard navigation (ArrowUp/Down, Enter, Escape), aria-activedescendant and the loading/empty/short-query states; the consumer supplies onSearch and receives grouped suggestions. Renders a real GET form, so search still works without JavaScript. ADR-071: the chromeless variant owns its field-level ring (`ring-offset-ep-bg`) as the blessed HeroSearch-style indicator; the boxed (non-chromeless) variant rings the input box itself — never nest either inside a parent focus-within ring.
Ouvrir le composantFooterColumn
Footer column with title + optional accent underline + vertical link list. Column sizing is owned by the parent Footer organism.
Ouvrir le composantImageUploader
Image picker with currentSrc preview (the persisted image IS the control — click to replace), variant=avatar (96px circular slot with initials fallback), and an optional inline remove control. Absorbs the removed AvatarUploader and FileDropzone molecule surfaces (D1 dedup merge).
Ouvrir le composantMarkdownRenderer
XSS-safe Markdown-subset → HTML renderer (h1-h3, bold/italic, inline+block code, ul/ol, blockquote, safe links; no images/tables). Raw HTML inside content is escaped FIRST. Allowlist for links: http(s), mailto, /, #, ./, ../ (javascript: stripped). html mode renders pre-sanitized HTML verbatim.
Ouvrir le composantMediaGallery
Responsive image+video gallery grid (2/3/4 columns). Tiles become full-size buttons when onSelect is provided; video tiles show a centered play indicator. Empty state renders a role='status' message.
Ouvrir le composantPaymentMethodCard
Saved-payment-method display card: brand label + last4 + expiry, with an optional default badge, Set-default action and Remove action. Compact wallet row — supersedes the deprecated paymentmethod (selection semantics live there, not here).
Ouvrir le composantProgressUpload
Per-file upload row: file icon + name + size, an inline status-colored bar (not composed of ProgressBar — composition refactor tracked), a percent/status readout, and ghost-button Cancel/Retry actions gated on status. uploading/done/error/paused states; error renders a role='alert' message and paused differentiates with a warning-tinted bar.
Ouvrir le composantResponsiveFieldGroup
Horizontal form fields that auto-stack on narrow viewports. Wraps each child in a min-w-0 flex slot so flex children can shrink below their intrinsic content width — fixes the 129-167% horizontal overflow on 375 px viewports.
Ouvrir le composantTableToolbar
Composing molecule: search input (44px-hit clear button) + filter chip group + optional trailing slot + conditional bulk actions, wrapped in role=toolbar. Every announced string has an EN default plus an i18n port (filtersLabel, clearSearchLabel, bulkActionsLabel).
Ouvrir le composantTextFormatToolbar
Formatting toolbar (bold/italic/underline/strikethrough/h1/h2/h3/ul/ol/link/quote/code/undo/redo) for contentEditable surfaces. Roving-tabindex keyboard nav (ArrowLeft/Right wrap, Home/End), per-command localized aria-labels via labels, 44px tap hit-rects (--ep-tap-min) with 32px visuals, Phosphor glyphs for link/quote/lists/undo/redo. Each button is a real <button> and onMouseDown preventDefault preserves the caret position.
Ouvrir le composantVideoPlayer
Video playback frame wrapping native <video controls> with aspect-ratio enforcement (16:9, 4:3, 1:1), poster, loading skeleton, and error fallback. Keyboard: Space (play/pause), ←/→ (seek ±5s), ↑/↓ (volume ±0.1), f (fullscreen), c (captions toggle — case-insensitive). prefers-reduced-motion guard blocks autoplay. Error state (role=alert) on playback failure.
Ouvrir le composantCalendar
Standalone month-grid calendar with click-to-select, roving-tabindex keyboard navigation (arrows/PageUp/PageDown/Home/End/Enter), min/max/disabled dates, and overridable labels (English defaults; Monday-first). Optional range mode (selectionMode='range' + range/onChangeRange, hero « Quand » picker, ADR-068 amendment): first click sets the start, same-day second click completes a single-day range, later-day second click completes the range, earlier-day restarts it; hover previews the pending range. For locale-aware date entry use DatePicker (native UA widget); for dashboard range filters use StatisticsDateFilter.
Ouvrir le composantCommandMenu
Portal command palette with keyboard navigation and shortcut registration. Real implementation; the organisms/commandmenu stories twin was removed per ADR-035.
Ouvrir le composantDrawer
Side panel dialog (portal, scrim, Escape, scroll-lock). Always renders a header row — title <h2> left, close IconButton right — above a scrolling body (flex column, flex-1 overflow-y-auto). Placements left/right, sizes. Real implementation; the organisms/drawer stories twin was removed per ADR-035.
Ouvrir le composantModal
Centered dialog (portal, scrim, Escape, focus trap, restore-focus, topmost-ESC stacking, 85vh panel scroll, configurable scrim, sizes, footer slot). Composes the Modal molecule for dialog chrome.
Ouvrir le composantSidebar
Vertical navigation sidebar with grouped items, active-state indicator (aria-current), and a built-in mobile drawer (portal + scrim + focus trap + Escape + scroll lock). Persistent at >= breakpoint; overlay drawer below it. Real implementation; the organisms/sidebar stories twin was removed per ADR-035.
Ouvrir le composantPlanifiés
- ArtistCard— Performer/artist card — circular image, name, role, follow button. Used in event detail and artist pages.
- DateBadge— Square date label — 16px/800 day on top, 9px/700 uppercase month below. Positioned absolute top-left of EventCard thumbnail. White bg + card shadow.
- QuickBuyBar— Sticky quick-buy bar at bottom of event page — event name, date, price from, and 'Buy Now' CTA. Appears on scroll past hero. Critical UX pattern: 3-click purchase flow.
- VenueCard— Venue preview — image, name, address, capacity, link to venue page. Static, server-rendered.
- WaitlistJoinForm— Waitlist join form for sold-out events — email input, notification preference, and join button.
- WillCallPicker— Will-call ticket pickup selector — choose pickup location, date, and time slot. Shows ID requirements. Critical UX pattern: will-call pickup.