react-audio-wavekit 0.2.4 → 0.2.6
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 +14 -0
- package/dist/waveform/index.cjs +5 -1
- package/dist/waveform/index.js +5 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -38,6 +38,8 @@ Static waveform visualization with playhead and drag-to-seek.
|
|
|
38
38
|
|
|
39
39
|
```tsx
|
|
40
40
|
<AudioWaveform
|
|
41
|
+
// Also accepts classnames, compatible with tailwind.
|
|
42
|
+
className=""
|
|
41
43
|
blob={audioBlob}
|
|
42
44
|
currentTime={currentTime}
|
|
43
45
|
duration={duration}
|
|
@@ -47,6 +49,11 @@ Static waveform visualization with playhead and drag-to-seek.
|
|
|
47
49
|
audio.currentTime = time;
|
|
48
50
|
audio.play();
|
|
49
51
|
}}
|
|
52
|
+
style={{
|
|
53
|
+
// Or use classNames with Tailwind
|
|
54
|
+
width: '400px',
|
|
55
|
+
height: '100px',
|
|
56
|
+
}}
|
|
50
57
|
/>
|
|
51
58
|
```
|
|
52
59
|
|
|
@@ -63,6 +70,8 @@ Static waveform visualization with playhead and drag-to-seek.
|
|
|
63
70
|
| `suspense` | `boolean` | `false` | Enable React Suspense mode |
|
|
64
71
|
| `appearance` | `AudioWaveformAppearance` | - | See [Appearance Options](#appearance-options) |
|
|
65
72
|
|
|
73
|
+
**SSR note:** When `suspense` is `true`, decoding only starts on the client after mount. On the server (and during the first client render), the waveform renders without peaks, so wrap the component in a Suspense boundary to show a fallback during hydration.
|
|
74
|
+
|
|
66
75
|
---
|
|
67
76
|
|
|
68
77
|
## Recorder
|
|
@@ -228,6 +237,11 @@ Components accept `className`, `style`, and all standard canvas HTML attributes.
|
|
|
228
237
|
<AudioWaveform
|
|
229
238
|
blob={blob}
|
|
230
239
|
className="h-32 w-full rounded-lg bg-slate-900 p-4"
|
|
240
|
+
// or style prop
|
|
241
|
+
style={{
|
|
242
|
+
width: "100%",
|
|
243
|
+
height: "100%",
|
|
244
|
+
}}
|
|
231
245
|
appearance={{
|
|
232
246
|
barColor: "#3b82f6",
|
|
233
247
|
barWidth: 2,
|
package/dist/waveform/index.cjs
CHANGED
|
@@ -24,9 +24,13 @@ const AudioWaveform = react.forwardRef(function AudioWaveform2({
|
|
|
24
24
|
}, ref) {
|
|
25
25
|
const [decodedPeaks, setDecodedPeaks] = react.useState(null);
|
|
26
26
|
const [error, setError] = react.useState(null);
|
|
27
|
+
const [isMounted, setIsMounted] = react.useState(false);
|
|
27
28
|
const blobRef = react.useRef(null);
|
|
28
29
|
const rendererRef = react.useRef(null);
|
|
29
30
|
const sampleCount = react.useMemo(() => getInitialSampleCount(), []);
|
|
31
|
+
react.useEffect(() => {
|
|
32
|
+
setIsMounted(true);
|
|
33
|
+
}, []);
|
|
30
34
|
react.useEffect(() => {
|
|
31
35
|
if (ref && typeof ref === "function") {
|
|
32
36
|
ref({ canvas: rendererRef.current?.canvas || null });
|
|
@@ -35,7 +39,7 @@ const AudioWaveform = react.forwardRef(function AudioWaveform2({
|
|
|
35
39
|
}
|
|
36
40
|
}, [ref]);
|
|
37
41
|
const shouldDecode = !precomputedPeaks && blob;
|
|
38
|
-
const suspensePeaks = shouldDecode && suspense ? utilSuspense.unwrapPromise(utilAudioDecoder.getAudioData(blob, sampleCount)) : null;
|
|
42
|
+
const suspensePeaks = shouldDecode && suspense && isMounted ? utilSuspense.unwrapPromise(utilAudioDecoder.getAudioData(blob, sampleCount)) : null;
|
|
39
43
|
react.useEffect(() => {
|
|
40
44
|
if (!shouldDecode || suspense) {
|
|
41
45
|
if (!shouldDecode) {
|
package/dist/waveform/index.js
CHANGED
|
@@ -22,9 +22,13 @@ const AudioWaveform = forwardRef(function AudioWaveform2({
|
|
|
22
22
|
}, ref) {
|
|
23
23
|
const [decodedPeaks, setDecodedPeaks] = useState(null);
|
|
24
24
|
const [error, setError] = useState(null);
|
|
25
|
+
const [isMounted, setIsMounted] = useState(false);
|
|
25
26
|
const blobRef = useRef(null);
|
|
26
27
|
const rendererRef = useRef(null);
|
|
27
28
|
const sampleCount = useMemo(() => getInitialSampleCount(), []);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
setIsMounted(true);
|
|
31
|
+
}, []);
|
|
28
32
|
useEffect(() => {
|
|
29
33
|
if (ref && typeof ref === "function") {
|
|
30
34
|
ref({ canvas: rendererRef.current?.canvas || null });
|
|
@@ -33,7 +37,7 @@ const AudioWaveform = forwardRef(function AudioWaveform2({
|
|
|
33
37
|
}
|
|
34
38
|
}, [ref]);
|
|
35
39
|
const shouldDecode = !precomputedPeaks && blob;
|
|
36
|
-
const suspensePeaks = shouldDecode && suspense ? unwrapPromise(getAudioData(blob, sampleCount)) : null;
|
|
40
|
+
const suspensePeaks = shouldDecode && suspense && isMounted ? unwrapPromise(getAudioData(blob, sampleCount)) : null;
|
|
37
41
|
useEffect(() => {
|
|
38
42
|
if (!shouldDecode || suspense) {
|
|
39
43
|
if (!shouldDecode) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-audio-wavekit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "React component library for audio waveform visualization and live recording",
|
|
5
5
|
"license": "CC0-1.0",
|
|
6
6
|
"author": "semanticist21",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@storybook/react": "10.1.4",
|
|
73
73
|
"@storybook/react-vite": "10.1.4",
|
|
74
74
|
"@tailwindcss/vite": "4.1.17",
|
|
75
|
-
"@testing-library/react": "^16.3.
|
|
75
|
+
"@testing-library/react": "^16.3.1",
|
|
76
76
|
"@types/node": "24.10.1",
|
|
77
77
|
"@types/react": "19.2.7",
|
|
78
78
|
"@types/react-dom": "19.2.3",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"typescript": "5.9.3",
|
|
88
88
|
"vite": "7.2.6",
|
|
89
89
|
"vite-plugin-dts": "4.5.4",
|
|
90
|
-
"vitest": "^4.0.
|
|
90
|
+
"vitest": "^4.0.16"
|
|
91
91
|
},
|
|
92
92
|
"dependencies": {
|
|
93
93
|
"mpg123-decoder": "^1.0.3"
|