Skeleton

Skeleton is a placeholder component used to display the loading state of content before the actual data is loaded, providing users with a visual indication of the page structure.

Basic Skeleton Example

import { Skeleton } from "aki-ui";

export default function SkeletonExample() {
  return (
    <Skeleton variant="text" width="100%" height="1rem" />
  );
}

Variants

Skeletons come in different variants to match the content they're replacing.

Text

Circular

Rectangular

Rounded

import { Skeleton } from "aki-ui";

export default function SkeletonVariants() {
  return (
    <div className="space-y-4">
      <Skeleton variant="text" width="75%" height="1rem" />
      <Skeleton variant="circular" width={48} height={48} />
      <Skeleton variant="rectangular" width="100%" height={80} />
      <Skeleton variant="rounded" width="100%" height={80} borderRadius="0.5rem" />
    </div>
  );
}

Text Skeleton with Multiple Lines

Create text skeletons with multiple lines for paragraph placeholders.

import { Skeleton } from "aki-ui";

export default function MultiLineSkeletonExample() {
  return (
    <Skeleton 
      variant="text" 
      width="100%" 
      lines={3}
      gap="0.5rem"
      shortenLastLine={true}
    />
  );
}

Animation Types

Skeletons can have different animation styles or no animation at all.

Pulse Animation

Wave Animation (simulated)

No Animation

import { Skeleton } from "aki-ui";

export default function SkeletonAnimations() {
  return (
    <div className="space-y-4">
      <Skeleton 
        variant="text" 
        width="75%" 
        animation="pulse" 
      />
      <Skeleton 
        variant="text" 
        width="75%" 
        animation="wave" 
      />
      <Skeleton 
        variant="text" 
        width="75%" 
        animation={false} 
      />
    </div>
  );
}

Complex UI Examples

Skeletons can be combined to create placeholders for complex UI elements.

import { Skeleton, Card } from "aki-ui";

export default function SkeletonCard() {
  return (
    <Card className="w-full">
      <Skeleton variant="rounded" height={160} />
      <div className="p-4 space-y-4">
        <Skeleton variant="text" width="70%" height="1.25rem" />
        <Skeleton variant="text" lines={3} />
        <div className="flex gap-2">
          <Skeleton variant="rounded" width={80} height={32} />
          <Skeleton variant="rounded" width={80} height={32} />
        </div>
      </div>
    </Card>
  );
}

Skeleton Container

Use the SkeletonContainer to conditionally show a skeleton or the actual content based on loading state.

Toggle between states:

import { useState, useEffect } from 'react';
import { SkeletonContainer, Skeleton, Card } from "aki-ui";

export default function LoadingExample() {
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    // Simulate loading for 3 seconds
    const timer = setTimeout(() => {
      setLoading(false);
    }, 3000);
    
    return () => clearTimeout(timer);
  }, []);
  
  return (
    <div>
      <button 
        className="mb-4 px-4 py-2 bg-blue-500 text-white rounded"
        onClick={() => setLoading(true)}
      >
        Reload
      </button>
      
      <SkeletonContainer
        loading={loading}
        fallback={
          <Card className="p-4">
            <h2 className="text-xl font-bold">Product Details</h2>
            <div className="mt-2">
              <p>Awesome product with amazing features!</p>
              <p className="mt-2">
                This product will revolutionize the way you work and play.
              </p>
            </div>
          </Card>
        }
      >
        <Card className="p-4">
          <Skeleton variant="text" width="60%" height="1.5rem" />
          <div className="mt-2">
            <Skeleton variant="text" lines={3} />
          </div>
        </Card>
      </SkeletonContainer>
    </div>
  );
}

Props Reference

PropTypeDefaultDescription
varianttext, circular, rectangular, roundedtextType of skeleton to render
widthnumber | string100%Width of the skeleton (number in px or CSS value)
heightnumber | string1remHeight of the skeleton (number in px or CSS value)
linesnumber1Number of lines for text variant
animationboolean, pulse, wavepulseAnimation type
shortenLastLinebooleanfalseWhether to make the last line shorter
gapstring0.5remGap between multiple lines
colorstring-Custom color for the skeleton
borderRadiusstring-Border radius for rounded variant

SkeletonContainer Props

PropTypeDefaultDescription
loadingbooleantrueWhether to show the skeleton or the actual content
childrenReactNode-Skeleton UI to show during loading
fallbackReactNode-Actual content to show when loading is complete