Skip to main content
Lumidot animations are built on a grid system. You can configure the number of rows and columns to create loading animations of different shapes and sizes.

Grid Props

rows

Sets the number of horizontal rows in the dot grid.
  • Type: number
  • Default: 3 (from DEFAULT_GRID constant)
  • Minimum: 1

cols

Sets the number of vertical columns in the dot grid.
  • Type: number
  • Default: 3 (from DEFAULT_GRID constant)
  • Minimum: 1

Default Grid

From the source code (index.tsx:11-246):
const DEFAULT_GRID = 3;

const Lumidot = React.forwardRef<HTMLSpanElement, LumidotProps>(
  ({
    rows = DEFAULT_GRID,
    cols = DEFAULT_GRID,
    // ... other props
  }, ref) => {
    // ...
  }
);
When no rows or cols are specified, Lumidot creates a 3×3 grid with 9 dots total.

Grid Size Calculation

The component calculates dot sizes automatically to maintain consistent proportions:
const size = 20 * scale;              // Base size multiplied by scale
const totalDots = rows * cols;         // Total number of dots
const gridMax = Math.max(rows, cols);  // Larger dimension
const dotSize = size / gridMax;        // Size of each dot
From index.tsx:366-370, the grid layout is applied:
style={{
  display: 'inline-grid',
  gridTemplateColumns: `repeat(${cols}, ${dotSize}px)`,
  gridTemplateRows: `repeat(${rows}, ${dotSize}px)`,
  gap: 0,
  width: cols * dotSize,
  height: rows * dotSize,
  // ...
}}
The dot size is determined by dividing the base size by the larger dimension (Math.max(rows, cols)). This ensures rectangular grids maintain proportional dots.

Usage Examples

Square grids

<Lumidot 
  pattern="corners-sync" 
  variant="blue" 
  rows={2} 
  cols={2} 
/>

Rectangular grids

<Lumidot 
  pattern="wave-lr" 
  variant="orange" 
  rows={1} 
  cols={5} 
/>

Grid-aware Patterns

Many patterns adapt to the grid dimensions automatically. Here are examples of how different patterns behave with various grid sizes:

Line patterns

// Horizontal line at the top
<Lumidot pattern="line-h-top" rows={5} cols={7} />

// Middle column
<Lumidot pattern="line-v-mid" rows={5} cols={5} />

// Diagonal from top-left to bottom-right
<Lumidot pattern="line-diag-1" rows={5} cols={5} />
From index.tsx:13-42, line patterns use grid-aware functions:
function topRow(rows: number, cols: number): number[] {
  return Array.from({ length: cols }, (_, c) => c);
}

function midCol(rows: number, cols: number): number[] {
  const c = Math.floor(cols / 2);
  return Array.from({ length: rows }, (_, r) => r * cols + c);
}

function diag1(rows: number, cols: number): number[] {
  const n = Math.min(rows, cols);
  return Array.from({ length: n }, (_, i) => i * cols + i);
}

Frame and perimeter patterns

// Animates around the perimeter
<Lumidot pattern="frame" rows={4} cols={6} />

// All perimeter dots at once
<Lumidot pattern="frame-sync" rows={5} cols={5} />
The perimeter is calculated from index.tsx:53-60:
function perimeterOrdered(rows: number, cols: number): number[] {
  if (rows < 2 || cols < 2) return rows * cols === 1 ? [0] : topRow(rows, cols).concat(bottomRow(rows, cols));
  const top = topRow(rows, cols);
  const right = rightCol(rows, cols).slice(1);
  const bottom = bottomRow(rows, cols).slice(0, -1).reverse();
  const left = leftCol(rows, cols).slice(1, -1).reverse();
  return [...top, ...right, ...bottom, ...left];
}

Center and corner patterns

// Center dot (calculated from grid dimensions)
<Lumidot pattern="solo-center" rows={5} cols={5} />

// All four corners simultaneously
<Lumidot pattern="corners-sync" rows={4} cols={6} />
The center is calculated at index.tsx:33-35:
function center(rows: number, cols: number): number {
  return Math.floor(rows / 2) * cols + Math.floor(cols / 2);
}

Combining with Scale

You can adjust both grid size and scale to create loading animations of any dimensions:
// Small 5×5 grid
<Lumidot 
  pattern="wave-lr" 
  variant="blue" 
  rows={5} 
  cols={5} 
  scale={0.5} 
/>

// Large 7×7 grid
<Lumidot 
  pattern="spiral" 
  variant="purple" 
  rows={7} 
  cols={7} 
  scale={2} 
/>
For wave patterns like wave-lr, wave-rl, wave-tb, and wave-bt, larger grids create more pronounced wave effects with smoother animations.
Very large grids (10×10 or more) may impact performance, as each dot is rendered as a separate DOM element. Use scale to increase visual size rather than adding more dots when possible.

Next Steps

Learn how to control animation timing and direction

Build docs developers (and LLMs) love