Skip to main content

Placeholder/Skeleton

The Placeholder/Skeleton components provide loading states and content placeholders for better user experience. They include individual skeleton elements, skeleton cards, skeleton lists, and skeleton forms that mimic the structure of actual content while data is loading.

Overview

The Placeholder/Skeleton components are designed to provide engaging loading states with:

  • Individual skeleton elements with various shapes and sizes
  • Pre-built skeleton cards for different content types
  • Skeleton lists for list-based content
  • Skeleton forms for form loading states
  • Customizable animations and styling
  • Dark mode support
  • Responsive design

Basic Usage

import { Skeleton } from '@/components/atoms'
import { SkeletonCard, SkeletonList, SkeletonForm } from '@/components/molecules'

function MyComponent() {
return (
<div className='space-y-4'>
{/* Basic skeleton */}
<Skeleton variant='text' width='w-full' height='h-4' />

{/* Skeleton card */}
<SkeletonCard variant='default' lines={3} />

{/* Skeleton list */}
<SkeletonList items={5} variant='default' showAvatar={true} />

{/* Skeleton form */}
<SkeletonForm fields={4} showTitle={true} showButtons={true} />
</div>
)
}

Skeleton Component

Props

PropTypeDefaultDescription
variantstring'text'Shape variant ('text', 'circle', 'rectangle', 'avatar', 'button')
classNamestring''Additional CSS classes
widthstring'w-full'Width CSS class
heightstring'h-4'Height CSS class
roundedstring'rounded'Border radius CSS class
animatedbooleantrueWhether to show pulse animation

Basic Skeleton

<Card>
<h4 className='mb-4'>Basic Skeleton</h4>
<div className='space-y-3'>
<Skeleton variant='text' width='w-full' height='h-4' />
<Skeleton variant='text' width='w-3/4' height='h-4' />
<Skeleton variant='text' width='w-1/2' height='h-4' />
</div>
</Card>

Skeleton with Avatar

<Card>
<h4 className='mb-4'>Skeleton with Avatar</h4>
<div className='flex items-center gap-4'>
<Skeleton variant='avatar' width='w-12' height='h-12' />
<div className='flex-1 space-y-2'>
<Skeleton variant='text' width='w-1/2' height='h-4' />
<Skeleton variant='text' width='w-3/4' height='h-3' />
</div>
</div>
</Card>

Skeleton Shapes

<Card>
<h4 className='mb-4'>Skeleton Shapes</h4>
<div className='space-y-4'>
<div className='flex items-center gap-4'>
<Skeleton variant='circle' width='w-8' height='h-8' />
<span className='text-sm text-gray-500'>Circle</span>
</div>
<div className='flex items-center gap-4'>
<Skeleton variant='rectangle' width='w-16' height='h-8' />
<span className='text-sm text-gray-500'>Rectangle</span>
</div>
<div className='flex items-center gap-4'>
<Skeleton variant='button' width='w-24' height='h-8' />
<span className='text-sm text-gray-500'>Button</span>
</div>
</div>
</Card>

Custom Sizes

<Card>
<h4 className='mb-4'>Skeleton with Custom Sizes</h4>
<div className='space-y-3'>
<Skeleton variant='text' width='w-32' height='h-2' />
<Skeleton variant='text' width='w-48' height='h-4' />
<Skeleton variant='text' width='w-64' height='h-6' />
<Skeleton variant='text' width='w-40' height='h-8' />
</div>
</Card>

Without Animation

<Card>
<h4 className='mb-4'>Skeleton without Animation</h4>
<div className='space-y-3'>
<Skeleton variant='text' width='w-full' height='h-4' animated={false} />
<Skeleton variant='text' width='w-3/4' height='h-4' animated={false} />
<Skeleton variant='text' width='w-1/2' height='h-4' animated={false} />
</div>
</Card>

SkeletonCard Component

Props

PropTypeDefaultDescription
variantstring'default'Card variant ('default', 'article', 'profile', 'table')
classNamestring''Additional CSS classes
showImagebooleanfalseWhether to show image skeleton
showAvatarbooleanfalseWhether to show avatar skeleton
linesnumber3Number of text lines (default variant only)

