Skip to content
Sign in
EffectsPixel grid loaderMenu

Pixel grid loaderPro

A grid of rounded squares lighting in named patterns. CSS only, themed by text color, with a still frame for reduced motion.

ProEight patterns on grids from 3 to 8 cells, large and at reading size.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/pixel-grid-loader

Usage

tsx
import { PixelGridLoader } from "@/components/ui/chatcn/pro/pixel-grid-loader"

<PixelGridLoader pattern="spiral" grid={5} size="lg" />

Cells are currentColor, so a text class sets the tone: text-chatcn-accent for the theme accent, text-chatcn-fg-subtle for a quiet one.

Examples

Every pattern

ProSnake, spiral, sweep, diagonal, pulse, rain, scatter and orbit at 40 px.

In context

Inside a button, a status row and an image slot, plus tones, sizes, paused and the reduced motion frame. In a right to left layout the grid mirrors, so sweeps and snakes start on the reading side.

ProIn a button, a status row and an image slot, tones, sizes, paused and the reduced motion frame.

Pending timing

ProNothing for 300 ms, then the loader for at least 400 ms: a fast job never flashes it.

Pending timing

Used as a pending state, a loader never shows in the first 300 ms: the user's own action is the feedback, and most waits end before that. Once shown, it stays at least 400 ms so it never flashes. useDelayedPresence from the free thinking-indicator does both.

tsx
import { useDelayedPresence } from "@/components/ui/chatcn/thinking-indicator"

const shown = useDelayedPresence(isPending)

{shown ? <PixelGridLoader /> : null}

Patterns

PatternHow the light travelsBest grid
snakeRow by row, turning at each end4 to 6
spiralFrom the outer edge to the center5 to 8
sweepA column passing across3 to 5
diagonalA diagonal band from corner to corner4 to 6
pulseSquare rings growing from the center5 or 7
rainEach column drops on its own beat5 to 8
scatterCells twinkle in a fixed random order5 to 8
orbitA ring of cells turning around the center5 to 7

Props

PropTypeNotes
patternLoaderPatternDefault snake
grid3 to 8Cells per side. Default 4
size"xs" | "sm" | "md" | "lg" | "xl" | number14, 18, 24, 40 or 72 px, or any side length. Cells snap to whole pixels
speednumberLoop speed multiplier. Default 1
pausedbooleanFreezes the loop
stillbooleanDraws the reduced motion frame
labelstringAccessible name. Default "Loading"; "" hides it

Keyboard

Not interactive: the loader takes no focus.

Accessibility

  • The loader is role="img" with label as its name, "Loading" by default. Next to a visible label, pass label="" and it hides from assistive tech.
  • Announce the outcome, not the wait: put a polite live region on the result (Done, Failed) instead of on the loader.
  • Under prefers-contrast: more unlit cells get darker; under forced-colors cells draw in CanvasText.

Motion

  • Each cell lights at its place in the pattern and fades over a tail sized for the pattern, so the light reads as a head with a trail. Cells switch on instantly, like an LED, which keeps the motion crisp even at 0.25x.
  • Under reduced motion the loop stops on one deterministic still frame and the whole loader breathes in opacity, 1 to 0.55 over 1.4 s, so it still reads as working without any movement. still draws that frame on demand.
  • paused freezes the loop where it is. Loaders are status, not decoration, so they need no pause button, but you can wire one to paused.
  • Animates only opacity and transform. No JavaScript runs per frame.