@waveform-playlist/ui-components 13.1.0 → 13.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # @waveform-playlist/ui-components
2
+
3
+ React UI components for waveform-playlist — canvas-rendered waveform/spectrogram/piano-roll channels, track controls, VU metering, and the styled-components theming layer.
4
+
5
+ Used internally by [`@waveform-playlist/browser`](https://www.npmjs.com/package/@waveform-playlist/browser), which composes these components into a full multitrack editor. Most users get this package transitively and never install it directly — reach for it standalone if you're building custom playlist UI (e.g. a bespoke VU meter or a themed control) without the full editor.
6
+
7
+ ## Features
8
+
9
+ - **Canvas waveform rendering** — `Channel` draws peaks as bars, with an optional `roundedBars` mode
10
+ - **Spectrogram & piano-roll channels** — `SpectrogramChannel` and `PianoRollChannel` render alongside waveform as alternate track visualizations
11
+ - **Track controls** — mute/solo/volume, track menu, and other transport-adjacent controls
12
+ - **Theming** — `ThemeProvider` + `WaveformPlaylistTheme` (with `defaultTheme` and `darkTheme`) drive every styled component from a single theme object
13
+ - **Virtual scrolling** — chunked canvases and viewport tracking so long timelines don't render off-screen content
14
+ - **`SegmentedVUMeter`** — standalone level meter with configurable color stops, orientation, and scale
15
+ - **`PlaylistErrorBoundary`** — catches render errors without depending on `ThemeProvider`
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @waveform-playlist/ui-components
21
+ ```
22
+
23
+ Peer dependencies (install alongside):
24
+
25
+ ```bash
26
+ npm install react react-dom styled-components
27
+ ```
28
+
29
+ `@dnd-kit/react` is an optional peer — only needed if you use the drag/trim-enabled clip components.
30
+
31
+ ## Usage
32
+
33
+ Most components expect the context providers from `@waveform-playlist/browser`, but standalone pieces like `SegmentedVUMeter` work with just props:
34
+
35
+ ```tsx
36
+ import { SegmentedVUMeter } from '@waveform-playlist/ui-components';
37
+
38
+ function TrackMeter({ levels }: { levels: number[] }) {
39
+ return (
40
+ <SegmentedVUMeter
41
+ levels={levels}
42
+ channelLabels={['L', 'R']}
43
+ orientation="vertical"
44
+ showScale
45
+ />
46
+ );
47
+ }
48
+ ```
49
+
50
+ ## Theming
51
+
52
+ Wrap your tree in styled-components' `ThemeProvider` with a `WaveformPlaylistTheme` object — `defaultTheme` and `darkTheme` are exported as starting points and can be partially overridden:
53
+
54
+ ```tsx
55
+ import { ThemeProvider } from 'styled-components';
56
+ import { defaultTheme } from '@waveform-playlist/ui-components';
57
+
58
+ <ThemeProvider theme={{ ...defaultTheme, waveOutlineColor: '#ff6600' }}>
59
+ {/* playlist components */}
60
+ </ThemeProvider>;
61
+ ```
62
+
63
+ `@waveform-playlist/browser`'s `WaveformPlaylistProvider` sets this up for you via its own `theme` prop — you only need `ThemeProvider` directly when using `ui-components` outside that provider.
64
+
65
+ ## Examples & Documentation
66
+
67
+ Full guides, API reference, and live examples: [naomiaro.github.io/waveform-playlist](https://naomiaro.github.io/waveform-playlist/)
68
+
69
+ ## License
70
+
71
+ MIT
package/dist/index.js CHANGED
@@ -2513,12 +2513,12 @@ var SpectrogramChannel = ({
2513
2513
  const register = onCanvasRegisterRef.current;
2514
2514
  const remaining = [];
2515
2515
  for (const id of registeredIdsRef.current) {
2516
- const match = id.match(/chunk(\d+)$/);
2517
- if (!match) {
2516
+ const parsed = (0, import_core5.parseSpectrogramCanvasId)(id);
2517
+ if (!parsed) {
2518
2518
  remaining.push(id);
2519
2519
  continue;
2520
2520
  }
2521
- const chunkIdx = parseInt(match[1], 10);
2521
+ const chunkIdx = parsed.chunkIndex;
2522
2522
  const canvas = canvasMapRef.current.get(chunkIdx);
2523
2523
  if (canvas && canvas.isConnected) {
2524
2524
  remaining.push(id);
@@ -2533,7 +2533,7 @@ var SpectrogramChannel = ({
2533
2533
  registeredIdsRef.current = remaining;
2534
2534
  for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
2535
2535
  if (transferredCanvasesRef.current.has(canvas)) continue;
2536
- const canvasId = `${clipId}-ch${channelIndex}-chunk${canvasIdx}`;
2536
+ const canvasId = (0, import_core5.buildSpectrogramCanvasId)({ clipId, channelIndex, chunkIndex: canvasIdx });
2537
2537
  let offscreen;
2538
2538
  try {
2539
2539
  offscreen = canvas.transferControlToOffscreen();