Component Contract

Toast

Lightweight, non-blocking notification used to surface brief, time-sensitive messages across the CAAT Pension Plan member experience.

Live Demo

Basic Toast

Rendered

Colour Variants

Rendered

Toast with Action

Rendered

States

Interactive states on the dismiss control and the action link. Shown statically via is-* classes that mirror the live :hover / :focus-visible rules.

Rendered

Stacked Toasts (positioned)

Rendered — click the button to show stacked toasts in the bottom-right corner.

Code sample

HTML

<!-- Basic toast -->
<div class="caat-toast toast" role="alert" aria-live="assertive" aria-atomic="true">
  <div class="caat-toast__header toast-header">
    <i class="bi bi-bell caat-toast__icon" aria-hidden="true"></i>
    <span class="caat-toast__title">Notification</span>
    <small class="caat-toast__meta">Just now</small>
    <button type="button" class="caat-toast__close"
            data-bs-dismiss="toast" aria-label="Close">
      <i class="bi bi-x" aria-hidden="true"></i>
    </button>
  </div>
  <div class="caat-toast__body">
    Your contribution statement is now available.
  </div>
</div>

<!-- Colour variant -->
<div class="caat-toast caat-toast--success toast" role="alert" ...>
  ...
</div>

<!-- Toast with action -->
<div class="caat-toast__body">
  Item removed.
  <a href="#" class="caat-toast__action">Undo</a>
</div>

<!-- Stacked container -->
<div class="caat-toast-container" aria-live="polite">
  <!-- Multiple .caat-toast elements -->
</div>

1. Summary

Component namecaat/components/toast
PurposeLightweight, non-blocking notification that appears briefly to confirm an action, surface a status change, or alert the member to a time-sensitive event. Used across the member portal for form confirmations, session warnings, and system messages.
Status New
VariantsDefault (blue), Success (green), Warning (amber), Error (red), Info (blue)
OptionsAuto-dismiss toggle, dismiss delay, optional action link, optional icon
AEM resource typecaat/components/toast
AEM categoryCAAT Components – Feedback

2. Design Tokens

Toasts consume these semantic tokens — no component-specific tokens are defined.

TokenRole
--caat-color-bg-pageToast background
--caat-color-textToast body text
--caat-color-text-mutedMeta / timestamp text
--caat-color-borderToast border
--caat-blue-700Default / info left-border accent
--caat-greenSuccess accent
--caat-warning-accentWarning accent
--caat-danger-accentError accent
--caat-shadow-smElevation shadow
--caat-radiusCorner radius
--caat-font-primaryFont family

3. Authoring Fields

FieldTypeRequiredNotes
TitleText fieldYesShort header text. Max 60 characters. E.g., "Success", "Session Expiring".
BodyText areaYesNotification message. Max 200 characters. Keep concise and actionable.
VariantDropdown (default | success | warning | error | info)YesDetermines accent colour and header background.
IconIcon pickerNoBootstrap Icon shown in the header (e.g., bi-check-circle-fill).
Action LabelText fieldNoText for an optional action link in the body (e.g., "Undo", "View").
Action URLPath pickerNoDestination for the action link. Required if Action Label is provided.
Auto-dismissToggle (boolean)NoDefault: on. When enabled, toast auto-hides after the configured delay.
Dismiss DelayNumber (ms)NoDefault: 5000. Time in milliseconds before auto-dismiss. Minimum 3000.

4. Validation Rules

  • Title and Body are mandatory; toast will not render without both.
  • Title max length: 60 characters.
  • Body max length: 200 characters.
  • Variant is required; defaults to "default" if not set.
  • If Action Label is provided, Action URL is also required (and vice-versa).
  • Dismiss Delay must be ≥ 3000 ms. Values below 3000 are clamped to 3000.
  • Error-variant toasts should default to autohide: false so members don't miss critical messages.

5. Content Guidance

GuidelineDetail
ToneBrief, member-friendly. Use plain language. Lead with the outcome ("Profile updated") not the action ("We have updated your profile").
Use Success forConfirmations — "Profile updated", "Beneficiary added", "Document uploaded".
Use Warning forNon-critical alerts — "Session expiring in 5 min", "Incomplete form saved as draft".
Use Error forFailures — "Unable to save changes", "Connection lost". Always provide guidance or retry option.
Use Info forNeutral updates — "New statement available", "Scheduled maintenance tonight".
Action linksUse sparingly. One action per toast maximum. Label should be a verb — "Undo", "View", "Retry".
Don'tUse toasts for critical, blocking errors (use a modal instead). Don't stack more than 3 toasts at once. Don't use toasts for marketing or promotional content.

