Skip to content
Sign in
EffectsBayer loaderMenu

Bayer loaderPro

Cells fade in Bayer matrix order, so the loop reads as an ordered dither filling in and emptying.

Pro4 x 4 and 8 x 8 matrices, as pixels and as dots.

Installation

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

Usage

tsx
import { BayerLoader } from "@/components/ui/chatcn/pro/bayer-loader"

<BayerLoader matrix={8} size="lg" />

It pairs with the dither effects: in an image slot it reads as the picture about to be dithered in.

Examples

States

ProA status row, an image slot, tones, sizes, paused and the reduced motion frame.

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}

Props

PropTypeNotes
matrix4 | 816 or 64 steps. Default 4
shape"pixel" | "dot"A solid block of square cells, or round cells with gaps
size"xs" | "sm" | "md" | "lg" | "xl" | number12, 16, 24, 40 or 72 px
speednumberDefault 1, a 2.4 s loop
paused, stillbooleanFreeze, or draw the reduced motion frame
labelstringDefault "Loading"

Keyboard

Not interactive.

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 turns on at its Bayer threshold and stays on for half the loop, so the block fills in dither order, holds full for a beat, then empties in the same order. The still frame is the matrix at half: a 50% checker dither.
  • 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.