Skip to main content

LoadingOverlay

Implemented

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.

Categorymolecules
Sourcepatterns/molecules/loadingoverlay.html
AI HintUse for an async gap where the user has acted and is waiting — submitting a payment, completing a checkout. Pass a message saying what is happening. aria-busy belongs on YOUR region, not on the overlay. Do not use it for content that has not painted yet (Skeleton), for measurable progress (ProgressBar), or over anything the user must still interact with — overlaying a payment challenge iframe breaks the payment. No focus trap or scroll lock by design; see ADR-047.

Catalog fallback

Live MDX preview not available for LoadingOverlay. Showing component catalog metadata instead.

Props

Preview

LoadingOverlay

Prop
Type
Required
Default
Description
open
boolean
Required
—

Controlled — the caller owns the state.

message
string
Required
—

What is happening, in the caller's language. Required: an overlay with no message only tells the user they cannot click.

detail
string
Optional
—

Optional second line, e.g. 'Please don't close this page.'

scope
"region" | "viewport"
Optional
'region'

'region' fills the nearest positioned ancestor — the caller must give it `relative`. 'viewport' portals to document.body.

delayMs
number
Optional
300

Wait before appearing so a fast response never flashes a spinner. 0 shows immediately.

Quick use:<LoadingOverlay />

Accessibility

ARIA rolestatus

ARIA

2 rules

WCAG 4.1.3

role='status' + aria-live='polite' on the card (not alert/assertive — waiting is not an emergency); the scrim is aria-hidden

WCAG 4.1.3

exactly ONE live region in the output — the Spinner is rendered `decorative` so it does not nest a second

Type

1 rule

NASA Rule 5

open=false renders nothing; open=true renders only after delayMs, and never if open goes false inside it

Usage

Import

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

Example 1

tsxSnippet
<LoadingOverlay open={submitting} message="Completing your purchase…" detail="Please don't close this page." />

Example 2

tsxSnippet
<LoadingOverlay open={busy} scope="viewport" message="Signing you in…" />

Example 3

tsxSnippet
<LoadingOverlay open={busy} delayMs={0} message="Loading…" />

Anti-patterns

— Do not hardcode data in molecules

— Avoid complex business logic in molecules

— Do not overlay an element the user still has to interact with

— Do not use for content placeholders — that is Skeleton

— Do not invent a percentage to show ProgressBar instead

Design System v4.1.0 | ePassLive