61 / Agent UI
Matrix
A grid of cells lit from the bottom by a level, which reads as a piece of hardware rather than as a chart.
"use client"
import * as React from "react"
import { Matrix } from "mischief-ui/matrix"
export function MatrixDemo() {
const [level, setLevel] = React.useState(0.3)
React.useEffect(() => {
const timer = setInterval(() => setLevel(0.2 + Math.random() * 0.75), 160)
return () => clearInterval(timer)
}, [])
return <Matrix className="h-32 w-full max-w-md" level={level} columns={28} />
}Installation
Copy the source into your project, or keep it behind a package.
npx shadcn@latest add Tinkerers-Labs/mischief-ui/matriximport { Matrix } from "mischief-ui/matrix"Or paste it in yourself. The source imports the shared cn helper from @/lib/utils, so point that at your own copy.
"use client" import * as React from "react" import { RenderSurface, useThemeColors, type SurfaceColor,} from "@/registry/default/render-surface/render-surface"import { cn } from "@/lib/utils" export type MatrixProps = Omit< React.HTMLAttributes<HTMLDivElement>, "children"Usage
export function Meter() {
return <Matrix className="h-32 w-full" level={level} />
}Why it fills from the floor
Cells light from the bottom up, so height is loudness and the grid reads the way an equaliser does. Scattering lit cells at random across the box would be prettier for a second and unreadable after that.
With nothing to show it keeps a low shimmer along the floor rather than going black, so a quiet microphone is told apart from a dead one. Turn that off with idle when the silence is the message.
API
columnsnumberCells across. Rows follow from the box. Defaults to 24.levelnumberNought to one.idlebooleanKeeps a low shimmer when there is no level. On by default.colorstringA theme token or CSS colour. Defaults to "--primary".gapnumberPixels between cells. Defaults to 2.labelstringNames the canvas when the grid is content rather than decoration.Accessibility
The grid is decoration by default and hidden from assistive technology, because a level meter beside a control that already says what it is doing has nothing to add. Give it a label only where the meter is the only thing carrying the state. It sleeps when scrolled out of view like every surface here, and rebuilds its cells on resize so the grid stays square rather than stretching.