Gauge
A health bar for React: a reading on a slanted well that leaves a trail when it drops, so the size of a hit stays readable.
Install
# once per project: where @zeroui items come frompnpm dlx shadcn@latest registry add @zeroui=https://zeroui.catforest.dev/r/{name}.jsonpnpm dlx shadcn@latest add @zeroui/gaugeExamples
A hit and a repair
import { useState } from "react";import { Button } from "@/components/zero/button";import { Gauge, GaugeLabel, GaugeValue } from "@/components/zero/gauge";export default function GaugeHit() { const [hull, setHull] = useState(84); return ( <div className="grid w-full max-w-md gap-5"> <Gauge value={hull} max={120} low={0.25}> <GaugeLabel>Hull</GaugeLabel> <GaugeValue /> </Gauge> <div className="flex flex-wrap gap-3"> <Button variant="danger" size="sm" onClick={() => setHull((h) => Math.max(0, h - 26))} > Take a hit </Button> <Button variant="secondary" size="sm" onClick={() => setHull((h) => Math.min(120, h + 30))} > Patch up </Button> </div> </div> );}Segments and tones
import { Gauge, GaugeLabel, GaugeValue } from "@/components/zero/gauge";export default function GaugeKinds() { return ( <div className="grid w-full max-w-md gap-6"> <Gauge value={68} segments={5} tone="rare"> <GaugeLabel>Shield</GaugeLabel> <GaugeValue /> </Gauge> <Gauge value={41} max={60} tone="legendary"> <GaugeLabel>Fuel</GaugeLabel> <GaugeValue>{(_, value) => `${value} L`}</GaugeValue> </Gauge> <Gauge value={7} max={10} segments={10} tone="epic"> <GaugeLabel>Signal</GaugeLabel> <GaugeValue /> </Gauge> </div> );}Behaviour
When the value drops, the fill falls at once and a pale trail stays where it was, waits (--zero-dur-hold) and catches up. When it rises, a faint trail runs ahead and the fill climbs into it. At or under low (a share of the whole) the fill turns red and breathes. Under reduced motion the trail does not wait and nothing breathes.
segments splits the well into slanted cells that fill in turn, for shields or charges. tone colours the fill: the accent, danger, or a rarity tier. It is a Base UI Meter: screen readers hear the value and its range, named by GaugeLabel.
Props
Gauge
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | — | The reading. |
| min / max | number | 0 / 100 | Its range. |
| tone | "accent" | "danger" | "uncommon" | "rare" | "epic" | "legendary" | "accent" | The fill's colour. |
| segments | number | — | Splits the well into this many cells. |
| low | number | — | A share of the whole (0–1); at or under it the fill turns red and breathes. |
Also takes every prop of Base UI's Meter.Root.
GaugeValue
| Prop | Type | Default | Description |
|---|---|---|---|
| children | (formatted, value) => ReactNode | "value / max" | Writes the reading your way. |
Also takes every prop of Base UI's Meter.Value.