@waveform-playlist/ui-components 7.1.0 → 7.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/dist/index.mjs CHANGED
@@ -327,7 +327,7 @@ var AutomaticScrollCheckbox = ({
327
327
  };
328
328
 
329
329
  // src/components/Channel.tsx
330
- import { useLayoutEffect, useEffect as useEffect2, useCallback as useCallback2, useRef as useRef2 } from "react";
330
+ import { useLayoutEffect } from "react";
331
331
  import styled9 from "styled-components";
332
332
 
333
333
  // src/wfpl-theme.ts
@@ -493,6 +493,7 @@ import {
493
493
  useContext,
494
494
  useEffect,
495
495
  useCallback,
496
+ useMemo,
496
497
  useRef,
497
498
  useSyncExternalStore
498
499
  } from "react";
@@ -587,11 +588,52 @@ function useScrollViewportSelector(selector) {
587
588
  () => selector(null)
588
589
  );
589
590
  }
591
+ function useVisibleChunkIndices(totalWidth, chunkWidth) {
592
+ const visibleChunkKey = useScrollViewportSelector((viewport) => {
593
+ const totalChunks = Math.ceil(totalWidth / chunkWidth);
594
+ const indices = [];
595
+ for (let i = 0; i < totalChunks; i++) {
596
+ const chunkLeft = i * chunkWidth;
597
+ const thisChunkWidth = Math.min(totalWidth - chunkLeft, chunkWidth);
598
+ if (viewport) {
599
+ const chunkEnd = chunkLeft + thisChunkWidth;
600
+ if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
601
+ continue;
602
+ }
603
+ }
604
+ indices.push(i);
605
+ }
606
+ return indices.join(",");
607
+ });
608
+ return useMemo(
609
+ () => visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [],
610
+ [visibleChunkKey]
611
+ );
612
+ }
590
613
 
591
- // src/constants.ts
592
- var MAX_CANVAS_WIDTH = 1e3;
614
+ // src/hooks/useChunkedCanvasRefs.ts
615
+ import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2 } from "react";
616
+ function useChunkedCanvasRefs() {
617
+ const canvasMapRef = useRef2(/* @__PURE__ */ new Map());
618
+ const canvasRef = useCallback2((canvas) => {
619
+ if (canvas !== null) {
620
+ const idx = parseInt(canvas.dataset.index, 10);
621
+ canvasMapRef.current.set(idx, canvas);
622
+ }
623
+ }, []);
624
+ useEffect2(() => {
625
+ const map = canvasMapRef.current;
626
+ for (const [idx, canvas] of map.entries()) {
627
+ if (!canvas.isConnected) {
628
+ map.delete(idx);
629
+ }
630
+ }
631
+ });
632
+ return { canvasRef, canvasMapRef };
633
+ }
593
634
 
594
635
  // src/components/Channel.tsx
636
+ import { MAX_CANVAS_WIDTH } from "@waveform-playlist/core";
595
637
  import { jsx as jsx4 } from "react/jsx-runtime";
