Skip to main content

Overview

The Loader component is a full-screen loading indicator featuring a 3x3 grid of cells with a cascading ripple animation. Each cell animates with a unique delay and color from the green-cyan spectrum, creating a smooth, eye-catching loading experience.

Visual Design

The loader displays 9 cells arranged in a 3x3 grid. Each cell:
  • Animates from transparent to its assigned color and back
  • Uses staggered delays (0-400ms) to create a wave effect
  • Features vibrant colors ranging from Spotify green (#1db954) to cyan (#60efff)
  • Has rounded corners (4px border-radius)

Source Location

/workspace/source/src/app/components/ui/Loader.tsx

Props

This component accepts no props. It’s a self-contained loader with fixed styling.

Styling Approach

This component uses styled-components for CSS-in-JS styling, unlike other UI components in the codebase that use Tailwind CSS.

CSS Variables

The loader uses CSS custom properties for configuration:
--cell-size
string
default:"52px"
Size of each individual cell in the grid
--cell-spacing
string
default:"1px"
Spacing between cells
--cells
number
default:"3"
Number of cells per row/column
--cell-color
string
Color assigned to each cell via :nth-child() selectors

Animation Details

The ripple animation runs continuously with these characteristics:
  • Duration: 1.5 seconds
  • Easing: ease
  • Repeat: infinite
  • Keyframes: 0% → 30% → 60% → 100% (transparent → color → transparent → transparent)

Animation Delays

Cells use class-based delay modifiers:
.cell.d-0 // No delay
.cell.d-1 // 100ms delay
.cell.d-2 // 200ms delay
.cell.d-3 // 300ms delay
.cell.d-4 // 400ms delay

Usage Example

From /workspace/source/src/app/page.tsx:5,45-46,49:
import Loader from "./components/ui/Loader";

export default function Home() {
  const [loading, setLoading] = useState<boolean>(true);

  useEffect(() => {
    const timer = setTimeout(() => {
      setLoading(false);
    }, 500);

    return () => clearTimeout(timer);
  }, []);

  return (
    <>
      {loading ? (
        <Loader />
      ) : (
        <main className="w-screen max-w-[1600px] mx-auto...">
          <Suspense fallback={<Loader />}>
            {/* Page content */}
          </Suspense>
        </main>
      )}
    </>
  );
}
The loader is used both as an initial page loader and as a Suspense fallback for lazy-loaded components.

Color Palette

The loader uses 9 distinct colors in the green-cyan spectrum:
CellColor CodeVisual
1#1db954Spotify Green
2#0cfd95Mint Green
3#17fba2Light Green
4#23f9b2Aqua Green
5#30f7c3Turquoise
6#3df5d4Light Turquoise
7#45f4deCyan
8#53f1f0Light Cyan
9#60efffBright Cyan

Layout

The loader is positioned as a fixed overlay:
position: fixed;
top: 0;
left: 0;
z-index: 9999;
height: 100vh;
width: 100vw;
The z-index of 9999 ensures the loader appears above all other content during loading states.

Implementation Notes

  • No external dependencies besides React and styled-components
  • Self-contained animation logic using CSS keyframes
  • Fixed positioning covers entire viewport
  • Centered using flexbox alignment
  • No accessibility attributes (consider adding role="status" and aria-live="polite" for screen readers)

Build docs developers (and LLMs) love