Skip to main content

Loading Overlay

Fullscreen, container, and inline loading overlays with spinner animations and backdrop effects

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

Sample Content Container overlay demo
<LoadingOverlay position="container" />

Inline Overlay

Displays as part of normal document flow

<LoadingOverlay position="inline" />

API Reference

Props

PropTypeDefaultDescription
activebooleanfalseControls overlay visibility
configLoadingConfigRequiredConfiguration options
stateLoadingState-Current loading state
accent'jasper' \| 'info' \| 'none''jasper'Color accent for spinner
onCancel() => void-Callback for cancel action

LoadingConfig

PropertyTypeDefaultDescription
position'fullscreen' \| 'container' \| 'inline''fullscreen'Overlay positioning
size'sm' \| 'md' \| 'lg' \| 'xl''md'Size variant
variant'spinner' \| 'dots' \| 'blob''spinner'Animation type
backdropbooleantrueShow backdrop overlay
backdropBlurbooleantrueApply backdrop blur effect
showProgressbooleanfalseDisplay progress indicator
showMessagebooleantrueDisplay loading message
focusTrapbooleantrueEnable focus trapping
minimumDurationnumber300Minimum display time (ms)

LoadingState

PropertyTypeDescription
idstringUnique identifier
activebooleanWhether loading is active
messagestringLoading message text
startTimenumberStart timestamp
cancellablebooleanCan 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-label describes current loading state
  • Live regions: aria-live announces loading messages
  • Modal semantics: role="dialog" and aria-modal for fullscreen overlays

Keyboard Navigation

  • Escape key: Cancels operation if cancellable is 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 active is 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