Meter

Displays a numeric value within a known range, such as disk usage or battery level.

Loading...

Anatomy

<Meter.Root>
  <Meter.Label />
  <Meter.ValueText />
  <Meter.Track>
    <Meter.Indicator />
  </Meter.Track>
</Meter.Root>

Meter or Progress?

A meter shows a measurement that stays within a range: storage used, battery remaining, a password's strength. A progress bar shows how far a task has come and finishes when the task does. Use Progress for loading and uploads, and Meter for everything that is a reading rather than a countdown to done.

Examples

Basic

Pass a defaultValue between min and max (0 and 100 by default). The value is formatted as a percentage.

Value State

low, high, and optimum split the range into regions, the same way the HTML <meter> element does. The root, track, and indicator expose the result as data-state: optimal, suboptimal, or least-optimal.

Put optimum below low when lower is better, as with server load, and above high when higher is better, as with battery charge. The regions are exclusive at the optimal end, so with high={80} a value of exactly 80 is still suboptimal.

Format Options

formatOptions goes to Intl.NumberFormat. Any style other than percent formats the value itself rather than its percentage, which suits currency and units.

Value Text

Use the value translation to describe the value in words. It sets both the rendered ValueText and the aria-valuetext that screen readers announce.

Min and Max

Set min and max for ranges that don't start at zero.

Vertical

Set orientation="vertical" to fill the indicator from the bottom. The indicator's height is set instead of its width.

Battery

A meter without a visible label needs an aria-label. Set optimum above high so a full battery reads as optimal and an almost empty one as least optimal.

Password Strength

A meter is a good fit for a password strength score. Map each score to a word with the value translation and let data-state color the bar.

Context

Use Context to read valueState and render content that depends on it.

Root Provider

Use the useMeter hook with RootProvider to read the value and update it from outside the component.

Guides

Styling

The indicator's width (or height when vertical) is set inline from the value, so the track only needs a size and overflow: hidden. The root also exposes the fill as the --percent CSS variable.

[data-meter-indicator][data-state='optimal'] {
  background: green;
}

[data-meter-indicator][data-state='suboptimal'] {
  background: orange;
}

[data-meter-indicator][data-state='least-optimal'] {
  background: red;
}

Accessibility

The root has role="meter" with aria-valuenow, aria-valuemin, aria-valuemax, and aria-valuetext set from the value and its formatting. Label names the meter; without one, pass an aria-label to the root. ValueText is hidden from assistive technology, because aria-valuetext already announces the value.

API Reference

Props

Root

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
defaultValue
number

The initial value of the meter when rendered. Use when you don't need to control the value of the meter.

formatOptions{ style: 'percent' }
NumberFormatOptions

The options to use for formatting the value.

high
number

The lower numeric bound of the high end of the measured range. Defaults to `max`.

id
string

The unique identifier of the machine.

ids
Partial<{ label: string }>

The ids of the elements in the meter. Useful when the label lives outside the machine and you need to control `aria-labelledby`.

locale
string

The locale to use for formatting the value.

low
number

The upper numeric bound of the low end of the measured range. Defaults to `min`.

max100
number

The maximum allowed value of the meter.

min0
number

The minimum allowed value of the meter.

onValueChange
(details: ValueChangeDetails) => void

Callback fired when the value changes.

optimum
number

The optimal numeric value. Combined with `low` and `high`, this decides which region is preferred (HTML `<meter>` algorithm). Defaults to the midpoint of `min` and `max`.

orientation'horizontal'
'horizontal' | 'vertical'

The orientation of the element.

render
ReactElement<unknown, string | JSXElementConstructor<any>> | RenderFn<EmptyState>

Render the part as a custom element, combining their props and behavior. Pass an element to have the part's props merged into it, or a function to control the merge yourself and read the part's state.

translations
IntlTranslations

The localized messages to use.

value
number

The controlled value of the meter.

AttributeDescription
[data-meter-root]<uid>
[data-value]The value of the item
[data-state]"optimal" | "suboptimal" | "least-optimal"
[data-orientation]The orientation of the meter
CSS VariableDescription
--percentThe percent value for the Root

Indicator

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
render
ReactElement<unknown, string | JSXElementConstructor<any>> | RenderFn<EmptyState>

Render the part as a custom element, combining their props and behavior. Pass an element to have the part's props merged into it, or a function to control the merge yourself and read the part's state.

AttributeDescription
[data-meter-indicator]<uid>
[data-orientation]The orientation of the indicator
[data-state]"optimal" | "suboptimal" | "least-optimal"

Label

Renders a <span> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
render
ReactElement<unknown, string | JSXElementConstructor<any>> | RenderFn<EmptyState>

Render the part as a custom element, combining their props and behavior. Pass an element to have the part's props merged into it, or a function to control the merge yourself and read the part's state.

AttributeDescription
[data-meter-label]<uid>
[data-orientation]The orientation of the label

RootProvider

Renders a <div> element.

PropDefaultType
value
UseMeterReturn

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
render
ReactElement<unknown, string | JSXElementConstructor<any>> | RenderFn<EmptyState>

Render the part as a custom element, combining their props and behavior. Pass an element to have the part's props merged into it, or a function to control the merge yourself and read the part's state.

Track

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
render
ReactElement<unknown, string | JSXElementConstructor<any>> | RenderFn<EmptyState>

Render the part as a custom element, combining their props and behavior. Pass an element to have the part's props merged into it, or a function to control the merge yourself and read the part's state.

AttributeDescription
[data-meter-track]<uid>
[data-orientation]The orientation of the track
[data-state]"optimal" | "suboptimal" | "least-optimal"

ValueText

Renders a <span> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
render
ReactElement<unknown, string | JSXElementConstructor<any>> | RenderFn<EmptyState>

Render the part as a custom element, combining their props and behavior. Pass an element to have the part's props merged into it, or a function to control the merge yourself and read the part's state.