Noctis

Meter

Show a static measurement within a known range. A filled bar reports a settled reading — disk usage, battery, a score, remaining quota — with an optional label and a value that formats for the reader's locale. Declare thresholds and the tone derives itself.

Basic

Give Meter.Root a value and an aria-label, then compose a Meter.Track holding a Meter.Indicator. The range defaults to 0100. A Meter.Label and Meter.Value caption the reading, and labels="top" lays them out in a header row above the track — no wrapper needed. The fill sizes itself to the value.

Storage used
x

Thresholds

A meter is a reading, so its colour signals status, not progress. Declare low, high, and optimum — exactly the HTML <meter> model — and the fill tone is derived: success in the healthy zone, warning as it tightens, danger once it's critical. The position of optimum decides which direction is good, so one declaration covers a quota (high is bad), a battery (high is good), or a temperature (low is good). No hand-written traffic-light logic, and because the breakpoints live in one place the bar and any quota note can't disagree. An explicit tone always overrides the derived one.

When a tone is in play, the meter also defaults a localized aria-valuetext (e.g. "96% — critical") so assistive tech hears the status the colour shows, not just a number.

Documents
x
Photos
x
System
x

Battery

The canonical accessible meter. Here a high charge is best, so optimum sits at the top of the range and the bar turns danger as it drains below low. A custom getAriaValueText gives the APG battery readout — a screen reader hears the time remaining — while the Meter.Value render child shows a qualitative reading instead of a bare number. labels="side" flanks the track on a single line.

Battery
x

Custom range

Set min and max for any scale — a temperature, a price band, a rating — and the fill maps the value across it. Thresholds work in the custom range too: this CPU gauge is best when cool (optimum at the floor), so warm derives warning and hot derives danger, and the value reads in its own units.

CPU temperature
x

Sizes

Two track thicknesses — md (the default, a thin rail matching the Progress twin) and sm, thinner still — sharing the same ends and rhythm. Both follow the radius knob, so a RadiusScope retunes them. For an arbitrary height, pass thickness (a number is px, a string is any CSS length).

Usage
x
Usage
x

Labels

labels="top" (the default) stacks the caption row above the track; labels="side" flanks the track on one line. The root owns the layout — the same Meter.Label + Meter.Value + Meter.Track compose either way, and a meter with no caption collapses to just the bar.

Memory
x
Memory
x

Usage card

Composed with a Surface: a billing-style usage card where the derived tone drives the bar and a status line echoes it. One set of thresholds, so the warning note fires at the same point the bar turns.

Storage
x

Nearly full — upgrade to add space.

Anatomy

Compose a meter from its parts. Meter.Root owns the value (value, with optional min/max, default 0100) and the shared tone, size, and labels.

  • Meter.Root — the container. Props: value, min/max, low/high/optimum (the threshold model), tone (explicit, overrides the derived one), size (default md), labels (default top), thickness, format (an Intl.NumberFormatOptions), plus the Base UI Meter.Root props (getAriaValueText, aria-valuetext, locale). Give it an aria-label.
  • Meter.Track — the groove the indicator fills against. Holds a single Meter.Indicator.
  • Meter.Indicator — the filled portion, sized to the value; its fill colour follows the resolved tone and eases as the value changes.
  • Meter.Label — the visible caption. Laid out by the root's labels axis.
  • Meter.Value — the formatted value text, localized via the active locale; pass a render child (formattedValue, value) => … for a qualitative reading.

Every part carries a data-slot (meter, meter-track, meter-indicator, meter-label, meter-value) for host-side styling — pair the root slot with the data-tone, data-size, and data-labels axes it stamps. The reading is exposed through the Base UI meter role (aria-valuenow / aria-valuetext) and the fill is RTL-aware.

On surfaces

The same control re-tuned across the elevation scopes — the root canvas, an elevated panel, a menu, and a sunken well. It stays legible on every layer.

root
Documents
x
Photos
x
System
x
elevated
Documents
x
Photos
x
System
x
menu
Documents
x
Photos
x
System
x
sunken
Documents
x
Photos
x
System
x

Design tokens

Generated from the component's declaration — the same graph that mints the CSS, so a variable name or its resolution default can't drift. The track and fill follow the radius knob (--noctis-radius-control) rather than a baked-in pill, so a RadiusScope or the System Controls retune them with every other control. The minted tokens are the public override seam: set one on any ancestor and every meter in that region retunes — e.g. .dashboard { --noctis-meter-track-block-size: 0.625rem; } thickens every bar (or pass thickness per instance). See Customization for the full override ladder and Tokens for the whole graph.

Token

API reference

Generated from the component's types — every prop, type, default, and description comes straight from the source. Each part gets its own table; parts that only forward to Base UI (Track, Indicator, Label, Value) list just the props they pass through. Expand a row for the full type and description.

Meter.Root

Prop

Meter.Track

Prop

Meter.Indicator

Prop

Meter.Label

Prop

Meter.Value

Prop

AttributeDescription
data-slotThe root meter element.
data-tone`neutral` | `success` | `warning` | `danger` — the reading's status tint, stamped on the root.
data-size`sm` | `md` — the track thickness, stamped on the root.
data-labels`top` | `side` — the caption placement relative to the track, stamped on the root.