Skip to content
v2.5.0
English
Русский
Documentation

Meter

Meter shows a bounded quantitative value, typically without the temporal progress semantics of a progress bar.
Cloud storage36 of 50 GB
meter.tsx · 11 lines
import { Meter, MeterTrack, Text } from '@vega-ui/react';

<div>
  <div>
    <Text id='preview-meter-label' size={2} fontWeight={500}>Cloud storage</Text>
    <Text size={2}>36 of 50 GB</Text>
  </div>
  <Meter value={36} max={50} valueText='36 GB of 50 GB used' aria-labelledby='preview-meter-label' fullWidth>
    <MeterTrack />
  </Meter>
</div>
Browser support
Widely available
  • Chrome 111
  • Edge 111
  • Firefox 113
  • Safari 15.4
  • Safari on iOS 15.4
Bundle size
Tested in
19 tests

Summary

Meter shows a bounded quantitative value, typically without the temporal progress semantics of a progress bar. It is the descriptive-measurement bar when the UI should read as level, score, capacity, or quality rather than task completion.

Imports

import {
  Meter,
  MeterTrack,
  type MeterProps,
  type MeterSize,
  type MeterVariant,
} from '@vega-ui/react';

Exported Types

  • MeterProps
  • MeterTrackProps
  • MeterSize
  • MeterVariant

Minimal Composition

max defaults to 1, so a fraction like 0.72 needs no max; pass max for any other scale (value={36} max={50}). The meter has no visible label of its own: give it aria-label or aria-labelledby.

minimal-composition.tsx · 9 lines
import { Meter, MeterTrack } from '@vega-ui/react';

export default function MinimalComposition() {
  return (
    <Meter value={0.72} valueText='72%' aria-label='Disk usage' fullWidth>
      <MeterTrack />
    </Meter>
  );
}

Required Parts

  • Meter: root meter surface
  • MeterTrack: visible measured-fill track

Optional Parts

  • No extra public parts beyond root and track

Composition Order

  1. Meter
  2. MeterTrack

Variants

  • Sizes: sm, md, lg
  • Variants: primary, secondary
  • States: neutral, good, warn, bad via thresholds

Edge Cases

  • Meter is for bounded measurement, not async completion.
  • Threshold props like low, high, and optimum can shift the semantic color state.
  • Surrounding copy should explain the measured value and range.
  • If the measurement is actually composed of several meaningful parts, MeterStack is usually clearer than one continuous bar.

Common Mistakes

  • Using Meter for loading or async work.
  • Showing a value without explaining the range or meaning.
  • Ignoring threshold semantics when they matter to interpretation.

Examples

Basic

Basic: storage usage with a visible summary

A meter on a real scale: max is the plan limit, so value is passed in gigabytes, not as a fraction. The visible heading names the meter through aria-labelledby, and valueText repeats the human-readable summary for screen readers instead of a bare number.

storage-usage.tsx · 21 lines
import { Meter, MeterTrack, Text } from '@vega-ui/react';
import { useId } from 'react';

