Flexible loading overlay for fullscreen, section, or inline use
Tags: component feedback loading overlay
A composable loading indicator that works at three scope levels: fullscreen, section overlay, or inline. Renders different indicator types (spinner, logo, progress bar, skeleton) and supports delayed appearance to prevent flash on fast operations.
Import
<script>
import { LoadingOverlay } from '@classic-homes/theme-svelte';
</script>import { LoadingOverlay } from '@classic-homes/theme-react';Basic Usage
<!-- Overlay on a section (default mode) -->
<div class="relative" style="height: 200px;">
<p>Content behind the overlay</p>
<LoadingOverlay loading />
</div>Props
| Prop | Type | Default | Description |
|---|---|---|---|
loading |
boolean |
true |
Whether loading is active |
variant |
'spinner' | 'logo' | 'progress' | 'skeleton' |
'spinner' |
Which indicator to show |
mode |
'fullscreen' | 'overlay' | 'inline' |
'overlay' |
Positioning mode |
size |
'sm' | 'md' | 'lg' | 'xl' |
'md' |
Indicator size |
message |
string |
- | Loading message text |
progress |
number |
- | Progress value (0–100) for progress variant |
blur |
boolean |
true |
Backdrop blur on overlay/fullscreen modes |
opaque |
boolean |
false |
Fully opaque background |
delay |
number |
0 |
Delay in ms before showing |
children |
Snippet (Svelte) / ReactNode (React) |
- | Content behind the overlay |
class |
string |
- | Additional CSS classes |
Modes
Overlay (default)
Covers a positioned parent container. The parent must have position: relative.
<div class="relative" style="height: 200px;">
<p>Your content here</p>
<LoadingOverlay loading variant="spinner" message="Loading data..." />
</div>- Uses
position: absolute; inset: 0; z-index: 10 - Semi-transparent background (
bg-background/60) - Optional backdrop blur
Fullscreen
Covers the entire viewport, typically for initial app loading.
<LoadingOverlay loading mode="fullscreen" variant="logo" message="Starting app..." />- Uses
position: fixed; inset: 0; z-index: 50 - Semi-transparent background (
bg-background/80) - Centers indicator in viewport
For full-page loading screens, consider using LoadingPage instead, which provides a branded experience with logo and progress bar.
Inline
Renders as an inline element, useful for loading states within text or buttons.
<LoadingOverlay mode="inline" variant="spinner" size="sm" message="Saving..." />- Uses
display: inline-flex; align-items: center; gap: 0.5rem - No background or positioning
- Compact indicator with optional message
Variants
Spinner
Default circular spinning indicator:
<LoadingOverlay variant="spinner" />Logo
Branded loading with the Classic Homes logo animation:
<LoadingOverlay variant="logo" />Progress
Horizontal progress bar (use with progress prop):
<LoadingOverlay variant="progress" progress={45} />Skeleton
Content placeholder skeleton:
<LoadingOverlay variant="skeleton" />Renders a preset skeleton layout (title + text lines).
Indicator Sizes
| Size | Spinner | Logo |
|---|---|---|
sm |
16px | 32px |
md |
24px | 40px |
lg |
32px | 56px |
xl |
48px | 80px |
<LoadingOverlay size="sm" />
<LoadingOverlay size="lg" />Delay
Prevent flash for fast operations by delaying the overlay appearance:
<!-- Only shows if loading takes longer than 300ms -->
<LoadingOverlay loading delay={300} />This is useful for operations that usually complete quickly but may occasionally be slow.
Examples
Section Loading
<div class="relative border rounded-lg" style="min-height: 200px;">
<div class="p-4">
<h3>Dashboard Stats</h3>
<p>Revenue: $45,231</p>
</div>
<LoadingOverlay loading={isLoading} message="Refreshing..." />
</div>Inline Save Indicator
<div class="flex items-center gap-4">
<Button onclick={save}>Save</Button>
{#if saving}
<LoadingOverlay mode="inline" size="sm" message="Saving changes..." />
{/if}
</div>Opaque Overlay
<!-- Fully opaque, hides content completely -->
<div class="relative" style="height: 200px;">
<p>Sensitive content</p>
<LoadingOverlay loading opaque />
</div>Without Blur
<div class="relative" style="height: 200px;">
<p>Content visible without blur</p>
<LoadingOverlay loading blur={false} />
</div>Accessibility
- Uses
role="status"andaria-live="polite"to announce loading state to screen readers - Provides sr-only fallback text ("Loading") when no message is provided
- Does not manage
aria-busyon the content container — use LoadingSection for that pattern, or set it yourself on the parent
<div class="relative" aria-busy={loading}>
<MyContent />
<LoadingOverlay {loading} message="Loading content..." />
</div>Related Components
- LoadingPage - Branded full-page loading screen
- LoadingSection - Section wrapper with built-in
aria-busy - Spinner - Standalone spinner component
- ProgressBar - Standalone progress bar
- Skeleton - Content placeholder