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
Prop | Type | Default | Description |
---|---|---|---|
variant | string | - | The type of loading animation |
size | string | - | The size of the loader |
color | string | - | The color of the loader |
speed | string | - | Animation speed |
className | string | - | 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.divanimate={{ 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
- Appropriate Size: Use smaller loaders for buttons, larger for page loads
- Consistent Placement: Keep loaders in consistent locations across your app
- Meaningful Text: Include descriptive text with loaders when appropriate
- Accessibility: Always provide ARIA labels for screen readers
- 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
- CSS Animations: Use CSS animations when possible for better performance
- Reduced Motion: Respect
prefers-reduced-motion
media query - Optimized Bundles: Tree-shake unused loader variants
- 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.