Lab

Waveform

The headless Waveform of @audio-ui/react: its parts, what each renders and owns, and their props.

pnpm add @audio-ui/react
import { Waveform } from "@audio-ui/react/waveform";
ExportKindWhat it is
Waveform.BarfunctionOne bar of Waveform.Bars.
Waveform.BarsfunctionDraws the waveform as a fixed number of elements, one Waveform.Bar each, for a visualizer styled in plain CSS.
Waveform.CanvasfunctionDraws the waveform on a canvas, laid out on the device pixel grid: as many bars as fit its width, every edge on a physical pixel, so it stays sharp at any pixel density and zoom level.
Waveform.ControlfunctionThe seekable surface: a press jumps to the pointer and a drag scrubs.
Waveform.HoverfunctionShown while the pointer is over the Control, positioned at the hovered point.
Waveform.MarkerfunctionA point of interest on the timeline, such as a cue or a chapter, positioned at value.
Waveform.PlayheadfunctionA marker at the playback position, with no interaction of its own.
Waveform.RegionfunctionA stretch of the timeline, such as a loop or a selection, laid over the waveform from value[0] to value[1].
Waveform.RegionHandlefunctionResizes one edge of the region: by dragging, or from the keyboard through the native <input type="range"> it holds, which carries the accessible name (aria-label / aria-labelledby).
Waveform.RootfunctionGroups the parts of a waveform and owns what they show: the audio's shape (peaks, known upfront, or a live levels signal) and, for a seekable one, the playback position in duration units.
Waveform.ThumbfunctionA handle centered on the playback position.

Anatomy

Import the primitive and assemble its parts.

import { Waveform } from "@audio-ui/react";

<Waveform.Root>
  <Waveform.Control>
    <Waveform.Canvas />
    <Waveform.Playhead />
    <Waveform.Region>
      <Waveform.RegionHandle edge="start" />
      <Waveform.RegionHandle edge="end" />
    </Waveform.Region>
    <Waveform.Marker />
    <Waveform.Hover />
    <Waveform.Thumb />
  </Waveform.Control>
</Waveform.Root>

API reference

Root

Groups the parts of a waveform and owns what they show: the audio's shape (peaks, known upfront, or a live levels signal) and, for a seekable one, the playback position in duration units. The position comes from value, or from a live source that the waveform follows straight in the DOM without re-rendering React; it is exposed as the --waveform-position CSS variable (a percentage). While a live signal is audible the element carries data-active. Renders a <div> element.

Props · 13

Data attributes · 3

data-disabled
Present when disabled.
data-dragging
Whether a pointer is scrubbing the waveform.
data-loading
Whether the audio is still on its way: there is nothing to seek yet.

Region

A stretch of the timeline, such as a loop or a selection, laid over the waveform from value[0] to value[1]. Dragging its body moves it; add a Waveform.RegionHandle per edge to resize it. Renders a <div> element.

Props · 7

Data attributes · 2

data-disabled
Present when disabled.
data-dragging
Whether a pointer is moving or resizing the region.

RegionHandle

Resizes one edge of the region: by dragging, or from the keyboard through the native <input type="range"> it holds, which carries the accessible name (aria-label / aria-labelledby). Renders a <div> element.

Props · 2

Data attributes · 2

data-disabled
Present when disabled.
data-dragging
Whether a pointer is moving or resizing the region.

Control

The seekable surface: a press jumps to the pointer and a drag scrubs. It tracks the hovered position for Waveform.Hover, sets touch-action: none so touch scrubbing doesn't scroll the page, and holds the native <input type="range"> that takes focus, handles the keyboard and carries the accessible name (aria-label / aria-labelledby). Leave it out for a waveform that is only shown. Renders a <div> element.

Props · 3

Data attributes · 3

data-disabled
Present when disabled.
data-dragging
Whether a pointer is scrubbing the waveform.
data-loading
Whether the audio is still on its way: there is nothing to seek yet.

Bars

Draws the waveform as a fixed number of elements, one Waveform.Bar each, for a visualizer styled in plain CSS. Each bar's level, 0…1, is written to its --waveform-level CSS variable outside React: levels rise at once and fall smoothly, and nothing is written while they rest or sit off screen. Bars the playback position has passed carry data-played. Its children are a function called once per bar; left out, plain bars are rendered. Renders a <div> element.

Props · 6

Data attributes · 3

data-disabled
Present when disabled.
data-dragging
Whether a pointer is scrubbing the waveform.
data-loading
Whether the audio is still on its way: there is nothing to seek yet.

Bar

One bar of Waveform.Bars. Its level, 0…1, is its --waveform-level CSS variable: size it with height: calc(var(--waveform-level) * 100%), or the width for a vertical layout. Renders a <span> element.

Props · 1

Data attributes · 3

data-disabled
Present when disabled.
data-dragging
Whether a pointer is scrubbing the waveform.
data-loading
Whether the audio is still on its way: there is nothing to seek yet.

Canvas

Draws the waveform on a canvas, laid out on the device pixel grid: as many bars as fit its width, every edge on a physical pixel, so it stays sharp at any pixel density and zoom level. It paints only when something changed, and not at all while it is off screen. With peaks, the played part is drawn in one color and the rest in another. With a live levels signal, mode picks between the current levels across the width and a scrolling record of the loudest one. The scope variant takes raw samples instead of levels, and traces them as they are. Colors come from CSS: --waveform-color and --waveform-progress-color (both default to the text color). The bar corner radius is barRadius, or the --waveform-bar-radius CSS length. Renders a <canvas> element.

Props · 11

Data attributes · 3

data-disabled
Present when disabled.
data-dragging
Whether a pointer is scrubbing the waveform.
data-loading
Whether the audio is still on its way: there is nothing to seek yet.

Thumb

A handle centered on the playback position. Renders a <div> element.

Data attributes · 3

data-disabled
Present when disabled.
data-dragging
Whether a pointer is scrubbing the waveform.
data-loading
Whether the audio is still on its way: there is nothing to seek yet.

Marker

A point of interest on the timeline, such as a cue or a chapter, positioned at value. Its children label it. Renders a <div> element.

Props · 1

Data attributes · 3

data-disabled
Present when disabled.
data-dragging
Whether a pointer is scrubbing the waveform.
data-loading
Whether the audio is still on its way: there is nothing to seek yet.

Playhead

A marker at the playback position, with no interaction of its own. Renders a <div> element.

Data attributes · 3

data-disabled
Present when disabled.
data-dragging
Whether a pointer is scrubbing the waveform.
data-loading
Whether the audio is still on its way: there is nothing to seek yet.

Hover

Shown while the pointer is over the Control, positioned at the hovered point. Its children receive the hovered position, to print a time. Renders a <div> element.

Props · 1

Data attributes · 3

data-disabled
Present when disabled.
data-dragging
Whether a pointer is scrubbing the waveform.
data-loading
Whether the audio is still on its way: there is nothing to seek yet.

Styled

The registry's styled Waveform, its usage and interaction: Waveform.

Built by Ouest Labs, the source code is available on GitHub.
RSS