Level Meter
A peak and RMS level meter with zones, peak hold, a scale, a readout and a clip light.
Installation
$ pnpm dlx shadcn@latest add @audiocn/level-meterUsage
import { LevelMeter } from "@/components/ui/level-meter";<LevelMeter aria-label="Microphone level" peakDb={-12} />With no children, LevelMeter renders one track per channel with a peak bar and a peak-hold tick. Add children to control the anatomy.
Anatomy
<LevelMeter source={analyser.meter}>
<LevelMeterChannels>
<LevelMeterChannel index={0}>
<LevelMeterTrack>
<LevelMeterBar measure="rms" />
<LevelMeterBar measure="peak" />
<LevelMeterHold />
</LevelMeterTrack>
</LevelMeterChannel>
<LevelMeterScale />
</LevelMeterChannels>
<LevelMeterValue />
<LevelMeterClip />
</LevelMeter>Examples
Default
Values
Pass peakDb (and optionally rmsDb) for data that arrives slowly. The meter still moves smoothly between updates.
Vertical
Variants
Peak and RMS
Layer an rms bar over a translucent peak bar for a dual meter.
Ballistics
peak rises in 15 ms and falls steadily; vu is slow and averaged; instant follows the input exactly.
Colors and zones
Override the meter tokens with a class, or pass your own zones.
Build your own visual
Each channel writes its live level to --meter-level (0..1). Anything inside a LevelMeterChannel can use it in CSS.
Microphone
Feeding data
A meter accepts levels three ways. See Feeding data.
// A source: subscribes and paints itself, no React renders.
<LevelMeter source={analyser.meter} />
// Values: for slow data. Ballistics smooth the movement.
<LevelMeter peakDb={-9.1} rmsDb={-18} />
// A handle: for callers that own their own frame loop.
const meter = useRef<LevelMeterActions>(null);
meter.current?.paint({ channels: [{ peakDb: -9.1 }] });
<LevelMeter actionsRef={meter} />Theming
| Token or variable | Where | Default |
|---|---|---|
--meter-ok, --meter-warn, --meter-clip | theme | green, amber, --destructive |
--meter-thickness | root | 0.5rem (sm 0.25rem, lg 0.75rem) |
--meter-gap | root | 0.25rem, between channels |
--meter-level, --meter-rms, --meter-hold | each channel, live | 0..1 |
| Data attribute | On | Meaning |
|---|---|---|
data-orientation, data-variant, data-size | root | Current settings |
data-zone | root, channels | ok, warn or clip |
data-clipping | root | The signal clipped in the last 1.5 s |
data-active | channels | The level is above the bottom of the range |
data-dimmed | root | Inside a muted or silenced channel strip |
data-measure | bars | peak or rms |
Accessibility
- The root has
role="meter"witharia-valuemin,aria-valuemaxandaria-valuenowin dB, andaria-valuetextsuch as "−12.0 dB". These update at most four times a second. - Give every meter a name with
aria-labeloraria-labelledby. - With reduced motion, the meter shows the current level four times a second instead of animating.
API reference
LevelMeter
Prop
Type
LevelMeterChannel
Prop
Type
LevelMeterBar
Prop
Type
LevelMeterScale, LevelMeterValue, LevelMeterClip
These wrap DbScale, DbReadout and ClipIndicator, and take their props. The range, orientation and data come from the meter.