Default Card

<Card>
<h4 className='mb-4'>Skeleton Card - Default</h4>
<SkeletonCard variant='default' lines={4} />
</Card>

Article Card

<Card>
<h4 className='mb-4'>Skeleton Card - Article</h4>
<SkeletonCard variant='article' showImage={true} />
</Card>

Profile Card

<Card>
<h4 className='mb-4'>Skeleton Card - Profile</h4>
<SkeletonCard variant='profile' />
</Card>

Table Card

<Card>
<h4 className='mb-4'>Skeleton Card - Table</h4>
<SkeletonCard variant='table' showAvatar={true} />
</Card>

Card with Image

<Card>
<h4 className='mb-4'>Skeleton Card with Image</h4>
<SkeletonCard variant='default' showImage={true} lines={3} />
</Card>

Card with Avatar

<Card>
<h4 className='mb-4'>Skeleton Card with Avatar</h4>
<SkeletonCard variant='default' showAvatar={true} lines={3} />
</Card>

SkeletonList Component

Props

PropTypeDefaultDescription
itemsnumber5Number of list items
variantstring'default'List variant ('default', 'compact', 'detailed')
showAvatarbooleanfalseWhether to show avatar skeletons
showImagebooleanfalseWhether to show image skeletons
classNamestring''Additional CSS classes

Default List

<Card>
<h4 className='mb-4'>Skeleton List - Default</h4>
<SkeletonList items={3} variant='default' showAvatar={true} />
</Card>

Compact List

<Card>
<h4 className='mb-4'>Skeleton List - Compact</h4>
<SkeletonList items={5} variant='compact' showAvatar={true} />
</Card>

Detailed List

<Card>
<h4 className='mb-4'>Skeleton List - Detailed</h4>
<SkeletonList items={3} variant='detailed' showAvatar={true} showImage={true} />
</Card>

List with Avatars

<Card>
<h4 className='mb-4'>Skeleton List with Avatars</h4>
<SkeletonList items={4} variant='default' showAvatar={true} />
</Card>

List with Images

<Card>
<h4 className='mb-4'>Skeleton List with Images</h4>
<SkeletonList items={3} variant='detailed' showAvatar={true} showImage={true} />
</Card>

SkeletonForm Component

Props

PropTypeDefaultDescription
fieldsnumber4Number of form fields
showTitlebooleantrueWhether to show title skeleton
showButtonsbooleantrueWhether to show button skeletons
classNamestring''Additional CSS classes

Complete Form

<Card>
<h4 className='mb-4'>Skeleton Form</h4>
<SkeletonForm fields={5} showTitle={true} showButtons={true} />
</Card>

Form without Title

<Card>
<h4 className='mb-4'>Skeleton Form - No Title</h4>
<SkeletonForm fields={3} showTitle={false} showButtons={true} />
</Card>

Form without Buttons

<Card>
<h4 className='mb-4'>Skeleton Form - No Buttons</h4>
<SkeletonForm fields={4} showTitle={true} showButtons={false} />
</Card>

Minimal Form

<Card>
<h4 className='mb-4'>Minimal Skeleton Form</h4>
<SkeletonForm fields={2} showTitle={false} showButtons={false} />
</Card>

Advanced Examples

Skeleton Grid

<Card>
<h4 className='mb-4'>Skeleton Grid</h4>
<div className='grid grid-cols-2 gap-4'>
<SkeletonCard variant='default' lines={2} />
<SkeletonCard variant='default' lines={2} />
<SkeletonCard variant='default' lines={2} />
<SkeletonCard variant='default' lines={2} />
</div>
</Card>

Mixed Content Layout

<Card>
<h4 className='mb-4'>Mixed Content Layout</h4>
<div className='space-y-6'>
{/* Header */}
<div className='flex items-center gap-4'>
<Skeleton variant='avatar' width='w-16' height='h-16' />
<div className='flex-1 space-y-2'>
<Skeleton variant='text' width='w-1/3' height='h-6' />
<Skeleton variant='text' width='w-1/2' height='h-4' />
</div>
</div>