6. Semantic HTML

HTL / Markup contract

<!-- Single toast -->
<div class="caat-toast caat-toast--{variant} toast"
     role="alert" aria-live="assertive" aria-atomic="true"
     data-bs-autohide="{autohide}" data-bs-delay="{delay}">
  <div class="caat-toast__header toast-header">
    <i class="bi bi-{icon} caat-toast__icon" aria-hidden="true"></i>
    <span class="caat-toast__title">{title}</span>
    <small class="caat-toast__meta">{timestamp}</small>
    <button type="button" class="caat-toast__close"
            data-bs-dismiss="toast" aria-label="Close">
      <i class="bi bi-x" aria-hidden="true"></i>
    </button>
  </div>
  <div class="caat-toast__body">
    {body}
    <a href="{actionUrl}" class="caat-toast__action">{actionLabel}</a>
  </div>
</div>

<!-- Stacked toast container -->
<div class="caat-toast-container" aria-live="polite">
  <!-- Individual .caat-toast elements injected here -->
</div>

Key decisions

  • role="alert" with aria-live="assertive" ensures screen readers announce the toast immediately.
  • aria-atomic="true" ensures the entire toast content is announced as a single unit.
  • Close button uses aria-label="Close" for screen-reader accessibility.
  • Bootstrap's .toast class provides the show/hide JS behaviour; BEM classes layer CAAT styling on top.
  • The stacked container uses aria-live="polite" so new toasts don't interrupt the current announcement.

7. CSS Contract

SelectorPurpose
.caat-toastBase toast — font-family, border-radius, box-shadow, left-border accent, slide-in animation.
.caat-toast__headerHeader bar — flex layout, background, bottom border, font-weight 600.
.caat-toast__iconLeading icon in the header.
.caat-toast__titleHeader title text — flex: 1 to fill available space.
.caat-toast__metaTimestamp or supplementary text in header.
.caat-toast__closeClose button — transparent background, focus ring via --caat-focus.
.caat-toast__bodyBody content area — padding, font-size 0.875rem.
.caat-toast__actionAction link inside body — underlined, blue-700 colour.
.caat-toast--successSuccess variant — green left border, green-tinted header.
.caat-toast--warningWarning variant — amber left border, amber-tinted header.
.caat-toast--errorError variant — red left border, red-tinted header.
.caat-toast--infoInfo variant — blue left border, blue-tinted header.
.caat-toast-containerFixed bottom-right container for stacked toasts. z-index: 1090.

Sample CSS

