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'
Additional CSS classes to customize appearance
SkeletonAvatar
A circular or square skeleton for avatar placeholders.
import { SkeletonAvatar } from '@invopop/popui'
The width and height of the avatar skeleton in pixels
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'
The size of the avatar portion in pixels
The number of text lines to display
The width of the text lines in pixels
Additional CSS classes to customize appearance
SkeletonList
Multiple skeleton lines for text content placeholders.
import { SkeletonList } from '@invopop/popui'
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)
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