Spinner

A rotating loader icon, 16px by default. Set size in pixels to match the text next to it.

Checking for updates
<script lang="ts">
    import { Spinner } from '@sivir-ui/svelte/components/spinner';
</script>

<div class="flex items-center gap-3 text-sm text-foreground-muted">
    <Spinner aria-hidden="true" />
    <span>Checking for updates</span>
</div>

Installation

Copy the command below and run it in your terminal.

bunx @sivir-ui/svelte add spinner

Usage

Spinner has no role or live region. Put text next to it that describes the work, and set aria-hidden so screen readers skip the icon. Set ready when the work finishes.

import { Spinner } from '@sivir-ui/svelte/components/spinner';

<Spinner ready={saved} aria-hidden="true" />
<span>{saved ? 'Saved' : 'Saving'}</span>

Speed and curved rotation

One turn takes 850ms; speed multiplies the rate, so a speed of 2 takes 425ms. curved speeds up and slows down within each turn instead of spinning at a constant rate.

Default Speed 2 Curved
<script lang="ts">
    import { Spinner } from '@sivir-ui/svelte/components/spinner';
</script>

<div class="flex flex-wrap items-center gap-x-6 gap-y-3 text-sm text-foreground-muted">
    <span class="flex items-center gap-2">
        <Spinner aria-hidden="true" />
        <span>Default</span>
    </span>
    <span class="flex items-center gap-2">
        <Spinner speed={2} aria-hidden="true" />
        <span>Speed 2</span>
    </span>
    <span class="flex items-center gap-2">
        <Spinner curved aria-hidden="true" />
        <span>Curved</span>
    </span>
</div>

Completion state

Set ready to true when the work succeeds. The spinner swaps to a checkmark, holds it for two seconds, then collapses and removes itself. Set ready back to false to show it again.

Saving changes
<script lang="ts">
    import { Button } from '@sivir-ui/svelte/components/button';
    import { Spinner } from '@sivir-ui/svelte/components/spinner';
    import { onDestroy, onMount } from 'svelte';

    let ready = $state(false);
    let timer: ReturnType<typeof setTimeout> | undefined;

    function save() {
        clearTimeout(timer);
        ready = false;
        timer = setTimeout(() => {
            ready = true;
        }, 900);
    }

    onMount(save);
    onDestroy(() => clearTimeout(timer));
</script>

<div
    class="flex w-full max-w-sm items-center justify-between gap-4 rounded-[var(--radius-md)] border border-border bg-card px-3 py-2"
>
    <div class="flex items-center gap-2 text-sm text-foreground-muted">
        <Spinner {ready} aria-hidden="true" />
        <span>{ready ? 'Changes saved' : 'Saving changes'}</span>
    </div>
    <Button size="md" onclick={save}>Save again</Button>
</div>

Anatomy

Spinner - Spins while loading and resolves to a checkmark.