Back to all components

Loading States

Various loading animations and indicators

Loading States

A comprehensive collection of beautiful loading animations and indicators. Perfect for providing user feedback during async operations, data fetching, or any process that requires waiting time.

Features

  • Multiple Variants: Different loading styles for various use cases
  • Smooth Animations: Fluid, performant animations using Framer Motion
  • Customizable: Easy to modify colors, sizes, and animation speeds
  • Accessible: Proper ARIA labels and screen reader support
  • Responsive: Scales appropriately across all device sizes
  • Lightweight: Minimal bundle impact with optimized animations

Installation

npm install motion/react lucide-react

Basic Usage

import { Loader } from "@/components/ui/loader";
function MyComponent() {
return (
<div>
<Loader variant="spinner" size="md" />
</div>
);
}

Variants

Spinner

A classic spinning loader with customizable colors.

<Loader variant="spinner" />

Bounce

Bouncing dots that animate in a wave pattern.

<Loader variant="bounce" />

Pulse

A pulsing circle with fade effects.

<Loader variant="pulse" />

Morph

A morphing loader that changes shape and color.

<Loader variant="morph" />

Sizes

Loaders come in four sizes:

<Loader size="sm" /> // Small
<Loader size="md" /> // Medium (default)
<Loader size="lg" /> // Large
<Loader size="xl" /> // Extra large

Props

PropTypeDefaultDescription
variantstring-The type of loading animation
sizestring-The size of the loader
colorstring-The color of the loader
speedstring-Animation speed
classNamestring-Additional CSS classes

Examples

Button Loading State

function LoadingButton() {
const [isLoading, setIsLoading] = useState(false);
return (
<Button onClick={() => setIsLoading(true)} disabled={isLoading}>
{isLoading ? (
<>
<Loader size="sm" className="mr-2" />
Loading...
</>
) : (
"Submit"
)}
</Button>
);
}

Page Loading

function PageLoader() {
return (
<div className="flex min-h-screen items-center justify-center">
<div className="text-center">
<Loader size="xl" className="mb-4" />
<p className="text-neutral-600">Loading page...</p>
</div>
</div>
);
}

Skeleton Loading

function SkeletonCard() {
return (
<div className="rounded-lg border p-6">
<Loader variant="skeleton" className="mb-4 h-12 w-12 rounded-full" />
<Loader variant="skeleton" className="mb-2 h-4 w-3/4" />
<Loader variant="skeleton" className="h-4 w-1/2" />
</div>
);
}

Custom Colors

<Loader variant="spinner" color="#3b82f6" className="text-blue-500" />

Customization

Custom Animation Speed

<Loader variant="dots" speed="fast" className="text-red-500" />

Custom Sizes

<div className="flex items-center gap-4">
<Loader size="sm" />
<Loader size="md" />
<Loader size="lg" />
<Loader size="xl" />
</div>

Custom Variants

import { motion } from "motion/react";
const CustomLoader = () => (
<motion.div
animate={{ rotate: 360 }}
transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
className="h-8 w-8 rounded-full border-2 border-blue-500 border-t-transparent"
/>
);

Best Practices

  1. Appropriate Size: Use smaller loaders for buttons, larger for page loads
  2. Consistent Placement: Keep loaders in consistent locations across your app
  3. Meaningful Text: Include descriptive text with loaders when appropriate
  4. Accessibility: Always provide ARIA labels for screen readers
  5. Performance: Use lightweight animations for better performance

Accessibility

  • ARIA Labels: Proper labels for screen readers
  • Reduced Motion: Respect user's motion preferences
  • Focus Management: Proper focus handling during loading states
  • Color Contrast: Sufficient contrast for visibility

Performance Tips

  1. CSS Animations: Use CSS animations when possible for better performance
  2. Reduced Motion: Respect prefers-reduced-motion media query
  3. Optimized Bundles: Tree-shake unused loader variants
  4. Lazy Loading: Load heavy animations only when needed

Troubleshooting

Loader not animating?

Check if Framer Motion is properly installed and the component is wrapped in a motion provider.

Performance issues?

Consider using CSS-only animations for better performance on low-end devices.

Accessibility problems?

Ensure proper ARIA labels and test with screen readers.

Styling conflicts?

Check for conflicting CSS classes or Tailwind CSS purging issues.