PulseGrid

A blueprint of ticks that light in a diagonal wave — the loader that looks like the library measuring your layout, because that is the house style.

Install

$ npx shadcn@latest add wisp.pouriah.com/r/pulse-grid.json
Loader · CSSno JS
a front crossing the grid

PulseGridesc or double-click to exit full screendouble-tap to exit

loaders/pulse-grid.tsx
"use client";

import * as React from "react";
import { cx } from "@pouriahlabs/wisp-ui";

/**
 * PulseGrid — the loader that looks like the library measuring your layout.
 *
 * A grid of ticks that light in a diagonal wave, each cell delayed by its
 * distance from the top-left corner. It is the same blueprint vocabulary the
 * atmosphere tier draws in, shrunk to a hold: the house style, applied to the
 * wait.
 *
 * The wave is pure CSS — every cell runs one keyframe on a stagger the render
 * writes into an inline custom property. Colour is one token, so a theme swap
 * re-tints the whole grid, and under reduced motion the cells settle to a
 * legible resting state rather than blinking out.
 */

export interface PulseGridProps extends React.HTMLAttributes<HTMLDivElement> {
  /** Token for the tick colour. */
  token?: string;
  /** Columns across. */
  cols?: number;
  /** Rows down. */
  rows?: number;
  /** Seconds for one full pulse of a cell. */
  duration?: number;
  /** Accessible status text announced while the grid is on screen. */
  label?: string;
}

export function PulseGrid({
  token = "--wisp",
  cols = 5,
  rows = 5,
  duration = 1.4,
  label = "Loading",
  className,
  style,
  ...props
}: PulseGridProps) {
  // A cell's place in the diagonal wave is its Manhattan distance from the
  // corner; the delay is that distance times a fixed step, so the light reads
  // as a front sweeping across the grid rather than cells firing at random.
  const cells = Array.from({ length: cols * rows }, (_, i) => Math.floor(i / cols) + (i % cols));

  return (
    <div
      className={cx("wisp-boot", className)}
      role="status"
      aria-label={label}
      style={
        {
          "--wisp-boot-cols": cols,
          "--wisp-boot-ink": `var(${token})`,
          "--wisp-boot-duration": `${duration}s`,
          ...style,
        } as React.CSSProperties
      }
      {...props}
    >
      {cells.map((distance, i) => (
        <span
          key={i}
          aria-hidden
          style={{ "--wisp-boot-delay": `${(distance * 0.09).toFixed(2)}s` } as React.CSSProperties}
        />
      ))}
    </div>
  );
}

Certified against the contract