Skip to main content

Spinner

Spinner

Loading indicator for async operations

Tags: component feedback loading

View Demo

Spinner is a loading indicator that shows when content is being loaded or an operation is in progress.

Import​

<script>
  import { Spinner } from '@classic-homes/theme-svelte';
</script>

Basic Usage​

<Spinner />

Props​

Prop Type Default Description
size 'sm' | 'md' | 'lg' | 'xl' 'md' Size of the spinner
label string 'Loading...' Accessible label for screen readers
class string - Additional CSS classes

Sizes​

<Spinner size="sm" />
<!-- 16px -->
<Spinner size="md" />
<!-- 24px -->
<Spinner size="lg" />
<!-- 32px -->
<Spinner size="xl" />
<!-- 48px -->
Size Dimensions Use Case
sm 16x16px (h-4 w-4) Inline, buttons
md 24x24px (h-6 w-6) Default, general use
lg 32x32px (h-8 w-8) Section loading
xl 48x48px (h-12 w-12) Full page loading

Custom Label​

Provide a descriptive label for screen readers:

<Spinner label="Loading user data..." />
<Spinner label="Saving changes..." />
<Spinner label="Processing payment..." />

Color​

The spinner inherits the current text color. Use Tailwind classes to change it:

<Spinner class="text-primary" />
<Spinner class="text-muted-foreground" />
<Spinner class="text-white" />

Accessibility​

The Spinner component includes:

  • role="status" for screen reader announcements
  • aria-label attribute with the label text
  • <title> element for SVG accessibility
  • Animation is purely decorative

Examples​

Button Loading State​

<Button disabled={loading}>
  {#if loading}
    <Spinner size="sm" label="Submitting..." class="mr-2" />
    Submitting...
  {:else}
    Submit
  {/if}
</Button>

Centered Loading​

<div class="flex items-center justify-center h-64">
  <Spinner size="lg" label="Loading content..." />
</div>

Full Page Loading​

<div class="fixed inset-0 flex items-center justify-center bg-background/80 z-50">
  <div class="text-center">
    <Spinner size="xl" label="Loading application..." />
    <p class="mt-4 text-muted-foreground">Loading...</p>
  </div>
</div>

Inline Loading​

<p>
  Checking availability
  <Spinner size="sm" class="inline ml-2" label="Checking..." />
</p>

Card Loading State​

<Card>
  <CardContent class="flex items-center justify-center h-32">
    {#if loading}
      <Spinner label="Loading data..." />
    {:else}
      <p>{data}</p>
    {/if}
  </CardContent>
</Card>

With Loading Text​

<div class="flex items-center gap-3">
  <Spinner size="md" />
  <span class="text-muted-foreground">Loading your dashboard...</span>
</div>

Table Loading​

<table>
  <tbody>
    {#if loading}
      <tr>
        <td colspan="4" class="text-center py-8">
          <Spinner label="Loading data..." />
        </td>
      </tr>
    {:else}
      {#each rows as row}
        <tr><!-- row content --></tr>
      {/each}
    {/if}
  </tbody>
</table>
On this page