Meter
LED VU meter with zones and peak hold.
Installation
npx shadcn@latest add https://neonkit.heyaadi.com/r/meter.jsonUsage
import { Meter } from "@/components/ui/meter"
<Meter label="L" value={0.72} />Examples
Microphone check
Drive it from a real input: the example reads microphone loudness with Web Audio after you click.
Not just audio
Any 0 to 1 level works. A longer peakHold keeps the recent high visible between updates.
Zones and colors
Zones without a color use the meter's neon color, so color restyles the safe range. Pass your own bands for anything else.
API reference
Meter
Renders a div with role="meter" and accepts its attributes; the ref points at it.
| Prop | Type | Default |
|---|---|---|
value | numberLevel from 0 to 1. Out-of-range values are clamped. | None |
peak | booleantrue holds the highest recent segment, then lets it fall. A number (0 to 1) places the peak marker yourself. false hides it. | true |
peakHold | numberMilliseconds the automatic peak lingers before falling, one segment every 40ms. | 900 |
segments | numberNumber of LED segments. | 24 |
orientation | "horizontal"Vertical meters fill from the bottom. | "horizontal" |
zones | MeterZone[]Color bands from low to high. Each segment takes the last zone that starts at or below it. | neon → amber 72% → red 90% |
size | "sm"Segment thickness and the default length (144, 208 or 272px). Override the length with a w-* or h-* class. | "md" |
label | ReactNodeShort caption at the start of the meter. Also names it for screen readers. | None |
color | NeonColorColor of zones without their own. Falls back to --neon-accent, then cyan. | inherited |
MeterZone
| Prop | Type | Default |
|---|---|---|
from | numberWhere the zone starts, 0 to 1. | None |
color | NeonColorPalette name or hex. Leave it out to use the meter's neon color. | None |
Accessibility
- role="meter" reports the level as aria-valuenow from 0 to 100 with a percentage in aria-valuetext. Pass aria-valuetext to read something else, such as decibels.
- Without a label, pass aria-label or aria-labelledby.
- Values can change every frame: segments are plain spans, and the falling peak runs on its own clock and writes to the DOM, so it never re-renders the meter.
- With reduced motion, segments switch without the decay and the peak drops straight to the level once its hold ends.