Meter
A quantity within a known range, such as wallet usage, storage or a limit, with a label, a readout and a slim track.
Preview
Installation
pnpm add @syntara/react @syntara/tokensimport { Meter } from '@syntara/react';Usage
import { Meter } from '@syntara/react';
export function WalletUsage() {
return <Meter label="Consultations" value={7400} maxValue={18000} valueLabel="₹7,400 used" caption="of ₹18,000" />;
}Examples
Card variant
variant="card": the usage row inside a card, in an inset panel.
In-clinic consultation
GP, specialist or a second opinion
Tones
brand (default), accent, warning and neutral fills.
Formats
Percent by default, currency via formatOptions, and an aria-label-only meter.
Accessibility
No keyboard interaction of its own.
- Rendered by React Aria as role="meter progressbar" with aria-valuenow/min/max and aria-valuetext; it is read-only and takes no focus.
- The caption is linked with aria-describedby (merged with any you pass), so "of ₹18,000" is read after the value.
- Fill contrast (WCAG 1.4.11): fills use text roles, not action.primary.bg. action.primary.bg fell to 2.64:1 on surface.sunken in Care dark and below 3:1 in 709 of 2,000 fuzz schemes; text.brand stays ≥ 4.46:1 on sunken across the same fuzz and is guaranteed 4.5:1 on surface.default (the card variant's track).
- The fill slides in from the start edge with easing-out only when reduced motion is off; otherwise it is simply drawn at its width.
- Value text takes the locale's direction (formatted) or its own (authored strings), so readouts don't reorder in RTL.
Guidelines
Do
- Use Meter for amounts against a limit (money used, seats taken, storage).
- Say what the number means in valueLabel ("₹7,400 used"), and give the limit in caption.
- Use variant="card" for the usage row at the bottom of a benefit or plan card.
Don’t
- Don't use Meter for task progress; use ProgressBar.
- Don't rely on tone alone to signal "nearly used up"; say it in the caption.
- Don't put more than a few meters in one card: summarise instead.
API reference
Meter
labelReactNodeVisible label. Without one, pass aria-label or aria-labelledby (required by the types).
valuenumberCurrent value, clamped to minValue–maxValue.
Default
0minValuenumberStart of the range.
Default
0maxValuenumberEnd of the range.
Default
100valueLabelstringThe value as shown and announced (aria-valuetext), e.g. "₹7,400 used".
formatOptionsIntl.NumberFormatOptionsHow the value is formatted when there's no valueLabel, in the React Aria locale.
Default
{ style: 'percent' }showValuebooleanShows the value in the label row.
Default
truecaptionReactNodeQuiet context after the value: the limit or the pool ("of ₹18,000", "from ₹18K wallet"). Announced as the meter's description.
tonebranddefaultaccentneutralinfosuccesswarningdanger
Fill colour: text.brand, accent.text, text.subtle or the feedback fg role. Every tone reaches 3:1 against the track.
variantdefaultdefaultcard
card sets the meter in an inset surface.sunken panel: the value leads, the caption answers from the far end, the label (if any) sits above in text.subtle.
Tokens
The semantic tokens this component reads, grouped by what they control. Swatches show this site’s theme; change a tenant’s brand and the component follows with no code change.
- Colour8
text.brandaccent.texttext.subtlefeedback.*.fgsurface.sunkensurface.defaultborder.subtletext.default- Type1
font-size.xs–md- Space and size2
card-insetspace.1–4- Shape3
radius.pillradius.containerradius.badge- Depth1
hairline- Motion3
motion.duration-slowmotion.duration-fastmotion.easing-out