Pixel wave
A 3x3 pixel loader whose cells fade on staggered delays, so a wavefront sweeps across the grid.
Behaviour
- Cells are currentColor, so they follow the text colour and the theme.
- Nine cells share one opacity keyframe on staggered delays, so a wavefront sweeps out from the left-middle cell; the fade outlasts a step, so two fronts are in flight.
- Opacity only, no JavaScript per frame. It pauses while off screen.
- Decorative and hidden from screen readers, unless you pass aria-label or aria-labelledby (then it is an img). Put role="status" and the label text on the row around it.
- Inline in running text it sits centred on the line (vertical-align: middle).
- Reduced motion: the wave runs at half speed with a smaller opacity swing.
Props
| Prop | Type | Description |
|---|---|---|
| size | numberdefault 4 | Side of one cell, in px. |
| gap | numberdefault 1 | Space between cells, in px. Whole pixels keep the gaps even on 1x screens. |
| duration | numberdefault 0.65 | Seconds for one cell to fade up and back. |
| stagger | numberdefault 0.09 | Seconds between one diagonal of cells and the next. |
| className | string | Merged onto the root; set the colour (text-*) here. |
Installation
npx shadcn@latest add https://purrfectui.com/r/pixel-wave.jsonHow to use
import { PixelWave } from "@/components/ui/pixel-wave";
<div role="status" className="flex items-center gap-2.5">
<PixelWave className="text-foreground" />
Agent is thinking
</div>
<PixelWave size={6} gap={2} className="text-primary" aria-label="Loading" />Source code
Loading…
License
MIT. Copy it into your project and change it as you like.