Primitives
Meter
A gauge that shows a scalar value within a known range, bucketed into quality bands.
The gauge reflects data-value against data-min / data-max and reports data-quality, so one rule colours the optimum, suboptimum and critical bands.
Mirrors the HTML5 <meter> element: a measurement (battery, disk space, score, queue depth), not progress on a task. Use Progress for the latter.
When to choose
- Meter:
role="meter", a measurement within a known range, bucketed into quality bands bylow/high/optimum. Always determinate, since a meter has no unknown state. - Progress:
role="progressbar", for a task moving toward completion, including the indeterminate case (valueofnull). Choose it whenever the number is going somewhere. - Slider: when the number is one the user sets rather than one they read.
Anatomy
<div forMeter [value]="diskUsed()" [min]="0" [max]="100" [low]="20" [high]="80" [optimum]="40">
<div forMeterIndicator></div>
</div>
Examples
Custom value label
getValueLabel receives the clamped value, min and max and returns aria-valuetext, so AT announces 'Disk: 200 GB used · 312 GB free' instead of the bare number.
API
ForMeter
| Property | Type | Description |
|---|---|---|
value | input | Current measurement (one-way; display-only). Clamped to [min, max] for ARIA / data-* output; the input retains the raw value.Default: 0 |
min | input | Lower bound. Default: 0 |
max | input | Upper bound. Default: 100 |
low | input | Lower boundary of the "comfortable" range. Default: null (= min) |
high | input | Upper boundary of the "comfortable" range. Default: null (= max) |
optimum | input | Ideal point. Drives the quality classification. Default: null (= midpoint) |
getValueLabel | input | Override for aria-valuetext.Default: — |
ariaLabel | input | Accessible name for the meter. Prefer a visible label referenced via aria-labelledby when one exists.Default: null |
| Data attribute | Values | |
|---|---|---|
data-quality | optimum | sub-optimum | even-less-good | |
data-value | current value, clamped to [min, max] | |
data-min | lower bound | |
data-max | upper bound | |
data-percentage | value as a number in 0–100 |
ForMeterIndicator
Visual fill paired with [forMeter]. Mirrors the root's data-* reflections and exposes the --for-meter-percentage custom property so the consumer can drive width / transform from CSS.
| Data attribute | Values | |
|---|---|---|
data-quality | optimum | sub-optimum | even-less-good | |
data-value | current value, clamped to [min, max] | |
data-min | lower bound | |
data-max | upper bound | |
data-percentage | value as a number in 0–100 |
Quality algorithm
The data-quality reflection follows the HTML5 spec:
| Optimum sits in | value in | Quality | |
|---|---|---|---|
| middle | [low, high] | optimum | |
| middle | outside [low, high] | sub-optimum | |
below low | below low | optimum | |
below low | [low, high] | sub-optimum | |
below low | above high | even-less-good | |
above high | above high | optimum | |
above high | [low, high] | sub-optimum | |
above high | below low | even-less-good |
Accessibility
Implements the WAI-ARIA Meter pattern.
role="meter"announces the current value as a fraction of the range. Pair with a visible label andaria-labelledby(or setariaLabel) for context, as in "Disk usage 72 of 100".- Inverted bounds are sanitized. If
maxis passed belowmin, the reflected range is collapsed to a coherent one (min <= max) soaria-valuemin/aria-valuemaxnever emit invalid ARIA. The rawmin/maxinputs read back unchanged. - Always determinate. Unlike
<progress>, a meter must always have a known value. There is no indeterminate mode in HTML5 / ARIA. - Don't use Meter as Progress. Screen readers announce the two roles differently (and assistive guidance differs); pick the right primitive for the meaning.
- Quality is for CSS only.
data-qualityis a styling hook; assistive tech readsaria-valuenow/aria-valuetext, not the quality bucket.
Styling
forty-cdk ships no styles: put your own class on each piece and key your CSS off the data-* attributes listed under API, not off the for* selectors (Styling forty-cdk explains why).
CSS custom properties
| Property | Meaning | |
|---|---|---|
--for-meter-percentage | value as a CSS percentage of [min, max] (0%–100%), set on [forMeterIndicator]. Drive width / transform from it. |
.indicator {
width: var(--for-meter-percentage, 0%);
}
.indicator[data-quality='even-less-good'] {
background: #dc2626;
}
Wrapping in a design system
Subclass the root and re-provide FOR_METER_CONTEXT with useExisting pointing at the subclass, since Angular does not inherit a directive's providers; Wrapping non-form roots walks the pattern.