Loading Overlay
The LoadingOverlay component provides fullscreen, container-scoped, and inline loading states with customizable spinners, backdrop effects, and accessibility features.
Overview
Loading overlays are essential for indicating active processes without blocking the entire interface. They provide visual feedback during data loading, form submissions, or other asynchronous operations while maintaining proper focus management and accessibility.
Interactive Demo
Overlay Types
Different positioning modes for various loading contexts
Fullscreen Overlay
Covers entire viewport with backdrop and focus trap
<LoadingOverlay position="fullscreen" />Container Overlay
Positioned absolutely within parent container
<LoadingOverlay position="container" />Inline Overlay
Displays as part of normal document flow
<LoadingOverlay position="inline" />API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
active | boolean | false | Controls overlay visibility |
config | LoadingConfig | Required | Configuration options |
state | LoadingState | - | Current loading state |
accent | 'jasper' \| 'info' \| 'none' | 'jasper' | Color accent for spinner |
onCancel | () => void | - | Callback for cancel action |
LoadingConfig
| Property | Type | Default | Description |
|---|---|---|---|
position | 'fullscreen' \| 'container' \| 'inline' | 'fullscreen' | Overlay positioning |
size | 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Size variant |
variant | 'spinner' \| 'dots' \| 'blob' | 'spinner' | Animation type |
backdrop | boolean | true | Show backdrop overlay |
backdropBlur | boolean | true | Apply backdrop blur effect |
showProgress | boolean | false | Display progress indicator |
showMessage | boolean | true | Display loading message |
focusTrap | boolean | true | Enable focus trapping |
minimumDuration | number | 300 | Minimum display time (ms) |
LoadingState
| Property | Type | Description |
|---|---|---|
id | string | Unique identifier |
active | boolean | Whether loading is active |
message | string | Loading message text |
startTime | number | Start timestamp |
cancellable | boolean | Can be cancelled by user |
Usage Examples
Basic Fullscreen
<script>
import LoadingOverlay from '$lib/loading/components/LoadingOverlay.svelte';
let isLoading = $state(false);
async function handleSubmit() {
isLoading = true;
try {
await submitData();
} finally {
isLoading = false;
}
}
</script>
<LoadingOverlay
active={isLoading}
config={{
position: 'fullscreen',
size: 'md',
variant: 'spinner',
backdrop: true,
backdropBlur: true
}}
state={{
id: 'submit-loading',
active: isLoading,
message: 'Submitting form...',
startTime: Date.now(),
cancellable: false
}}
/> Container-scoped Loading
<div class="data-panel" style="position: relative;">
<!-- Your content -->
<div class="panel-content">
{#each items as item}
<div class="item">{item.name}</div>
{/each}
</div>
<!-- Loading overlay -->
<LoadingOverlay
active={refreshing}
config={{
position: 'container',
size: 'sm',
variant: 'dots',
backdrop: true
}}
state={{
id: 'refresh-data',
active: refreshing,
message: 'Refreshing data...',
startTime: Date.now(),
cancellable: false
}}
/>
</div> Inline Loading State
<!-- Loading state within form -->
<form onsubmit|preventDefault={handleSubmit}>
<div class="form-fields">
<input type="email" bind:value={email} />
<input type="password" bind:value={password} />
</div>
{#if submitting}
<LoadingOverlay
active={submitting}
config={{
position: 'inline',
size: 'md',
variant: 'spinner',
backdrop: false,
showMessage: true
}}
state={{
id: 'form-submit',
active: submitting,
message: 'Signing in...',
startTime: Date.now(),
cancellable: false
}}
/>
{:else}
<button type="submit">Sign In</button>
{/if}
</form> With Cancel Support
<script>
import { useLoading } from '$lib/loading/components/use-loading';
const loading = useLoading();
let currentOperation = $state(null);
async function startLongOperation() {
const state = await loading.start({
message: 'Processing large dataset...',
estimatedDuration: 30000,
cancellable: true
});
currentOperation = state;
}
function cancelOperation() {
if (currentOperation) {
loading.cancel(currentOperation.id);
currentOperation = null;
}
}
</script>
<LoadingOverlay
active={!!currentOperation}
config={{
position: 'fullscreen',
size: 'lg',
variant: 'blob',
backdrop: true,
focusTrap: true
}}
state={currentOperation}
onCancel={cancelOperation}
/> Size Variants
Small (sm)
- Spinner: 24px
- Padding: 12px
- Typography: Muted size
- Use case: Inline elements, small containers
Medium (md) - Default
- Spinner: 32px
- Padding: 24px
- Typography: Caption size
- Use case: Standard overlays, form sections
Large (lg)
- Spinner: 40px
- Padding: 32px
- Typography: Body size
- Use case: Large containers, important processes
Extra Large (xl)
- Spinner: 48px
- Padding: 48px
- Typography: Subheading size
- Use case: Full-screen operations, critical processes
Animation Variants
Spinner (Default)
12-dot rotating animation - clean and professional.
Dots
Three-dot bouncing animation - playful and lightweight.
Blob
Morphing blob animation - modern and organic.
Accessibility Features
Focus Management
- Focus trap: Prevents tabbing outside modal during fullscreen overlay
- Return focus: Focus returns to trigger element when overlay closes
- Skip links: Provides escape routes for keyboard users
Screen Reader Support
- ARIA labels:
aria-labeldescribes current loading state - Live regions:
aria-liveannounces loading messages - Modal semantics:
role="dialog"andaria-modalfor fullscreen overlays
Keyboard Navigation
- Escape key: Cancels operation if
cancellableis true - Tab cycling: Moves between cancel button and any other focusable elements
Best Practices
When to Use Each Position
Fullscreen:
- Application initialization
- Critical operations that block all interaction
- Form submissions that affect global state
- Authentication processes
Container:
- Data refreshing in specific sections
- Partial page updates
- Component-specific operations
- List or table loading states
Inline:
- Button loading states
- Progressive form sections
- Embedded content loading
- Non-critical background processes
Performance Considerations
- Overlay content is only rendered when
activeis true - Backdrop filters use hardware acceleration when available
- Animations are optimized for 60fps performance
- Memory cleanup happens automatically on unmount
Visual Guidelines
- Keep messages concise and informative
- Use appropriate spinner sizes for context
- Consider backdrop blur for better content separation
- Ensure adequate contrast for accessibility
- Test on various screen sizes and devices