Warren UI

MeterCluster

Grid of segmented threshold gauges with zone-tinted cells and ink tick marks.

NODE UTILIZATION · TICK MARKS ON · 20 CELLS
Source
"use client"

import { MeterCluster } from "@/registry/warren/meter-cluster/meter-cluster"

const METERS = [
  { label: "CPU", value: 87, max: 100, unit: "%", warn: 60, crit: 80, sub: "api-prod" },
  { label: "MEM", value: 4.2, max: 8, unit: "GB", warn: 5.6, crit: 7.2 },
  { label: "DISK", value: 91, max: 100, unit: "%", warn: 75, crit: 90, sub: "/var/log" },
  { label: "QUEUE", value: 142, max: 500, warn: 300, crit: 420 },
  { label: "CONN", value: 3100, max: 4000, warn: 3200, crit: 3600 },
  { label: "CACHE", value: 64, max: 100, unit: "%", warn: 85 },
]

export default function MeterClusterDemo() {
  return (
    <div className="flex flex-col gap-3 border-2 border-border bg-panel p-2">
      <span className="font-mono text-[10px] uppercase tracking-wide text-muted-foreground">
        NODE UTILIZATION · TICK MARKS ON · 20 CELLS
      </span>
      <MeterCluster meters={METERS} columns={3} size="sm" segments={20} tickMarks />
    </div>
  )
}

Installation

npx shadcn@latest add https://warren.eduard3v.com/r/meter-cluster.json

Usage

import { MeterCluster } from "@/components/ui/meter-cluster"
<MeterCluster
  meters={[{ label: "CPU", value: 87, max: 100, unit: "%", warn: 60, crit: 80 }]}
  columns={3}
  tickMarks
/>

Encoding

Each meter renders as a caption row — mono uppercase label, mono tabular value + unit — over a strip of discrete square cells filling left-to-right. Fills snap to whole cells: round(value/max · segments), clamped so values past max light every cell.

Cell tint is per-cell, read from the zone the cell's midpoint falls in: primary below warn, warning from warn, danger from crit. The gauge reads like a fuel panel — no arcs, no gradients, no rounded dials. With tickMarks, a 1px ink tick rides each valid threshold edge.

Threshold edges are validated against the scale before rendering: out-of-range edges and an inverted crit (not strictly above warn) are dropped, so zones can never render in the wrong order (thresholds()/cellZones() in gauge.ts).

Sizing & layout

The cluster lays out in a responsive CSS grid: one column by default, columns (2–4) from lg up. size="sm" uses 6px-tall tracks with 12px values, "md" 10px tracks with 14px values; segments sets the cell count per gauge. On the navy band, pass onDark to flip text to the light grade and ticks to light ink.

API Reference

Prop

Type

Prop

Type

On this page