Skip to main content
Skeleton components provide visual placeholders while content is loading, improving perceived performance and user experience.

Components

Skeleton

The base skeleton component for creating custom loading states.
import { Skeleton } from '@invopop/popui'
class
string
Additional CSS classes to customize appearance

SkeletonAvatar

A circular or square skeleton for avatar placeholders.
import { SkeletonAvatar } from '@invopop/popui'
size
number
default:"48"
The width and height of the avatar skeleton in pixels
class
string
Additional CSS classes to customize appearance

SkeletonCard

A composite skeleton with avatar and text lines, perfect for card or list item placeholders.
import { SkeletonCard } from '@invopop/popui'
avatarSize
number
default:"48"
The size of the avatar portion in pixels
lines
number
default:"2"
The number of text lines to display
width
number
default:"250"
The width of the text lines in pixels
class
string
Additional CSS classes to customize appearance

SkeletonList

Multiple skeleton lines for text content placeholders.
import { SkeletonList } from '@invopop/popui'
rows
number
default:"5"
The number of skeleton rows to display
width
number | string
default:"250"
The width of rows (in pixels if number, or CSS value if string)
class
string
Additional CSS classes to customize appearance

Usage

Basic Skeleton

<script>
  import { Skeleton } from '@invopop/popui'
</script>

<Skeleton class="h-12 w-64" />

Avatar Skeleton

<script>
  import { SkeletonAvatar } from '@invopop/popui'
</script>

<!-- Default 48px avatar -->
<SkeletonAvatar />

<!-- Custom size avatar -->
<SkeletonAvatar size={64} />

Card Skeleton

Perfect for loading states in user lists or comment sections:
<script>
  import { SkeletonCard } from '@invopop/popui'
</script>

<!-- Default card skeleton -->
<SkeletonCard />

<!-- Custom configuration -->
<SkeletonCard 
  avatarSize={56}
  lines={3}
  width={300}
/>

List Skeleton

<script>
  import { SkeletonList } from '@invopop/popui'
</script>

<!-- Default 5 rows -->
<SkeletonList />

<!-- Custom rows and width -->
<SkeletonList 
  rows={8}
  width={400}
/>

<!-- Responsive width with CSS -->
<SkeletonList 
  rows={3}
  width="100%"
/>

Loading Pattern Example

<script>
  import { SkeletonCard } from '@invopop/popui'
  
  let loading = $state(true)
  let users = $state([])
  
  async function loadUsers() {
    loading = true
    users = await fetchUsers()
    loading = false
  }
</script>

<div class="space-y-4">
  {#if loading}
    {#each Array(5) as _}
      <SkeletonCard avatarSize={48} lines={2} />
    {/each}
  {:else}
    {#each users as user}
      <UserCard {user} />
    {/each}
  {/if}
</div>

Custom Skeleton Shapes

<script>
  import { Skeleton } from '@invopop/popui'
</script>

<!-- Rectangle -->
<Skeleton class="h-32 w-full" />

<!-- Circle -->
<Skeleton class="h-20 w-20 rounded-full" />

<!-- Button shape -->
<Skeleton class="h-10 w-24 rounded-md" />

Implementation Details

  • Base skeleton uses animate-pulse for loading animation
  • Default background color: bg-background-default-tertiary
  • SkeletonList automatically makes the last row 80% width for natural appearance
  • All skeletons are highly customizable with Tailwind classes
  • Supports both fixed pixel widths and responsive CSS values

Build docs developers (and LLMs) love