Meter
Single or stacked progress with semantic segment fills and hover, keyboard and tap breakdowns.
When to use
- Known progress against a positive maximum.
- Delivery states with fixed colors assigned by meaning.
- Progress toward a goal that can be exceeded, with reference ticks.
Consider an alternative
- Unknown scope — show No scope yet.
- Indeterminate loading — use Spinner.
- Compact record property — use ProgressPill.
Import
import { Meter } from '@revido-llc/kit';Keyboard interaction
- Tab — reveal the full breakdown
- Escape — dismiss the tooltip
- Touch — tap a segment to toggle its breakdown
Props
Props documented by the Kit. Refer to the TypeScript types for the complete interface, including inherited props.
Examples
Single and stacked
<Meter label="Upload" value={65} valueText="13 of 20 files" />
<Meter label="Features" value={6} max={26} segments={[
{ id: "deployed", label: "Deployed", value: 4, tone: "success" },
{ id: "claimed", label: "Claimed", value: 2, tone: "warning" },
{ id: "in-progress", label: "In progress", value: 15, tone: "info" },
]} showLegend={false} />With legend
A legend with token swatches under the track. valueFormat (here euros) formats every number; build it from the Kit locale inside a component, e.g. `const euros = useAmountFormatter({ format: { style: "currency", currency: "EUR", maximumFractionDigits: 0 } })`.
<Meter label="Delivery" value={4} max={10} segments={[{ id: "done", label: "Deployed", value: 4, tone: "success" }]} showLegend details="Verified delivery" />
// euros is a formatter in the Kit locale; create it inside your component:
// const euros = useAmountFormatter({ format: { style: "currency", currency: "EUR", maximumFractionDigits: 0 } });
<Meter label="Balance" value={1200} max={2000} valueFormat={euros} valueText={`${euros(1200)} of ${euros(2000)}`}
segments={[{ id: "paid", label: "Paid", value: 1200, tone: "success" }, { id: "due", label: "Due", value: 450, tone: "warning" }]} />Target and markers
Progress toward a goal line with ticks beyond it. Without max, the scale extends to the furthest mark; percentages are measured against the target.
<Meter label="Monthly goal" value={92} target={{ value: 110, label: "Target" }}
markers={[{ value: 130, label: "Milestone 1" }, { value: 150, label: "Milestone 2" }]}
segments={[{ id: "done", label: "Done", value: 92, tone: "primary" },
{ id: "planned", label: "Planned", value: 24, tone: "primary", variant: "projected" }]}
valueText="92 of 110 · 18 to go" />Over target
Values may pass the target; the summary can exceed 100%. An explicit max still rejects overflow.
<Meter label="Monthly goal" value={138} target={{ value: 110, label: "Target" }}
markers={[{ value: 130, label: "Milestone 1" }, { value: 150, label: "Milestone 2" }]} showMarkLabels />Sizes
<Meter label="Small" value={40} size="sm" />
<Meter label="Medium" value={40} size="md" />Empty
<Meter label="Upload" value={0} max={20} valueText="0 of 20 files" />Overflow guard
Values above max and overflowing segment totals are rejected with RangeError; validate data before rendering.
<Meter label="Complete" value={100} max={100} />