@waveform-playlist/ui-components
The UI components package provides low-level React components for waveform visualization, track controls, and playlist UI elements. These components are used by the browser package but can also be used independently for custom implementations.Installation
Peer Dependencies
React 17.0.0 or later
React DOM 17.0.0 or later
Styled Components 5.0.0 or later
Optional Peer Dependencies
DnD Kit 6.0.0+ for drag-and-drop (only needed if using Clip/Track components)
DnD Kit modifiers 9.0.0+
DnD Kit utilities 3.0.0+
Main Exports
Components
Waveform Visualization
Canvas-based waveform channel renderer with virtual scrolling
Intelligent channel that switches between canvas rendering and loading states
FFT-based spectrogram visualization with Web Worker processing
Horizontal time ruler with configurable format (seconds, hh:mm:ss, samples)
Adaptive time scale that adjusts tick density based on zoom level
Vertical frequency labels for spectrogram (Hz, kHz)
Track & Clip Components
Complete track UI with controls, waveform, and interaction handlers
Audio clip with waveform, drag handles, and fade overlays
Clip name and color indicator
Draggable boundary handles for clip trimming
Visual fade curve overlay (linear, logarithmic, sCurve, exponential)
Playlist Layout
Container with horizontal virtual scrolling and viewport management
Animated playback position indicator
Visual selection region overlay
Loop region indicator with drag handles
Controls
Collection of track control components (Mute, Solo, Volume, Pan, Remove, etc.)
Dropdown menu for track actions
Master volume slider (0.0-1.0)
Time format selector dropdown
Current playback time display
Editable selection start/end time inputs
Generic time input with validation
Toggle automatic scrolling during playback
Utility
React error boundary for graceful error handling
Contexts
Provides viewport information for horizontal virtual scrolling
Access scroll position and visible range:
{ scrollLeft, containerWidth, visibleStart, visibleEnd }Provides clip’s pixel offset for coordinate space conversion
Provides device pixel ratio for high-DPI rendering
Provides playlist metadata (sample rate, samples per pixel)
Provides playout adapter reference
Styled-components theme provider with waveform-specific theme
Provides track control callbacks
Theming
Complete theme interface with all color and styling properties
Default light theme
Dark theme variant
Utilities
Time Formatting
Format seconds as string (hh:mm:ss, mm:ss.ms, samples, etc.)
Parse time string to seconds
Union type:
'seconds' | 'hh:mm:ss' | 'hh:mm:ss.ms' | 'samples'Conversions
Convert sample count to seconds
Convert seconds to sample count
Convert samples to pixels
Convert pixels to samples
Virtual Scrolling
Get array of visible canvas chunk indices for viewport-aware rendering
Usage Example
Custom Waveform Visualization
Custom Theme
Using Spectrogram
Key Features
Horizontal Virtual Scrolling
For performance with long audio files, waveforms are rendered in 1000px canvas chunks. Only visible chunks (plus buffer) are mounted:ScrollViewportProvidertracks scroll positionuseVisibleChunkIndices()calculates which chunks to render- Components use absolute positioning for chunks
- Massive memory savings for spectrogram visualization
High-DPI Canvas Rendering
All canvas components automatically scale for Retina/high-DPI displays:DevicePixelRatioProviderprovides window.devicePixelRatio- Canvas internal resolution scaled by DPR
- CSS size remains unchanged
- Crisp waveforms on all displays
Web Worker Spectrogram
Spectrogram FFT processing runs in a Web Worker to keep UI responsive:SpectrogramChanneltransfers canvas control to worker viatransferControlToOffscreen()- Worker processes audio and draws directly to canvas
- No main thread blocking
- Multi-channel fairness ensures all visible chunks render before background batches
Theme System
All styling properties live in theme object, not component props:- Colors, backgrounds, borders in
WaveformPlaylistTheme - Components access via
props.theme - Single source of truth for visual consistency
- Easy dark mode support
Architectural Patterns
Stable React Keys
Always usetrack.id / clip.clipId as React keys, never array indices. Index-based keys cause DOM reuse which breaks transferControlToOffscreen() (can only be called once per canvas).
Canvas Chunk Cleanup
useChunkedCanvasRefs() runs cleanup on every render because the virtualizer can unmount canvases between any render. This prevents stale canvas references in workers.
Virtual Scrolling Chunk Offsets
Canvas registries may contain non-consecutive chunks (e.g., chunks 50-55). Always useextractChunkNumber(canvasId) to get the real chunk index - never compute offsets from array index 0.