596
638
  function createCanvasFillStyle(ctx, color, width, height) {
597
639
  if (!isWaveformGradient(color)) {
@@ -652,48 +694,11 @@ var Channel = (props) => {
652
694
  transparentBackground = false,
653
695
  drawMode = "inverted"
654
696
  } = props;
655
- const canvasesRef = useRef2([]);
656
- const visibleChunkKey = useScrollViewportSelector((viewport) => {
657
- const totalChunks = Math.ceil(length / MAX_CANVAS_WIDTH);
658
- const indices = [];
659
- for (let i = 0; i < totalChunks; i++) {
660
- const chunkLeft = i * MAX_CANVAS_WIDTH;
661
- const chunkWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
662
- if (viewport) {
663
- const chunkEnd = chunkLeft + chunkWidth;
664
- if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
665
- continue;
666
- }
667
- }
668
- indices.push(i);
669
- }
670
- return indices.join(",");
671
- });
672
- const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
673
- const canvasRef = useCallback2(
674
- (canvas) => {
675
- if (canvas !== null) {
676
- const index2 = parseInt(canvas.dataset.index, 10);
677
- canvasesRef.current[index2] = canvas;
678
- }
679
- },
680
- []
681
- );
682
- useEffect2(() => {
683
- const canvases = canvasesRef.current;
684
- for (let i = canvases.length - 1; i >= 0; i--) {
685
- if (canvases[i] && !canvases[i].isConnected) {
686
- delete canvases[i];
687
- }
688
- }
689
- });
697
+ const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
698
+ const visibleChunkIndices = useVisibleChunkIndices(length, MAX_CANVAS_WIDTH);
690
699
  useLayoutEffect(() => {
691
- const canvases = canvasesRef.current;
692
700
  const step = barWidth + barGap;
693
- for (let i = 0; i < canvases.length; i++) {
694
- const canvas = canvases[i];
695
- if (!canvas) continue;
696
- const canvasIdx = parseInt(canvas.dataset.index, 10);
701
+ for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
697
702
  const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH;
698
703
  const ctx = canvas.getContext("2d");
699
704
  const h2 = Math.floor(waveHeight / 2);
@@ -739,6 +744,7 @@ var Channel = (props) => {
739
744
  }
740
745
  }
741
746
  }, [
747
+ canvasMapRef,
742
748
  data,
743
749
  bits,
744
750
  waveHeight,
@@ -749,7 +755,7 @@ var Channel = (props) => {
749
755
  barWidth,
750
756
  barGap,
751
757
  drawMode,
752
- visibleChunkKey
758
+ visibleChunkIndices
753
759
  ]);
754
760
  const waveforms = visibleChunkIndices.map((i) => {
755
761
  const chunkLeft = i * MAX_CANVAS_WIDTH;
@@ -2061,8 +2067,9 @@ var usePlayoutStatus = () => useContext6(PlayoutStatusContext);
2061
2067
  var usePlayoutStatusUpdate = () => useContext6(PlayoutStatusUpdateContext);
2062
2068
 
2063
2069
  // src/components/SpectrogramChannel.tsx
2064
- import { useLayoutEffect as useLayoutEffect2, useCallback as useCallback5, useRef as useRef6, useEffect as useEffect6 } from "react";
2070
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef6, useEffect as useEffect6 } from "react";
2065
2071
  import styled19 from "styled-components";
2072
+ import { MAX_CANVAS_WIDTH as MAX_CANVAS_WIDTH2 } from "@waveform-playlist/core";
2066
2073
  import { jsx as jsx20 } from "react/jsx-runtime";
2067
2074
  var LINEAR_FREQUENCY_SCALE = (f, minF, maxF) => (f - minF) / (maxF - minF);
2068
2075
  var Wrapper3 = styled19.div.attrs((props) => ({
@@ -2116,38 +2123,13 @@ var SpectrogramChannel = ({
2116
2123
  onCanvasesReady
2117
2124
  }) => {
2118
2125
  const channelIndex = channelIndexProp ?? index;
2119
- const canvasesRef = useRef6([]);
2126
+ const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
2120
2127
  const registeredIdsRef = useRef6([]);
2121
2128
  const transferredCanvasesRef = useRef6(/* @__PURE__ */ new WeakSet());
2122
2129
  const workerApiRef = useRef6(workerApi);
2123
2130
  const onCanvasesReadyRef = useRef6(onCanvasesReady);
2124
2131
  const isWorkerMode = !!(workerApi && clipId);
2125
- const visibleChunkKey = useScrollViewportSelector((viewport) => {
2126
- const totalChunks = Math.ceil(length / MAX_CANVAS_WIDTH);
2127
- const indices = [];
2128
- for (let i = 0; i < totalChunks; i++) {
2129
- const chunkLeft = i * MAX_CANVAS_WIDTH;
2130
- const chunkWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
2131
- if (viewport) {
2132
- const chunkEnd = chunkLeft + chunkWidth;
2133
- if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
2134
- continue;
2135
- }
2136
- }
2137
- indices.push(i);
2138
- }
2139
- return indices.join(",");
2140
- });
2141
- const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
2142
- const canvasRef = useCallback5(
2143
- (canvas) => {
2144
- if (canvas !== null) {
2145
- const idx = parseInt(canvas.dataset.index, 10);
2146
- canvasesRef.current[idx] = canvas;
2147
- }
2148
- },
2149
- []
2150
- );
2132
+ const visibleChunkIndices = useVisibleChunkIndices(length, MAX_CANVAS_WIDTH2);
2151
2133
  const lut = colorLUT ?? DEFAULT_COLOR_LUT;
2152
2134
  const maxF = maxFrequency ?? (data ? data.sampleRate / 2 : 22050);
2153
2135
  const scaleFn = frequencyScaleFn ?? LINEAR_FREQUENCY_SCALE;
@@ -2162,14 +2144,30 @@ var SpectrogramChannel = ({
2162
2144
  if (!isWorkerMode) return;
2163
2145
  const currentWorkerApi = workerApiRef.current;
2164
2146
  if (!currentWorkerApi || !clipId) return;
2165
- const canvases2 = canvasesRef.current;
2147
+ const previousCount = registeredIdsRef.current.length;
2148
+ const remaining = [];
2149
+ for (const id of registeredIdsRef.current) {
2150
+ const match = id.match(/chunk(\d+)$/);
2151
+ if (!match) {
2152
+ remaining.push(id);
2153
+ continue;
2154
+ }
2155
+ const chunkIdx = parseInt(match[1], 10);
2156
+ const canvas = canvasMapRef.current.get(chunkIdx);
2157
+ if (canvas && canvas.isConnected) {
2158
+ remaining.push(id);
2159
+ } else {
2160
+ try {
2161
+ currentWorkerApi.unregisterCanvas(id);
2162
+ } catch (err) {
2163
+ console.warn(`[spectrogram] unregisterCanvas failed for ${id}:`, err);
2164
+ }
2165
+ }
2166
+ }
2167
+ registeredIdsRef.current = remaining;
2166
2168
  const newIds = [];
2167
- const newWidths = [];
2168
- for (let i = 0; i < canvases2.length; i++) {
2169
- const canvas = canvases2[i];
2170
- if (!canvas) continue;
2169
+ for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
2171
2170
  if (transferredCanvasesRef.current.has(canvas)) continue;
2172
- const canvasIdx = parseInt(canvas.dataset.index, 10);
2173
2171
  const canvasId = `${clipId}-ch${channelIndex}-chunk${canvasIdx}`;
2174
2172
  let offscreen;
2175
2173
  try {
@@ -2182,7 +2180,6 @@ var SpectrogramChannel = ({
2182
2180
  try {
2183
2181
  currentWorkerApi.registerCanvas(canvasId, offscreen);
2184
2182
  newIds.push(canvasId);
2185
- newWidths.push(Math.min(length - canvasIdx * MAX_CANVAS_WIDTH, MAX_CANVAS_WIDTH));
2186
2183
  } catch (err) {
2187
2184
  console.warn(`[spectrogram] registerCanvas failed for ${canvasId}:`, err);
2188
2185
  continue;
@@ -2190,34 +2187,22 @@ var SpectrogramChannel = ({
2190
2187
  }
2191
2188
  if (newIds.length > 0) {
2192
2189
  registeredIdsRef.current = [...registeredIdsRef.current, ...newIds];
2193
- onCanvasesReadyRef.current?.(newIds, newWidths);
2194
2190
  }
2195
- }, [isWorkerMode, clipId, channelIndex, length, visibleChunkKey]);
2196
- useEffect6(() => {
2197
- if (!isWorkerMode) return;
2198
- const currentWorkerApi = workerApiRef.current;
2199
- if (!currentWorkerApi) return;
2200
- const remaining = [];
2201
- for (const id of registeredIdsRef.current) {
2202
- const match = id.match(/chunk(\d+)$/);
2203
- if (!match) {
2204
- remaining.push(id);
2205
- continue;
2206
- }
2207
- const chunkIdx = parseInt(match[1], 10);
2208
- const canvas = canvasesRef.current[chunkIdx];
2209
- if (canvas && canvas.isConnected) {
2210
- remaining.push(id);
2211
- } else {
2212
- try {
2213
- currentWorkerApi.unregisterCanvas(id);
2214
- } catch (err) {
2215
- console.warn(`[spectrogram] unregisterCanvas failed for ${id}:`, err);
2191
+ const canvasSetChanged = newIds.length > 0 || remaining.length < previousCount;
2192
+ if (canvasSetChanged) {
2193
+ const allIds = registeredIdsRef.current;
2194
+ const allWidths = allIds.map((id) => {
2195
+ const match = id.match(/chunk(\d+)$/);
2196
+ if (!match) {
2197
+ console.warn(`[spectrogram] Unexpected canvas ID format: ${id}`);
2198
+ return MAX_CANVAS_WIDTH2;
2216
2199
  }
2217
- }
2200
+ const chunkIdx = parseInt(match[1], 10);
2201
+ return Math.min(length - chunkIdx * MAX_CANVAS_WIDTH2, MAX_CANVAS_WIDTH2);
2202
+ });
2203
+ onCanvasesReadyRef.current?.(allIds, allWidths);
2218
2204
  }
2219
- registeredIdsRef.current = remaining;
2220
- });
2205
+ }, [canvasMapRef, isWorkerMode, clipId, channelIndex, length, visibleChunkIndices]);
2221
2206
  useEffect6(() => {
2222
2207
  return () => {
2223
2208
  const api = workerApiRef.current;
@@ -2234,15 +2219,11 @@ var SpectrogramChannel = ({
2234
2219
  }, []);
2235
2220
  useLayoutEffect2(() => {
2236
2221
  if (isWorkerMode || !data) return;
2237
- const canvases2 = canvasesRef.current;
2238
2222
  const { frequencyBinCount, frameCount, hopSize, sampleRate, gainDb, rangeDb: rawRangeDb } = data;
2239
2223
  const rangeDb = rawRangeDb === 0 ? 1 : rawRangeDb;
2240
2224
  const binToFreq = (bin) => bin / frequencyBinCount * (sampleRate / 2);
2241
- for (let i = 0; i < canvases2.length; i++) {
2242
- const canvas = canvases2[i];
2243
- if (!canvas) continue;
2244
- const canvasIdx = parseInt(canvas.dataset.index, 10);
2245
- const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH;
2225
+ for (const [canvasIdx, canvas] of canvasMapRef.current.entries()) {
2226
+ const globalPixelOffset = canvasIdx * MAX_CANVAS_WIDTH2;
2246
2227
  const ctx = canvas.getContext("2d");
2247
2228
  if (!ctx) continue;
2248
2229
  const canvasWidth = canvas.width / devicePixelRatio;
@@ -2302,10 +2283,10 @@ var SpectrogramChannel = ({
2302
2283
  ctx.drawImage(tmpCanvas, 0, 0, canvas.width, canvas.height);
2303
2284
  }
2304
2285
  }
2305
- }, [isWorkerMode, data, length, waveHeight, devicePixelRatio, samplesPerPixel, lut, minFrequency, maxF, scaleFn, hasCustomFrequencyScale, visibleChunkKey]);
2286
+ }, [canvasMapRef, isWorkerMode, data, length, waveHeight, devicePixelRatio, samplesPerPixel, lut, minFrequency, maxF, scaleFn, hasCustomFrequencyScale, visibleChunkIndices]);
2306
2287
  const canvases = visibleChunkIndices.map((i) => {
2307
- const chunkLeft = i * MAX_CANVAS_WIDTH;
2308
- const currentWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH);
2288
+ const chunkLeft = i * MAX_CANVAS_WIDTH2;
2289
+ const currentWidth = Math.min(length - chunkLeft, MAX_CANVAS_WIDTH2);
2309
2290
  return /* @__PURE__ */ jsx20(
2310
2291
  SpectrogramCanvas,
2311
2292
  {
@@ -2527,7 +2508,7 @@ var SpectrogramLabels = ({
2527
2508
  import { useContext as useContext8 } from "react";
2528
2509
 
2529
2510
  // src/components/TimeScale.tsx
2530
- import React15, { useRef as useRef8, useEffect as useEffect7, useLayoutEffect as useLayoutEffect4, useContext as useContext7, useMemo, useCallback as useCallback6 } from "react";
2511
+ import React15, { useLayoutEffect as useLayoutEffect4, useContext as useContext7, useMemo as useMemo2 } from "react";
2531
2512
  import styled21, { withTheme as withTheme2 } from "styled-components";
2532
2513
 
2533
2514
  // src/utils/conversions.ts
@@ -2551,6 +2532,7 @@ function secondsToPixels(seconds, samplesPerPixel, sampleRate) {
2551
2532
  }
2552
2533
 
2553
2534
  // src/components/TimeScale.tsx
2535
+ import { MAX_CANVAS_WIDTH as MAX_CANVAS_WIDTH3 } from "@waveform-playlist/core";
2554
2536
  import { jsx as jsx23, jsxs as jsxs10 } from "react/jsx-runtime";
2555
2537
  function formatTime2(milliseconds) {
2556
2538
  const seconds = Math.floor(milliseconds / 1e3);
@@ -2602,7 +2584,7 @@ var TimeScale = (props) => {
2602
2584
  secondStep,
2603
2585
  renderTimestamp
2604
2586
  } = props;
2605
- const canvasRefsMap = useRef8(/* @__PURE__ */ new Map());
2587
+ const { canvasRef, canvasMapRef } = useChunkedCanvasRefs();
2606
2588
  const {
2607
2589
  sampleRate,
2608
2590
  samplesPerPixel,
@@ -2610,13 +2592,7 @@ var TimeScale = (props) => {
2610
2592
  controls: { show: showControls, width: controlWidth }
2611
2593
  } = useContext7(PlaylistInfoContext);
2612
2594
  const devicePixelRatio = useDevicePixelRatio();
2613
- const canvasRefCallback = useCallback6((canvas) => {
2614
- if (canvas !== null) {
2615
- const idx = parseInt(canvas.dataset.index, 10);
2616
- canvasRefsMap.current.set(idx, canvas);
2617
- }
2618
- }, []);
2619
- const { widthX, canvasInfo, timeMarkersWithPositions } = useMemo(() => {
2595
+ const { widthX, canvasInfo, timeMarkersWithPositions } = useMemo2(() => {
2620
2596
  const nextCanvasInfo = /* @__PURE__ */ new Map();
2621
2597
  const nextMarkers = [];
2622
2598
  const nextWidthX = secondsToPixels(duration / 1e3, samplesPerPixel, sampleRate);
@@ -2643,26 +2619,10 @@ var TimeScale = (props) => {
2643
2619
  timeMarkersWithPositions: nextMarkers
2644
2620
  };
2645
2621
  }, [duration, samplesPerPixel, sampleRate, marker, bigStep, secondStep, renderTimestamp, timeScaleHeight]);
2646
- const visibleChunkKey = useScrollViewportSelector((viewport) => {
2647
- const totalChunks = Math.ceil(widthX / MAX_CANVAS_WIDTH);
2648
- const indices = [];
2649
- for (let i = 0; i < totalChunks; i++) {
2650
- const chunkLeft = i * MAX_CANVAS_WIDTH;
2651
- const chunkWidth = Math.min(widthX - chunkLeft, MAX_CANVAS_WIDTH);
2652
- if (viewport) {
2653
- const chunkEnd = chunkLeft + chunkWidth;
2654
- if (chunkEnd <= viewport.visibleStart || chunkLeft >= viewport.visibleEnd) {
2655
- continue;
2656
- }
2657
- }
2658
- indices.push(i);
2659
- }
2660
- return indices.join(",");
2661
- });
2662
- const visibleChunkIndices = visibleChunkKey ? visibleChunkKey.split(",").map(Number) : [];
2622
+ const visibleChunkIndices = useVisibleChunkIndices(widthX, MAX_CANVAS_WIDTH3);
2663
2623
  const visibleChunks = visibleChunkIndices.map((i) => {
2664
- const chunkLeft = i * MAX_CANVAS_WIDTH;
2665
- const chunkWidth = Math.min(widthX - chunkLeft, MAX_CANVAS_WIDTH);
2624
+ const chunkLeft = i * MAX_CANVAS_WIDTH3;
2625
+ const chunkWidth = Math.min(widthX - chunkLeft, MAX_CANVAS_WIDTH3);
2666
2626
  return /* @__PURE__ */ jsx23(
2667
2627
  TimeTickChunk,
2668
2628
  {
@@ -2672,27 +2632,19 @@ var TimeScale = (props) => {
2672
2632
  width: chunkWidth * devicePixelRatio,
2673
2633
  height: timeScaleHeight * devicePixelRatio,
2674
2634
  "data-index": i,
2675
- ref: canvasRefCallback
2635
+ ref: canvasRef
2676
2636
  },
2677
2637
  `timescale-${i}`
2678
2638
  );
2679
2639
  });
2680
- const firstChunkLeft = visibleChunkIndices.length > 0 ? visibleChunkIndices[0] * MAX_CANVAS_WIDTH : 0;
2681
- const lastChunkRight = visibleChunkIndices.length > 0 ? (visibleChunkIndices[visibleChunkIndices.length - 1] + 1) * MAX_CANVAS_WIDTH : Infinity;
2640
+ const firstChunkLeft = visibleChunkIndices.length > 0 ? visibleChunkIndices[0] * MAX_CANVAS_WIDTH3 : 0;
2641
+ const lastChunkRight = visibleChunkIndices.length > 0 ? (visibleChunkIndices[visibleChunkIndices.length - 1] + 1) * MAX_CANVAS_WIDTH3 : Infinity;
2682
2642
  const visibleMarkers = visibleChunkIndices.length > 0 ? timeMarkersWithPositions.filter(({ pix }) => pix >= firstChunkLeft && pix < lastChunkRight).map(({ element }) => element) : timeMarkersWithPositions.map(({ element }) => element);
2683
- useEffect7(() => {
2684
- const currentMap = canvasRefsMap.current;
2685
- for (const [idx, canvas] of currentMap.entries()) {
2686
- if (!canvas.isConnected) {
2687
- currentMap.delete(idx);
2688
- }
2689
- }
2690
- });
2691
2643
  useLayoutEffect4(() => {
2692
- for (const [chunkIdx, canvas] of canvasRefsMap.current.entries()) {
2644
+ for (const [chunkIdx, canvas] of canvasMapRef.current.entries()) {
2693
2645
  const ctx = canvas.getContext("2d");
2694
2646
  if (!ctx) continue;
2695
- const chunkLeft = chunkIdx * MAX_CANVAS_WIDTH;
2647
+ const chunkLeft = chunkIdx * MAX_CANVAS_WIDTH3;
2696
2648
  const chunkWidth = canvas.width / devicePixelRatio;
2697
2649
  ctx.resetTransform();
2698
2650
  ctx.clearRect(0, 0, canvas.width, canvas.height);
@@ -2706,7 +2658,7 @@ var TimeScale = (props) => {
2706
2658
  ctx.fillRect(localX, scaleY, 1, scaleHeight);
2707
2659
  }
2708
2660
  }
2709
- }, [duration, devicePixelRatio, timeColor, timeScaleHeight, canvasInfo, visibleChunkKey]);
2661
+ }, [canvasMapRef, duration, devicePixelRatio, timeColor, timeScaleHeight, canvasInfo, visibleChunkIndices]);
2710
2662
  return /* @__PURE__ */ jsxs10(
2711
2663
  PlaylistTimeScaleScroll,
2712
2664
  {
@@ -3178,7 +3130,7 @@ var SliderWrapper = styled30.label`
3178
3130
  `;
3179
3131
 
3180
3132
  // src/components/TrackMenu.tsx
3181
- import React17, { useState as useState6, useEffect as useEffect8, useRef as useRef9 } from "react";
3133
+ import React17, { useState as useState6, useEffect as useEffect7, useRef as useRef8 } from "react";
3182
3134
  import { createPortal } from "react-dom";
3183
3135
  import styled31 from "styled-components";
3184
3136
  import { jsx as jsx32, jsxs as jsxs12 } from "react/jsx-runtime";
@@ -3226,9 +3178,9 @@ var TrackMenu = ({
3226
3178
  const close = () => setOpen(false);
3227
3179
  const items = typeof itemsProp === "function" ? itemsProp(close) : itemsProp;
3228
3180
  const [dropdownPos, setDropdownPos] = useState6({ top: 0, left: 0 });
3229
- const buttonRef = useRef9(null);
3230
- const dropdownRef = useRef9(null);
3231
- useEffect8(() => {
3181
+ const buttonRef = useRef8(null);
3182
+ const dropdownRef = useRef8(null);
3183
+ useEffect7(() => {
3232
3184
  if (open && buttonRef.current) {
3233
3185
  const rect = buttonRef.current.getBoundingClientRect();
3234
3186
  setDropdownPos({
@@ -3237,7 +3189,7 @@ var TrackMenu = ({
3237
3189
  });
3238
3190
  }
3239
3191
  }, [open]);
3240
- useEffect8(() => {
3192
+ useEffect7(() => {
3241
3193
  if (!open) return;
3242
3194
  const handleClick = (e) => {
3243
3195
  const target = e.target;
@@ -3312,7 +3264,6 @@ export {
3312
3264
  InlineLabel,
3313
3265
  LoopRegion,
3314
3266
  LoopRegionMarkers,
3315
- MAX_CANVAS_WIDTH,
3316
3267
  MasterVolumeControl,
3317
3268
  Playhead,
3318
3269
  PlayheadWithMarker,
@@ -3361,6 +3312,7 @@ export {
3361
3312
  useScrollViewportSelector,
3362
3313
  useTheme2 as useTheme,
3363
3314
  useTrackControls,
3315
+ useVisibleChunkIndices,
3364
3316
  waveformColorToCss
3365
3317
  };
3366
3318
  //# sourceMappingURL=index.mjs.map