Skip to content

Early previewhamur is not on npm yet. The components are being built in the open, follow along on GitHub.

FeedbackReact

Meter

A graphical display of a numeric value within a known range, such as disk usage or a password's strength.

Rendered by React 19.3.1

import * as React from 'react'
import { Meter } from '@hamur/react/meter'

export default function MeterExample() {
  const [value, setValue] = React.useState(24)
  return (
    <div className="stack">
      <Meter.Root className="range" value={value}>
        <div className="range-head">
          <Meter.Label>Storage used</Meter.Label>
          <Meter.Value className="muted" />
        </div>
        <Meter.Track className="range-track">
          <Meter.Indicator className="range-fill" />
        </Meter.Track>
      </Meter.Root>
      <div className="row">
        <button
          type="button"
          className="button"
          onClick={() => setValue((current) => Math.max(0, current - 10))}
        >
          Free 10
        </button>
        <button
          type="button"
          className="button"
          onClick={() => setValue((current) => Math.min(100, current + 10))}
        >
          Use 10
        </button>
      </div>
    </div>
  )
}
186Tests passing in React · 0 failing
3.9 KiBSize
Not measured yetMemory
Not measured yetSpeed
productdevbook and 10 upstream authors8 commits · last

Installation

npm i @hamur/react

Not on npm yet. The package goes out under the chosen name.

Anatomy

Import the component and assemble its parts:

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

Examples

The demo at the top is the one example this component has so far.

API reference

8 props across 5 parts, in React syntax. className, style, render are listed once, under Shared props.

IndicatorMeter.Indicator

Visualizes the position of the value along the range. Renders a <div>.

LabelMeter.Label

An accessible label for the meter. Renders a <span>.

RootMeter.Root

Groups all parts of the meter and provides the value for screen readers. Renders a <div>.

Root props
PropTypeDefault
valuerequiredThe current value.number—
aria-valuetextA string value that provides a user-friendly name for aria-valuenow, the current value of the meter.string—
getAriaValueTextA function that returns a string value that provides a human-readable text alternative for aria-valuenow, the current value of the meter.((formattedValue: string, value: number) => string)—
localeThe locale used by Intl.NumberFormat when formatting the value.Intl.LocalesArgument—
minThe minimum valuenumber0
maxThe maximum valuenumber100
formatOptions to format the value.Intl.NumberFormatOptions—

TrackMeter.Track

Contains the meter indicator and represents the entire range of the meter. Renders a <div>.

ValueMeter.Value

A text element displaying the current value. Renders a <span>.

Value props
PropTypeDefault
children((formattedValue: string, value: number) => React.ReactNode) | null—

Shared props

Every part that renders an element takes these.

Shared props
PropType
classNameCSS class applied to the element, or a function that returns a class based on the component's state.string | ((state: State) => string | undefined)
styleStyle applied to the element, or a function that returns a style object based on the component's state.React.CSSProperties | ((state: State) => React.CSSProperties | undefined)
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State>

Keyboard and accessibility

Keyboard

Meter takes no focus and has no keys of its own.

Accessibility

What the parts set
PartSetsSo that
Rootrole="meter", aria-valuenow, aria-valuemin, aria-valuemaxa screen reader reads the value within its range
Rootaria-valuetext from format, getAriaValueText or aria-valuetextthe value is read as written, such as "75%"
Rootaria-labelledby to Labelthe meter is read with its name
Valuearia-hidden="true"the visible number is not read twice

Focus order

  1. Meter is not focusable; focus passes over it.