Meter
FreeA measurement within a known range, with thresholds marked on the track and a word for whether it is fine.
pnpm dlx shadcn@latest add https://caliperui.site/r/meter.jsonOld preview builds are removed after 30 days.
When to use #
Use it for
- Storage, quota, battery, a quality score or latency.
- Values with a healthy band and a band to worry about.
Skip it when
- Progress through a task; use progress.
- Usage against a billed limit with segments; use the usage meter.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/meter.json
Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above. It is built from Meter and meterState.
import { useState } from "react" import { Meter } from "@/components/ui/meter" import { Slider } from "@/components/ui/slider" export function MeterDemo() { const [used, setUsed] = useState(71); return ( <div className="grid w-full max-w-lg gap-6"> <Meter label="Storage" value={used} max={100} low={80} high={95} optimum={0} format={(v) => `${v} GB of 100 GB`} words={{ good: "Plenty left", fair: "Filling up", poor: "Almost full" }} description={used >= 95 ? "Uploads stop at 100 GB. Delete old builds or add storage." : "Old preview builds are removed after 30 days."} /> <div className="grid max-w-xs gap-1.5"> <label htmlFor="meter-used" className="text-[13px] text-muted-foreground">Used storage</label> <Slider id="meter-used" min={0} max={100} value={used} onChange={(event) => setUsed(Number(event.target.value))} /> </div> <Meter label="Battery" value={18} low={20} high={50} optimum={100} format={(v) => `${v}%`} words={{ poor: "Charge soon", fair: "Half way", good: "Charged" }} size="sm" /> <div className="grid gap-4 border-t border-border pt-5 sm:grid-cols-3"> <Meter variant="ring" label="CPU" value={34} low={70} high={90} optimum={0} /> <Meter variant="ring" label="Memory" value={82} low={70} high={90} optimum={0} /> <Meter variant="ring" label="p95 latency" value={412} max={500} low={200} high={350} optimum={0} format={(v) => `${v} ms`} words={{ poor: "Slow" }} /> </div> </div> ); }
API reference #
Meter
component
meterState
component
No props of its own; it accepts the native props of its root element.
Accessibility #
It is built on native elements and keeps aria-hidden in step with state.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.