assistant-ui logo/Docs/Components

Dot Matrix

Tiny 5x5 dot-matrix indicator with 20 state-specific blink patterns.

This is a standalone component that does not depend on the assistant-ui runtime. Use it anywhere in your application.

idleidle
loadingloading
thinkingthinking
streamingstreaming
searchingsearching
syncingsyncing
connectingconnecting
waitingwaiting
uploadinguploading
downloadingdownloading
listeninglistening
speakingspeaking
recordingrecording
successsuccess
errorerror
warningwarning
infoinfo
pausedpaused
stoppedstopped
offlineoffline

Installation

npx shadcn@latest add https://r.assistant-ui.com/dot-matrix.json

This adds a /components/assistant-ui/dot-matrix.tsx file to your project, which you can adjust as needed. The component has no dependencies beyond React.

Usage

import { DotMatrix } from "@/components/assistant-ui/dot-matrix";

export function RunIndicator({ isRunning }: { isRunning: boolean }) {
  return <DotMatrix state={isRunning ? "loading" : "success"} />;
}

Dots inherit the surrounding text color, so the matrix renders dark dots on light backgrounds and light dots on dark backgrounds without configuration. Every state is a combination of a dot pattern, a motion, and a color, and switching states cross-fades each dot into its new pattern.

States

StatePattern
idleDim static grid
loadingRandomized twinkle (default)
thinkingDiagonal wave
streamingFalling rain, per-column streaks
searchingHorizontal sweep
syncingRotating sweep around the center
connectingRipple expanding from the center
waitingEllipsis dots blinking in sequence
uploadingWave rising upward
downloadingWave falling downward
listeningSlow equalizer columns
speakingFast equalizer columns
recordingRed center dot breathing
successGreen check glyph, static
errorRed cross glyph, blinking
warningAmber exclamation glyph, slow blink
infoBlue info glyph, static
pausedPause bars glyph, static
stoppedSquare glyph, static
offlineVery dim static grid

The component exports dotMatrixStates (the ordered list above) and the DotMatrixState union type, so UIs can enumerate or map states without duplicating the list. New states are added by extending the STATES record in the component source with a glyph and a per-dot blink function.

Examples

State Lifecycle

Drive the state prop from your run status; the matrix morphs between patterns instead of swapping components.

idleidle

Inline With Text

At the default size-4 the matrix aligns with text like an icon, and the dots adapt to inverted surfaces through currentColor.

loadingGenerating response…
thinkingThinking…
recordingRecording…

Sizes

The matrix is an SVG, so any size utility scales it crisply.

loadingsize-4
loadingsize-6
loadingsize-10
loadingsize-16

How It Works

The grid is a 5x5 SVG of currentColor circles. Blinking is a single CSS keyframe animation whose high/low opacity bounds come from registered per-dot CSS variables; the animation runs in every state (static states collapse the bounds) and the bounds carry a transition, which is what makes state changes cross-fade per dot. The randomized loading rhythm uses deterministic per-dot delays and durations, so server and client render identical markup and no JavaScript runs after render. With prefers-reduced-motion, the dots hold their resting opacity instead of blinking.

The root is a role="status" live region whose text content is the state name (or the label prop), so screen readers announce state changes; the SVG itself is aria-hidden.

API Reference

DotMatrix

DotMatrixProps
state : DotMatrixState = "loading"

One of the 20 built-in states listed above, controlling pattern, motion, and color.

label ?: string

Accessible label announced by screen readers. Defaults to the state name.

className ?: string

Additional CSS classes. Use size utilities to scale and text color utilities to recolor.

Styling

Color follows currentColor, so className="text-blue-500" recolors the whole matrix; the outcome states (success, error, warning, info, recording, and the muted static states) set their own color which a className can override. Dots are targetable via [data-slot="dot-matrix"] and [data-slot="dot-matrix-dot"], and the current state is exposed as data-state on the root.

  • Number Roll - Animated rolling number
  • Badge - Small status and metadata labels
  • Voice - Voice activity visualization