Pho Design System

Meter

Displays a scalar measurement within a known range — disk usage, quota, a score. Built on Base UI Meter. Unlike Progress, a meter is not about a task advancing over time; it’s a static reading at a point in time.

Import

import { Meter } from "@photon-ai/pho-ui/components/meter";

Basic

Set value on Meter.Root (0–100 by default). Compose a header row with Meter.Label and Meter.Value; with no format, the value reads as a percentage of the range.

Storage used
x
<Meter.Root value={72}>
  <div className="flex items-center justify-between">
    <Meter.Label>Storage used</Meter.Label>
    <Meter.Value />
  </div>
  <Meter.Track>
    <Meter.Indicator />
  </Meter.Track>
</Meter.Root>

Range and formatting

Pass min / max to set the real bounds, and format (an Intl.NumberFormatOptions) to render the value in its own units instead of a percentage — bytes, GB, currency, a score out of five.

Disk
x
<Meter.Root
  value={168}
  max={256}
  format={{ style: "unit", unit: "gigabyte", unitDisplay: "short" }}
>
  <div className="flex items-center justify-between">
    <Meter.Label>Disk</Meter.Label>
    <Meter.Value />
  </div>
  <Meter.Track>
    <Meter.Indicator />
  </Meter.Track>
</Meter.Root>

Levels

The value maps to a level, so the fill can carry meaning. Override Meter.Indicator’s fill with a semantic token past a threshold, and use Meter.Value’s render prop for a raw “used / total” reading instead of a percentage.

Team seats
x
Build minutes
x
<Meter.Root value={1880} max={2000}>
  <div className="flex items-center justify-between">
    <Meter.Label>Build minutes</Meter.Label>
    <Meter.Value>{(_, v) => `${v} / 2000`}</Meter.Value>
  </div>
  <Meter.Track>
    <Meter.Indicator className="bg-pho-error-solid" />
  </Meter.Track>
</Meter.Root>

Anatomy

Props

Every part also accepts className and render (Base UI’s prop for swapping the underlying element).

Meter.Root (<div role="meter">)

Meter.Value (<span aria-hidden>)

Meter.Label (<span>), Meter.Track (<div>), Meter.Indicator (<div>) take only the common className / render; the indicator’s inline size is set by Base UI from value.

Accessibility

Best practices