Skip to main content

Installation

    Usage

    A highly customizable loading spinner with wave animations.
    import { WaveSpinner } from "@/components/ui/wave-spinner";
    
    export default function Example() {
      return <WaveSpinner />;
    }
    

    Features

    Colors

    Choose from 10 color presets or use any CSS color:
    {/* Color presets */}
    <WaveSpinner color="primary" />   {/* GAIA blue #00bbff */}
    <WaveSpinner color="success" />   {/* Green */}
    <WaveSpinner color="danger" />    {/* Red */}
    <WaveSpinner color="warning" />   {/* Amber */}
    <WaveSpinner color="purple" />    {/* Purple */}
    
    {/* Custom colors */}
    <WaveSpinner color="#ff6b6b" />   {/* Hex */}
    <WaveSpinner color="rgb(255, 107, 107)" /> {/* RGB */}
    <WaveSpinner color="hsl(0, 100%, 71%)" />  {/* HSL */}
    
    Available presets: primary, success, warning, danger, muted, purple, cyan, rose, indigo, emerald

    Sizes

    Five size options:
    <WaveSpinner size="xs" />  {/* 3px dots */}
    <WaveSpinner size="sm" />  {/* 4px dots */}
    <WaveSpinner size="md" />  {/* 6px dots - Default */}
    <WaveSpinner size="lg" />  {/* 8px dots */}
    <WaveSpinner size="xl" />  {/* 10px dots */}
    

    Grid Patterns

    Seven layout patterns:
    <WaveSpinner pattern="square3x3" />  {/* 3x3 grid - Default */}
    <WaveSpinner pattern="square2x2" />  {/* 2x2 grid */}
    <WaveSpinner pattern="square4x4" />  {/* 4x4 grid */}
    <WaveSpinner pattern="line" />      {/* Single row */}
    <WaveSpinner pattern="diamond" />   {/* Diamond shape */}
    <WaveSpinner pattern="cross" />     {/* Plus sign */}
    <WaveSpinner pattern="circle" />    {/* Circular arrangement */}
    

    Animation Patterns

    Nine wave animation styles:
    <WaveSpinner animation="diagonalTL" />  {/* Top-left to bottom-right */}
    <WaveSpinner animation="diagonalTR" />  {/* Top-right to bottom-left */}
    <WaveSpinner animation="diagonalBL" />  {/* Bottom-left to top-right */}
    <WaveSpinner animation="diagonalBR" />  {/* Bottom-right to top-left */}
    <WaveSpinner animation="ripple" />      {/* From center outward */}
    <WaveSpinner animation="horizontal" />  {/* Left to right waves */}
    <WaveSpinner animation="vertical" />    {/* Top to bottom waves */}
    <WaveSpinner animation="random" />      {/* Pseudo-random pattern */}
    <WaveSpinner animation="spiral" />      {/* Spiral from center */}
    

    Dot Shapes

    Three shape options:
    <WaveSpinner dotShape="square" />   {/* Sharp corners - Default */}
    <WaveSpinner dotShape="rounded" />  {/* Rounded corners */}
    <WaveSpinner dotShape="circle" />   {/* Fully circular */}
    

    Animation Speed

    Custom duration in seconds:
    <WaveSpinner duration={0.5} />  {/* Fast */}
    <WaveSpinner duration={0.7} />  {/* Default */}
    <WaveSpinner duration={1.2} />  {/* Slow */}
    

    Props

    Examples

    Loading Button

    <button disabled className="flex items-center gap-2 px-4 py-2">
      <WaveSpinner size="sm" color="white" />
      <span>Loading...</span>
    </button>
    

    Centered Page Loader

    <div className="flex items-center justify-center min-h-screen">
      <div className="text-center">
        <WaveSpinner size="lg" />
        <p className="mt-4 text-muted-foreground">Loading your data...</p>
      </div>
    </div>
    

    Inline Spinner

    <p className="flex items-center gap-2">
      Processing
      <WaveSpinner size="xs" pattern="line" />
    </p>
    

    Custom Themed

    <WaveSpinner
      color="#ff6b6b"
      size="lg"
      pattern="circle"
      animation="ripple"
      dotShape="circle"
      duration={1.0}
    />
    

    Color Presets

    All available color presets:
    PresetColorHex
    primaryGAIA Blue#00bbff
    successGreen#22c55e
    warningAmber#f59e0b
    dangerRed#ef4444
    mutedZinc#71717a
    purplePurple#a855f7
    cyanCyan#06b6d4
    roseRose#f43f5e
    indigoIndigo#6366f1
    emeraldEmerald#10b981

    Animation Details

    The spinner uses CSS keyframe animations:
    @keyframes waveSpinnerPulse {
      0%, 100% {
        opacity: 0.3;
        transform: scale(0.8);
      }
      50% {
        opacity: 1;
        transform: scale(1);
      }
    }
    
    Each dot has a calculated delay based on the chosen animation pattern, creating the wave effect.

    Reduced Motion

    Respects user preferences:
    @media (prefers-reduced-motion: reduce) {
      [role="status"] div {
        animation-duration: 0s !important;
        opacity: 0.7 !important;
        transform: scale(1) !important;
      }
    }
    
    Users with reduced motion preferences see a static spinner.

    Accessibility

    • Has role="status" for screen reader announcements
    • Customizable aria-label for context-specific loading messages
    • Respects prefers-reduced-motion
    • Sufficient color contrast for all presets
    • Non-intrusive animation timing

    Build docs developers (and LLMs) love