{/* Content */}
<div className='space-y-3'>
<Skeleton variant='text' width='w-full' height='h-4' />
<Skeleton variant='text' width='w-5/6' height='h-4' />
<Skeleton variant='text' width='w-4/6' height='h-4' />
</div>

{/* Actions */}
<div className='flex gap-3'>
<Skeleton variant='button' width='w-24' height='h-10' />
<Skeleton variant='button' width='w-24' height='h-10' />
</div>
</div>
</Card>

Dashboard Layout

<Card>
<h4 className='mb-4'>Dashboard Layout</h4>
<div className='space-y-6'>
{/* Stats Row */}
<div className='grid grid-cols-4 gap-4'>
{[...Array(4)].map((_, index) => (
<div key={index} className='space-y-2'>
<Skeleton variant='text' width='w-16' height='h-4' />
<Skeleton variant='text' width='w-24' height='h-8' />
</div>
))}
</div>

{/* Content Area */}
<div className='grid grid-cols-2 gap-6'>
<SkeletonCard variant='default' lines={4} />
<SkeletonList items={3} variant='compact' showAvatar={true} />
</div>
</div>
</Card>

Examples

Basic Skeleton

<Card>
<h4 className='mb-4'>Basic Skeleton</h4>
<div className='space-y-3'>
<Skeleton variant='text' width='w-full' height='h-4' />
<Skeleton variant='text' width='w-3/4' height='h-4' />
<Skeleton variant='text' width='w-1/2' height='h-4' />
</div>
</Card>

Skeleton with Avatar

<Card>
<h4 className='mb-4'>Skeleton with Avatar</h4>
<div className='flex items-center gap-4'>
<Skeleton variant='avatar' width='w-12' height='h-12' />
<div className='flex-1 space-y-2'>
<Skeleton variant='text' width='w-1/2' height='h-4' />
<Skeleton variant='text' width='w-3/4' height='h-3' />
</div>
</div>
</Card>

Skeleton Card - Default

<Card>
<h4 className='mb-4'>Skeleton Card - Default</h4>
<SkeletonCard variant='default' lines={4} />
</Card>

Skeleton Card - Article

<Card>
<h4 className='mb-4'>Skeleton Card - Article</h4>
<SkeletonCard variant='article' showImage={true} />
</Card>

Skeleton Card - Profile

<Card>
<h4 className='mb-4'>Skeleton Card - Profile</h4>
<SkeletonCard variant='profile' />
</Card>

Skeleton Card - Table

<Card>
<h4 className='mb-4'>Skeleton Card - Table</h4>
<SkeletonCard variant='table' showAvatar={true} />
</Card>

Skeleton List - Default

<Card>
<h4 className='mb-4'>Skeleton List - Default</h4>
<SkeletonList items={3} variant='default' showAvatar={true} />
</Card>

Skeleton List - Compact

<Card>
<h4 className='mb-4'>Skeleton List - Compact</h4>
<SkeletonList items={5} variant='compact' showAvatar={true} />
</Card>

Skeleton List - Detailed

<Card>
<h4 className='mb-4'>Skeleton List - Detailed</h4>
<SkeletonList items={3} variant='detailed' showAvatar={true} showImage={true} />
</Card>

Skeleton Shapes

<Card>
<h4 className='mb-4'>Skeleton Shapes</h4>
<div className='space-y-4'>
<div className='flex items-center gap-4'>
<Skeleton variant='circle' width='w-8' height='h-8' />
<span className='text-sm text-gray-500'>Circle</span>
</div>
<div className='flex items-center gap-4'>
<Skeleton variant='rectangle' width='w-16' height='h-8' />
<span className='text-sm text-gray-500'>Rectangle</span>
</div>
<div className='flex items-center gap-4'>
<Skeleton variant='button' width='w-24' height='h-8' />
<span className='text-sm text-gray-500'>Button</span>
</div>
</div>
</Card>

Skeleton with Custom Sizes