export default function StorageUsage() {
  const labelId = useId();
  const usedGb = 36.2;
  const limitGb = 50;
  const summary = `${usedGb} GB of ${limitGb} GB used`;

  return (
    <div style={{ display: 'grid', gap: 'var(--spacing-3)', width: '100%' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 'var(--spacing-8)' }}>

Controlled/Stateful

Controlled/Stateful: battery level with threshold zones

The parent owns the level and passes it to the meter together with low, high and optimum. The track turns red, amber or green on its own, while the same thresholds drive a text status linked through aria-describedby, so the meaning never relies on color.

battery-level.tsx · 51 lines
import { Button, Meter, MeterTrack, Text } from '@vega-ui/react';
import { useId, useState } from 'react';

export default function BatteryLevel() {
  const labelId = useId();
  const statusId = useId();
  const [level, setLevel] = useState(64);

  let status = 'Battery is fine';
  if (level < 20) {
    status = 'Battery is low — connect the charger';
  } else if (level > 80) {

Form/Integration

Form/Integration: character limit under a textarea

The meter follows the length of a TextArea inside a real form. optimum={0} makes short text the good zone, so the bar turns amber near the limit and red at it; maxLength enforces the hard cap and the remaining count is linked to the field. The submit handler reads the value with FormData, and reset clears the state.

bio-length-meter.tsx · 62 lines
import { Button, HelperText, Label, Meter, MeterTrack, TextArea } from '@vega-ui/react';
import { FormEvent, useId, useState } from 'react';

export default function BioLengthMeter() {
  const fieldId = useId();
  const counterId = useId();
  const limit = 160;
  const [bio, setBio] = useState('Product designer in Lisbon. I write about design systems and accessible forms.');
  const [saved, setSaved] = useState<string | null>(null);

  const left = limit - bio.length;

Layout/Overlay

Layout/Overlay: plan usage card

Several meters in a card, one list item each, every one labelled by its own row heading. Lower is better here (optimum={0}), so a resource close to its limit stands out without extra code.

en-US
ru-RU
ar-EG
he-IL
meter-inside-a-card.tsx · 49 lines
import { Card, Heading, Meter, MeterTrack, Text } from '@vega-ui/react';
import { useId } from 'react';

const usage = [
  { id: 'seats', label: 'Seats', used: 18, limit: 20, unit: 'seats' },
  { id: 'storage', label: 'Storage', used: 412, limit: 500, unit: 'GB' },
  { id: 'minutes', label: 'Build minutes', used: 1240, limit: 3000, unit: 'min' },
];

export const locales = ['en-US', 'ru-RU', 'ar-EG', 'he-IL'];

export default function MeterInsideACard({ locale = 'en-US' }: { locale?: string }) {

Error

Error: quota exceeded

The meter clamps the fill at max, so an overflow cannot be seen in the bar alone. When usage passes the limit, the example renders an error HelperText, links it to the meter with aria-describedby and says exactly how far over the limit the account is.

en-US
ru-RU
ar-EG
he-IL
quota-exceeded.tsx · 52 lines
import { Button, HelperText, Meter, MeterTrack, Text } from '@vega-ui/react';
import { useId, useState } from 'react';

export const locales = ['en-US', 'ru-RU', 'ar-EG', 'he-IL'];

export default function QuotaExceeded({ locale = 'en-US' }: { locale?: string }) {
  const labelId = useId();
  const errorId = useId();
  const limit = 10000;
  const [requests, setRequests] = useState(8700);

  const format = new Intl.NumberFormat(locale);

Edge

Edge: non-zero minimum and an optimum in the middle

A temperature scale from 10 to 35 °C with the comfortable zone in the middle: values below low or above high are both bad. min shifts the start of the track, and the verdict is printed next to each value.

room-temperature.tsx · 48 lines
import { Meter, MeterTrack, Text } from '@vega-ui/react';
import { useId } from 'react';

const rooms = [
  { id: 'living', name: 'Living room', celsius: 21.5 },
  { id: 'bedroom', name: 'Bedroom', celsius: 18.2 },
  { id: 'server', name: 'Server closet', celsius: 29.8 },
];

export default function RoomTemperature() {
  const prefix = useId();

Anatomy

Overview

Meter is a compound component because the root meter role and the visible track share one bounded measurement model.

Required Parts

Meter

Required. Owns range values, thresholds, variant, size, and accessibility attributes.

MeterTrack

Required. Renders the visible measured-fill amount.

Optional Parts

Meter does not expose additional public parts beyond the root and track.

Composition Order

  1. Meter
  2. MeterTrack

Valid Composition Patterns

minimal-composition.tsx · 9 lines
import { Meter, MeterTrack } from '@vega-ui/react';

export default function MinimalComposition() {
  return (
    <Meter value={0.72} valueText='72%' aria-label='Disk usage' fullWidth>
      <MeterTrack />
    </Meter>
  );
}

Invalid Composition Patterns

Meter used for ongoing async completion

If the value represents temporal completion, Progress is the better pattern.

Threshold-based colors without explaining what the range means

Users may see semantic color shifts but not understand the measurement.