Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelogApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip
ARC UIARC Radiant Components
v4.9DocsComponentsTokensSynthesizer
Getting StartedFrameworksServer RenderingDesign TokensThemingTheme SynthesizerTypographyUtilitiesAll ComponentsAccessibilityBrowser SupportChangelogContributingStatsApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip

Level Meter

Segmented audio level meter with peak-hold. Zone-tinted segments light in proportion to a live value, with a decaying peak line. The live vertical sibling of Meter.

ComponentsLevel Meter
datastatic
<arc-level-meter>

Overview

LevelMeter is built for values that move at signal rate: audio levels first, but equally buffer fill, network throughput, or any telemetry that updates many times a second. It renders a track of discrete segments (twenty by default) that light up in proportion to `value`, each tinted by the zone it occupies: success below the `warn` threshold, warning between `warn` and `clip`, error above `clip`. Lit segments glow; unlit ones show a faint preview of their zone so the scale reads even at silence. Set `segments="0"` for a continuous, unsegmented bar. The value maps linearly between `min` and `max`, which default to 0 and 1. For dB metering set the range directly (`min="-60" max="0"`) and feed dB readings as `value`. The `warn` and `clip` thresholds are always fractions of the range (0.75 and 0.9 by default), so the same zone geometry works for linear and dB scales alike. A thin peak-hold line rides above the signal. Left alone, the component tracks its own peak from incoming values, holds it for a beat, then decays it toward the current level on an animation frame loop. Under `prefers-reduced-motion` the decay becomes a jump rather than a slide. If your audio engine already computes peaks, set the `peak` property and the line renders exactly there with no tracking of its own. One element is one channel: there is no stereo mode. Compose two meters side by side for a stereo pair. Channel count stays the consumer's decision, and layouts from mono to 7.1 fall out of ordinary flex composition rather than a prop fork. The component renders no visible text, so the `label` attribute is the accessible name; `role="meter"` with `aria-valuemin`, `aria-valuemax`, and `aria-valuenow` carries the reading itself.

Guidelines

When to use

  • Use LevelMeter for live, fast-moving readings (audio channels, input gain, buffer health) where Meter would flicker meaninglessly
  • Set `min="-60" max="0"` (or your headroom of choice) and feed dB values directly for audio work
  • Compose one meter per channel: two side by side for stereo, a row of them for a mixer
  • Give every meter a `label` naming its channel ("Master left", not "Level"). It is the only accessible name the component gets
  • Set the `peak` property from your audio engine when it already computes peak values; the built-in tracker is for when it does not
  • Tune `warn` and `clip` to your actual headroom. The defaults (0.75/0.9) suit a linear 0..1 signal

When not to use

  • Do not use LevelMeter for a static scalar like disk usage or a score. That is Meter, whose low/high/optimum semantics exist for exactly that
  • Do not use it for task completion. Progress owns determinate and indeterminate work tracking
  • Do not look for a stereo prop; two elements are the stereo pair
  • Do not drive `value` from slow polling and expect the peak line to mean much. The tracker is only as live as the data feeding it
  • Do not rely on segment color alone to signal clipping to users. Pair the meter with a clip indicator or text where it matters

Features

  • Segmented display with proportional lighting; segment count is configurable, and `segments="0"` gives a continuous bar
  • Three-zone tinting from `warn` and `clip` fractions: success, warning, and error via the `--color-*` tokens, glow on lit segments
  • Peak-hold line that tracks incoming values, holds, then decays, or renders a consumer-supplied `peak` exactly
  • Linear or dB scales through plain `min`/`max`. Thresholds stay fractions of the range either way
  • Vertical (default, bottom-up) and horizontal orientations using logical properties, so horizontal meters follow text direction
  • Peak decay runs on `requestAnimationFrame`, starts on connect, and stops on disconnect. No work while unmounted
  • Honours `prefers-reduced-motion`: the peak line jumps instead of animating its fall
  • Semantic `role="meter"` with `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, and a `label`-driven accessible name
  • One meter per channel; compose several for stereo or surround
  • Exposed CSS parts: meter, track, segment, fill, peak

Preview

Usage

Level Meter is in the media domain group, so it is absent from the default @arclux/arc-ui barrel. Import it from@arclux/arc-ui/media, or from its own subpath@arclux/arc-ui/level-meter. Everything else (the element, the CSS, the framework wrappers, the support it gets) is unchanged.

<!-- Stereo pair: one meter per channel -->
<div style="display: flex; gap: 4px;">
  <arc-level-meter id="ch-l" label="Master left" min="-60" max="0" value="-60"></arc-level-meter>
  <arc-level-meter id="ch-r" label="Master right" min="-60" max="0" value="-60"></arc-level-meter>
</div>

<script>
  // Drive it at signal rate; the meter tracks its own decaying peak.
  analyzer.onLevels = ({ left, right }) => {
    document.getElementById('ch-l').value = left;  // dB
    document.getElementById('ch-r').value = right;
  };
</script>

API

labelstring''
Accessible name applied as aria-label on the meter. The component renders no visible text, so this is the only name screen readers get; use something like "Master left" rather than "Level".
valuenumber0
Current level. Interpreted against min and max, so with the defaults (0 and 1) it is a linear fraction, and with min="-60" max="0" it is a dB reading. Values outside the range are clamped.
minnumber0
Value at the empty end of the meter. Defaults to 0.
maxnumber1
Value at the full end of the meter. Defaults to 1. Use -60..0 (or your headroom of choice) for dB scales.
peaknumber0
Externally supplied peak-hold level, in the same units as value. When set, the component renders the hold line exactly there and does no tracking of its own. When absent, the meter tracks its own peak from incoming values, holds it briefly, then decays it toward the current level.
orientation'vertical' | 'horizontal''vertical'
Meter direction. Vertical (the default) fills bottom-up like a channel strip; horizontal fills from the inline start. Unknown values fall back to vertical.
segmentsnumber20
Number of discrete segments. Defaults to 20. Set 0 for a continuous, unsegmented bar.
warnnumber0.75
Fraction of the range (0..1) where the warning zone begins, regardless of units. Defaults to 0.75.
clipnumber0.9
Fraction of the range (0..1) where the clip (error) zone begins. Defaults to 0.9.

See Also