<Card>
<h4 className='mb-4'>Skeleton with Custom Sizes</h4>
<div className='space-y-3'>
<Skeleton variant='text' width='w-32' height='h-2' />
<Skeleton variant='text' width='w-48' height='h-4' />
<Skeleton variant='text' width='w-64' height='h-6' />
<Skeleton variant='text' width='w-40' height='h-8' />
</div>
</Card>

Skeleton Grid

<Card>
<h4 className='mb-4'>Skeleton Grid</h4>
<div className='grid grid-cols-2 gap-4'>
<SkeletonCard variant='default' lines={2} />
<SkeletonCard variant='default' lines={2} />
<SkeletonCard variant='default' lines={2} />
<SkeletonCard variant='default' lines={2} />
</div>
</Card>

Skeleton without Animation

<Card>
<h4 className='mb-4'>Skeleton without Animation</h4>
<div className='space-y-3'>
<Skeleton variant='text' width='w-full' height='h-4' animated={false} />
<Skeleton variant='text' width='w-3/4' height='h-4' animated={false} />
<Skeleton variant='text' width='w-1/2' height='h-4' animated={false} />
</div>
</Card>

Skeleton Form

<Card>
<h4 className='mb-4'>Skeleton Form</h4>
<SkeletonForm fields={5} showTitle={true} showButtons={true} />
</Card>

Skeleton Form - No Title

<Card>
<h4 className='mb-4'>Skeleton Form - No Title</h4>
<SkeletonForm fields={3} showTitle={false} showButtons={true} />
</Card>

Skeleton Form - No Buttons

<Card>
<h4 className='mb-4'>Skeleton Form - No Buttons</h4>
<SkeletonForm fields={4} showTitle={true} showButtons={false} />
</Card>

CSS Classes Reference

Skeleton Base

  • .bg-gray-200 - Light gray background
  • .dark:bg-gray-700 - Dark mode background
  • .animate-pulse - Pulse animation

Skeleton Variants

  • text - Text line skeleton
  • circle - Circular skeleton
  • rectangle - Rectangular skeleton
  • avatar - Avatar skeleton
  • button - Button skeleton

SkeletonCard

  • .skeleton-card - Base card container
  • .bg-white - Card background
  • .dark:bg-gray-800 - Dark mode card background
  • .rounded-lg - Rounded corners
  • .p-6 - Padding
  • .shadow-sm - Subtle shadow

SkeletonList

  • .skeleton-list - Base list container
  • .space-y-4 - Vertical spacing between items
  • .skeleton-item - Individual list item

SkeletonForm

  • .skeleton-form - Base form container
  • .space-y-6 - Vertical spacing between sections
  • .space-y-4 - Vertical spacing between fields
  • .space-y-2 - Vertical spacing between elements

Styling

The Placeholder/Skeleton components use Tailwind CSS classes and include:

  • Gray Backgrounds: Consistent skeleton colors
  • Dark Mode Support: Automatic dark mode variants
  • Pulse Animation: Smooth loading animation
  • Responsive Design: Works on all screen sizes
  • Flexible Sizing: Customizable width and height
  • Border Radius: Configurable rounded corners
  • Spacing: Consistent spacing patterns

Accessibility

The Placeholder/Skeleton components include accessibility features:

  • Semantic Structure: Proper HTML structure
  • Screen Reader Support: Non-interactive elements
  • Color Contrast: Proper contrast ratios
  • Animation Control: Optional animations
  • Focus Management: Non-focusable elements

Best Practices

  1. Use appropriate variants for your content type
  2. Match skeleton structure to actual content layout
  3. Consider animation preferences for users
  4. Use consistent sizing with actual content
  5. Provide meaningful context with skeleton titles
  6. Test with screen readers for accessibility

Common Use Cases

  • Content loading: Show while data is being fetched
  • List placeholders: Maintain layout during loading
  • Form placeholders: Show form structure before data loads
  • Card placeholders: Maintain card layout consistency
  • Dashboard loading: Show dashboard structure during initialization
  • Skeleton - Individual skeleton element
  • SkeletonCard - Pre-built skeleton cards
  • SkeletonList - Skeleton list layouts
  • SkeletonForm - Skeleton form layouts
  • Card - Often used as a container for skeleton examples