zeroUI

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

terminal
# 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/gauge

Examples

A hit and a repair

Hull
x
gauge-hit.tsx
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

Shield
x
Fuel
x
Signal
x
gauge-kinds.tsx
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

PropTypeDefaultDescription
valuenumber—The reading.
min / maxnumber0 / 100Its range.
tone"accent" | "danger" | "uncommon" | "rare" | "epic" | "legendary""accent"The fill's colour.
segmentsnumber—Splits the well into this many cells.
lownumber—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

PropTypeDefaultDescription
children(formatted, value) => ReactNode"value / max"Writes the reading your way.

Also takes every prop of Base UI's Meter.Value.

GaugeLabel