ProductBrand
Sign inJoin us
Foundations
  • Introduction
Components
  • Accordion
  • Alert Dialog
  • Avatar
  • Badge
  • Button
  • Calendar
  • Card
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Context Menu
  • Date Picker
  • Diamond Grid
  • Diamond Loader
  • Dialog
  • Drawer
  • Dropdown Menu
  • Input
  • Kbd
  • Popover
  • Progress Bar
  • Radio Group
  • Scroll Area
  • Select
  • Separator
  • Skeleton
  • Slider
  • Switch
  • Tabs
  • Textarea
  • Toast
  • Tooltip

Diamond Grid

Rogo's diamond matrix, animated one on/off frame at a time.

Examples

3, 4 and 5 columns

Custom animations

Overview

DiamondGrid draws the Rogo Notes waveform matrix: a square of diamonds, each fully lit or fully resting. It is the renderer under every diamond animation, including DiamondLoader. An animation is plain data, a grid size, a list of frames and how long each one holds, so a new motion needs no new component.

Lit cells take the text colour and resting cells a 20% tint of it. Set --diamond-grid-lit and --diamond-grid-unlit to pick both. The grid animates opacity in CSS on the compositor, so React does no work after the first render. Under reduced motion it holds its first frame.

Pick the grid for the display size. The grid lays out whole-pixel cells and gaps for size, about four gaps to a cell, so every diamond sits on the pixel grid and renders the same. Fewer columns mean larger diamonds, which is why a 3 × 3 grid stays legible at 12px where a 5 × 5 one turns to mush.

Usage

tsx
import { DiamondGrid } from "@rogo-technologies/ui/diamond-grid";
import { diamondGridFrames } from "@rogo-technologies/ui/diamond-grid-frames";

const SWEEP = {
  columns: 5,
  frames: diamondGridFrames(5, 5, (_row, column, step) => column === step),
  frameMs: 280,
};

<DiamondGrid animation={SWEEP} size={20} className="text-brand-primary" />;

Authoring an animation

diamondGridFrames(columns, steps, isLit), from @rogo-technologies/ui/diamond-grid-frames, builds one frame per step, lighting each cell where isLit returns true. Write frames out by hand when the motion has no rule: columns² values, row by row from the top, with 1 for lit.

Keep animations at module scope. The grid compiles each animation object once and reuses it, and cells that share an on/off track share one @keyframes rule across every grid on the page.

What to change and what to leave

  • Change freely: frames, frameMs, colours through className or the two CSS variables.
  • Leave alone: the whole-pixel geometry in geometryFor, and the opacity overlay in diamond-grid.css. Both are what keep the cells crisp and the animation off the main thread.

API

DiamondGrid

PropTypeDefaultDescription
animationDiamondGridAnimationRequiredThe frames to play. One frame draws a still grid.
sizenumber16Side of the square in pixels.
classNamestring-Additional CSS classes. Set the colour here.

Other span props pass through. The cells are aria-hidden, so give the grid a role and label when it carries meaning. For a loading state, use DiamondLoader, which does.

DiamondGridAnimation

FieldTypeDescription
columns3 | 4 | 5Cells along one side.
framesreadonly DiamondGridFrame[]Played in order and looped.
frameMsnumberHow long each frame holds, in milliseconds.
PreviousDate Picker
NextDiamond Loader
Made in NYC© 2026 Rogo Technologies Inc.

Design at Rogo

We’re redesigning an entire industry. Come design it with us.

See open roles

Design at Rogo

  • How we workThe mission of design at Rogo, and the open roles
  • About RogoThe company and the product