loading-state-patterns

Patterns for skeleton loaders, shimmer effects, and loading states that match design system aesthetics. Covers skeleton components, shimmer animations, and progressive loading. Use when building polished loading experiences. Triggers on skeleton, loading state, shimmer, placeholder, loading animation.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "loading-state-patterns" with this command: npx skills add wpank/loading-state-patterns

Loading State Patterns

Build loading states that feel intentional and match your design system aesthetic.


When to Use

  • Building skeleton loaders for content areas
  • Need shimmer effects for streaming content
  • Want progressive loading experiences
  • Building premium loading UX

Pattern 1: Skeleton Base

import { cn } from '@/lib/utils';

interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
  shimmer?: boolean;
}

export function Skeleton({ className, shimmer = true, ...props }: SkeletonProps) {
  return (
    <div
      className={cn(
        'rounded-md bg-muted',
        shimmer && 'animate-shimmer bg-gradient-to-r from-muted via-muted-foreground/10 to-muted bg-[length:200%_100%]',
        className
      )}
      {...props}
    />
  );
}

CSS Animation

@keyframes shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.animate-shimmer {
  animation: shimmer 1.5s ease-in-out infinite;
}

Pattern 2: Content Skeleton Layouts

Card Skeleton

export function CardSkeleton() {
  return (
    <div className="rounded-lg border bg-card p-4 space-y-3">
      <div className="flex items-center gap-3">
        <Skeleton className="size-10 rounded-full" />
        <div className="space-y-1.5 flex-1">
          <Skeleton className="h-4 w-1/3" />
          <Skeleton className="h-3 w-1/4" />
        </div>
      </div>
      <Skeleton className="h-20 w-full" />
      <div className="flex gap-2">
        <Skeleton className="h-8 w-20" />
        <Skeleton className="h-8 w-20" />
      </div>
    </div>
  );
}

Table Row Skeleton

export function TableRowSkeleton({ columns = 4 }: { columns?: number }) {
  return (
    <tr>
      {Array.from({ length: columns }).map((_, i) => (
        <td key={i} className="p-3">
          <Skeleton className="h-4 w-full" />
        </td>
      ))}
    </tr>
  );
}

Metric Skeleton

export function MetricSkeleton() {
  return (
    <div className="space-y-2">
      <Skeleton className="h-3 w-16" />
      <Skeleton className="h-8 w-24" />
    </div>
  );
}

Pattern 3: Design System Skeleton

Match skeleton to your aesthetic:

// For retro-futuristic theme
export function CyberSkeleton({ className, ...props }: SkeletonProps) {
  return (
    <div
      className={cn(
        'rounded-md bg-tone-cadet/30',
        'animate-pulse-glow',
        'border border-tone-cyan/10',
        className
      )}
      {...props}
    />
  );
}

// CSS
@keyframes pulse-glow {
  0%, 100% { opacity: 0.4; box-shadow: 0 0 0 0 rgba(var(--tone-cyan), 0); }
  50% { opacity: 0.6; box-shadow: 0 0 8px 0 rgba(var(--tone-cyan), 0.1); }
}

Pattern 4: Progressive Loading

Show content as it loads:

interface ProgressiveLoadProps {
  isLoading: boolean;
  skeleton: React.ReactNode;
  children: React.ReactNode;
}

export function ProgressiveLoad({
  isLoading,
  skeleton,
  children,
}: ProgressiveLoadProps) {
  return (
    <div className="relative">
      {isLoading ? (
        skeleton
      ) : (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ duration: 0.2 }}
        >
          {children}
        </motion.div>
      )}
    </div>
  );
}

Pattern 5: Streaming Content Indicator

For AI/LLM content that streams:

export function StreamingIndicator() {
  return (
    <div className="flex items-center gap-1">
      {[0, 1, 2].map((i) => (
        <motion.div
          key={i}
          className="size-1.5 rounded-full bg-primary"
          animate={{ scale: [1, 1.3, 1], opacity: [0.5, 1, 0.5] }}
          transition={{
            duration: 0.8,
            repeat: Infinity,
            delay: i * 0.15,
          }}
        />
      ))}
    </div>
  );
}

Pattern 6: Loading Progress Bar

interface LoadingProgressProps {
  progress?: number; // 0-100, undefined = indeterminate
}

export function LoadingProgress({ progress }: LoadingProgressProps) {
  const isIndeterminate = progress === undefined;

  return (
    <div className="h-1 w-full bg-muted overflow-hidden rounded-full">
      <div
        className={cn(
          'h-full bg-primary transition-all duration-300',
          isIndeterminate && 'animate-indeterminate'
        )}
        style={!isIndeterminate ? { width: `${progress}%` } : undefined}
      />
    </div>
  );
}

// CSS
@keyframes indeterminate {
  0% { transform: translateX(-100%); width: 50%; }
  100% { transform: translateX(200%); width: 50%; }
}

.animate-indeterminate {
  animation: indeterminate 1.5s ease-in-out infinite;
}

Pattern 7: Skeleton Grid

export function GridSkeleton({ 
  count = 6, 
  columns = 3 
}: { 
  count?: number; 
  columns?: number;
}) {
  return (
    <div 
      className="grid gap-4" 
      style={{ gridTemplateColumns: `repeat(${columns}, 1fr)` }}
    >
      {Array.from({ length: count }).map((_, i) => (
        <CardSkeleton key={i} />
      ))}
    </div>
  );
}

Related Skills


NEVER Do

  • Use gray skeletons on dark themes — Match your surface colors
  • Skip shimmer animation — Static blocks look broken
  • Make skeletons exact size — Slight size variation is natural
  • Forget aspect ratios — Images need consistent skeleton ratios
  • Show skeleton forever — Add timeout fallbacks for errors

Quick Reference

// Basic skeleton
<Skeleton className="h-4 w-full" />

// Avatar skeleton
<Skeleton className="size-10 rounded-full" />

// Text lines
<div className="space-y-2">
  <Skeleton className="h-4 w-3/4" />
  <Skeleton className="h-4 w-1/2" />
</div>

// Card skeleton
<div className="p-4 space-y-3">
  <Skeleton className="h-6 w-1/3" />
  <Skeleton className="h-20 w-full" />
</div>

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Ai Competitor Analyzer

提供AI驱动的竞争对手分析,支持批量自动处理,提升企业和专业团队分析效率与专业度。

Registry SourceRecently Updated
General

Ai Data Visualization

提供自动化AI分析与多格式批量处理,显著提升数据可视化效率,节省成本,适用企业和个人用户。

Registry SourceRecently Updated
General

Ai Cost Optimizer

提供基于预算和任务需求的AI模型成本优化方案,计算节省并指导OpenClaw配置与模型切换策略。

Registry SourceRecently Updated