Skeleton

SkeletonSwap waits 120ms before showing its placeholder and then keeps it up for at least 380ms, so fast loads skip it and slow ones don't flash. Skeleton is a static block for building your own placeholder.

<script lang="ts">
    import { SkeletonSwap } from '@sivir-ui/svelte/components/skeleton';
    import { onMount } from 'svelte';

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

    onMount(() => {
        timer = setTimeout(() => (ready = true), 850);
        return () => clearTimeout(timer);
    });
</script>

<div class="w-full max-w-sm">
    <SkeletonSwap {ready} lines={3} lineHeight={21} label="Profile">
        {#if ready}
            <p class="text-sm leading-[21px] text-foreground-muted">
                Product designer in Lisbon. Works on onboarding and billing. Previously led the design system at a travel startup.
            </p>
        {/if}
    </SkeletonSwap>
</div>

Installation

Copy the command below and run it in your terminal.

bunx @sivir-ui/svelte add skeleton

Usage

Set ready when the data arrives. The box is lines × lineHeight tall (3 × 21px by default), or pass reserve for a fixed pixel height. Taller content scrolls inside it. With label, screen readers hear "Profile loaded" when the content appears.

import { SkeletonSwap } from '@sivir-ui/svelte/components/skeleton';

<SkeletonSwap ready={profile !== null} lines={3} label="Profile">
  {#if profile}<p>{profile.bio}</p>{/if}
</SkeletonSwap>

Examples

These use Skeleton, which takes w and h in px unless you set unit. Pass Skeleton blocks to the SkeletonSwap skeleton snippet to replace its default bars.

Rectangle

<script lang="ts">
    import { Skeleton } from '@sivir-ui/svelte/components/skeleton';
</script>

<Skeleton w={280} h={160} />

Circle

<script lang="ts">
    import { Skeleton } from '@sivir-ui/svelte/components/skeleton';
</script>

<Skeleton w={100} h={100} class="rounded-full" />

Card composition

<script lang="ts">
    import { Skeleton } from '@sivir-ui/svelte/components/skeleton';
</script>

<div class="flex flex-col gap-3">
    <Skeleton w={280} h={160} />
    <Skeleton w={200} h={20} />
    <Skeleton w={150} h={16} />
</div>

Anatomy

Skeleton - Displays a static loading placeholder.

SkeletonSwap - Shows a delayed placeholder in a fixed-height box until ready.