Skip to main content

RecordButton

Control button for starting and stopping audio recording. Package: @waveform-playlist/recording

Props

isRecording
boolean
required
Whether recording is currently active.
onClick
() => void
required
Callback function when the button is clicked.
disabled
boolean
default:"false"
Whether the button is disabled.
className
string
Additional CSS class name for styling.

Behavior

  • Shows “Record” text when not recording
  • Shows “Stop Recording” with pulsing indicator when recording
  • Button color changes based on recording state
  • Includes focus and hover states

Usage

import { useRecording, RecordButton } from '@waveform-playlist/recording';

function RecordingControls() {
  const { isRecording, startRecording, stopRecording } = useRecording();
  
  const handleClick = async () => {
    if (isRecording) {
      await stopRecording();
    } else {
      await startRecording();
    }
  };
  
  return <RecordButton isRecording={isRecording} onClick={handleClick} />;
}

MicrophoneSelector

Dropdown component for selecting microphone input device. Package: @waveform-playlist/recording

Props

devices
MicrophoneDevice[]
required
Array of available microphone devices.
selectedDeviceId
string
Currently selected device ID. If not provided, uses the first device.
onDeviceChange
(deviceId: string) => void
required
Callback when a different device is selected.
disabled
boolean
default:"false"
Whether the selector is disabled.
className
string
Additional CSS class name for styling.

Usage

import { useMicrophoneAccess, MicrophoneSelector } from '@waveform-playlist/recording';
import { useState } from 'react';

function MicrophoneSettings() {
  const { devices } = useMicrophoneAccess();
  const [selectedDevice, setSelectedDevice] = useState<string>();
  
  return (
    <MicrophoneSelector 
      devices={devices}
      selectedDeviceId={selectedDevice}
      onDeviceChange={setSelectedDevice}
    />
  );
}

RecordingIndicator

Displays recording status, duration, and visual indicator. Package: @waveform-playlist/recording

Props

isRecording
boolean
required
Whether recording is currently active.
isPaused
boolean
default:"false"
Whether recording is paused.
duration
number
required
Recording duration in seconds.
formatTime
(seconds: number) => string
Custom time formatting function. Default formats as MM:SS.
className
string
Additional CSS class name for styling.

Behavior

  • Shows blinking red dot when recording
  • Shows yellow dot when paused
  • Displays duration in MM:SS format (customizable)
  • Shows “Recording” or “Paused” status text
  • Background highlights when recording is active

Usage

import { useRecording, RecordingIndicator } from '@waveform-playlist/recording';

function RecordingStatus() {
  const { isRecording, isPaused, duration } = useRecording();
  
  return (
    <RecordingIndicator 
      isRecording={isRecording}
      isPaused={isPaused}
      duration={duration}
    />
  );
}

Custom Time Format

function formatTimeWithMillis(seconds: number): string {
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  const millis = Math.floor((seconds % 1) * 1000);
  return `${mins}:${secs.toString().padStart(2, '0')}.${millis.toString().padStart(3, '0')}`;
}

<RecordingIndicator 
  isRecording={isRecording}
  duration={duration}
  formatTime={formatTimeWithMillis}
/>

VUMeter

Displays real-time audio input levels with color-coded zones and peak indicator. Package: @waveform-playlist/recording

Props

level
number
required
Current audio level (0-1 range). Values are automatically clamped.
peakLevel
number
Peak level (0-1 range). When provided, shows a white indicator line at the peak position.
width
number
default:"200"
Width of the meter in pixels.
height
number
default:"20"
Height of the meter in pixels.
className
string
Additional CSS class name for styling.

Color Zones

  • Green (0-60%): Safe operating level
  • Yellow (60-85%): Approaching maximum
  • Red (85-100%): Clipping/distortion risk

Usage

import { useMicrophoneLevel, VUMeter } from '@waveform-playlist/recording';

function AudioLevelMeter({ stream }: { stream: MediaStream }) {
  const { level, peakLevel } = useMicrophoneLevel(stream);
  
  return (
    <VUMeter 
      level={level} 
      peakLevel={peakLevel}
      width={300}
      height={24}
    />
  );
}

Complete Recording UI Example

import { 
  useRecording,
  useMicrophoneAccess,
  useMicrophoneLevel,
  RecordButton,
  MicrophoneSelector,
  RecordingIndicator,
  VUMeter
} from '@waveform-playlist/recording';
import { useState } from 'react';

function RecordingInterface() {
  const [selectedDevice, setSelectedDevice] = useState<string>();
  
  const { 
    stream, 
    devices, 
    requestAccess 
  } = useMicrophoneAccess();
  
  const { 
    isRecording, 
    isPaused,
    duration,
    startRecording, 
    stopRecording,
    pauseRecording,
    resumeRecording
  } = useRecording({
    deviceId: selectedDevice
  });
  
  const { level, peakLevel } = useMicrophoneLevel(stream);
  
  const handleRecord = async () => {
    if (isRecording) {
      await stopRecording();
    } else {
      if (!stream) {
        await requestAccess(selectedDevice);
      }
      await startRecording();
    }
  };
  
  return (
    <div className="recording-ui">
      <MicrophoneSelector 
        devices={devices}
        selectedDeviceId={selectedDevice}
        onDeviceChange={setSelectedDevice}
      />
      
      <VUMeter 
        level={level} 
        peakLevel={peakLevel}
        width={300}
      />
      
      <RecordingIndicator 
        isRecording={isRecording}
        isPaused={isPaused}
        duration={duration}
      />
      
      <div className="controls">
        <RecordButton 
          isRecording={isRecording} 
          onClick={handleRecord}
        />
        
        {isRecording && (
          <button onClick={isPaused ? resumeRecording : pauseRecording}>
            {isPaused ? 'Resume' : 'Pause'}
          </button>
        )}
      </div>
    </div>
  );
}

Build docs developers (and LLMs) love