.caat-toast {
  font-family: var(--caat-font-primary, 'Libre Franklin', sans-serif);
  border-radius: var(--caat-radius, 0.375rem);
  border-left: 4px solid var(--caat-blue-700, #004a99);
  box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.15);
  background-color: #fff;
  color: var(--caat-ink, #212529);
  animation: caat-toast-slide-in 0.3s ease-out;
}

.caat-toast--success { border-left-color: var(--caat-green, #198754); }
.caat-toast--warning { border-left-color: #ffc107; }
.caat-toast--error   { border-left-color: #dc3545; }
.caat-toast--info    { border-left-color: var(--caat-blue-700, #004a99); }

.caat-toast__close:focus-visible {
  outline: 2px solid var(--caat-focus, #005fcc);
  outline-offset: 2px;
}

.caat-toast-container {
  position: fixed;
  bottom: 1.5rem;
  right: 1.5rem;
  z-index: 1090;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  max-width: 350px;
}

@keyframes caat-toast-slide-in {
  from { transform: translateX(100%); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}

8. Accessibility

RequirementImplementation
ARIA live regionEach toast uses role="alert" and aria-live="assertive" so screen readers announce it immediately upon display.
Atomic announcementaria-atomic="true" ensures the entire toast (title + body) is read as one unit.
Close buttonUses aria-label="Close". Receives visible focus ring (:focus-visible) via --caat-focus token.
KeyboardClose button is reachable via Tab. Pressing Enter or Space dismisses the toast.
Colour contrastAll variant text meets WCAG 2.1 AA (4.5:1 minimum).
Colour not sole indicatorVariants pair colour with an icon and title text (e.g., "Error" + red + ✕ icon).
Reduced motionSlide-in animation is disabled when prefers-reduced-motion: reduce is active.
Auto-dismiss timingMinimum 5 000 ms delay. Error toasts should not auto-dismiss. Members can always dismiss manually.

9. SEO

Transient / structural UI with no indexable content of its own — no SEO markup required. Ensure any content this component wraps or reveals stays server-rendered and crawlable.

10. Analytics

Analytics are captured through the shared data-analytics-component attribute on the component root (emitted automatically) and reported to the central data layer. Event names and payloads follow the organisation's standard analytics schema — defined centrally with the analytics team, not invented per component — so no bespoke tracking is specified here.

11. AEM Notes

  • Resource type: caat/components/toast
  • Component group: CAAT Components – Feedback
  • Proxy: Create as a proxy component under /apps/caat/components/toast.
  • Policies: Configure allowed variants and auto-dismiss defaults per template via content policies.
  • Sling Model: com.caat.core.models.ToastModel — exposes title, body, variant, icon, actionLabel, actionUrl, autohide, delay.
  • HTL: toast.html — uses data-sly-attribute to set variant class and data attributes dynamically.
  • Client library: caat.components.toast (categories: caat.site). Includes JS for Bootstrap Toast initialization.
  • Render condition: Toast is rendered only when triggered by a server-side or client-side event — not displayed in the AEM editor preview by default.

12. Dialog Model (YAML)

Simplified model — shows field intent and Granite UI resource types, not the literal cq:dialog node tree (e.g. select options are authored as child items nodes).

title: Toast
description: Lightweight non-blocking notification for member feedback.
fields:
  - name: title
    label: Title
    type: textfield
    required: true
    maxLength: 60
    helpText: Short header text (e.g., "Success", "Session Expiring").

  - name: body
    label: Body
    type: textarea
    required: true
    maxLength: 200
    helpText: Notification message. Keep concise and actionable.

  - name: variant
    label: Variant
    type: select
    required: true
    options:
      - value: default
        label: Default (Blue)
      - value: success
        label: Success (Green)
      - value: warning
        label: Warning (Amber)
      - value: error
        label: Error (Red)
      - value: info
        label: Info (Blue)
    helpText: Determines accent colour and header background.

  - name: icon
    label: Icon
    type: iconpicker
    required: false
    helpText: Bootstrap Icon for the header (e.g., bi-check-circle-fill).

  - name: actionLabel
    label: Action Label
    type: textfield
    required: false
    maxLength: 30
    helpText: Optional action link text (e.g., "Undo", "View").

  - name: actionUrl
    label: Action URL
    type: pathpicker
    required: false
    helpText: Destination for the action link. Required if Action Label is set.

  - name: autohide
    label: Auto-dismiss
    type: checkbox
    required: false
    defaultValue: true
    helpText: Automatically hide the toast after the configured delay.

  - name: delay
    label: Dismiss Delay (ms)
    type: numberfield
    required: false
    defaultValue: 5000
    min: 3000
    helpText: Time before auto-dismiss. Minimum 3000 ms.

13. QA Acceptance Checklist

  • All four colour variants render correct left-border accent and header background.
  • Toast appears with slide-in animation from the right.
  • Animation is suppressed when prefers-reduced-motion: reduce is active.
  • Close button dismisses the toast and receives a visible focus ring on Tab.
  • Auto-dismiss hides the toast after the configured delay (default 5 000 ms).
  • Error-variant toast does not auto-dismiss by default.
  • Action link ("Undo", "View") is keyboard-accessible and announces correctly.
  • Screen reader (NVDA, VoiceOver) announces the toast title and body immediately on display.
  • Stacked toasts display in the bottom-right corner and stack vertically with spacing.
  • No more than 3 toasts visible simultaneously (oldest removed when a 4th is triggered).
  • Colour contrast meets WCAG 2.1 AA (4.5:1) for all variants.
  • Analytics events (toast-displayed, toast-dismissed, toast-action-click) fire correctly.
  • Cross-browser tested: Chrome, Firefox, Safari, Edge.

14. Definition of Done

AreaDone means
Design Figma component matches this contract. All four variant colours documented with accent tokens. Slide-in animation specified. Stacked layout pattern included.
Development AEM proxy component created. HTL template emits semantic HTML per Section 6. CSS uses design tokens exclusively. JS initializes Bootstrap Toast API. Reduced-motion fallback in place. Unit tests pass.
QA All items in the QA Acceptance Checklist (Section 13) pass. Manual accessibility audit completed. Cross-browser tested (Chrome, Firefox, Safari, Edge).
Launch Component deployed to AEM production. Content authors trained on variant selection and auto-dismiss configuration. Documentation published. Analytics dashboards confirmed receiving events.