react-modern-audio-player 2.0.0-beta.1 → 2.1.0
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 +96 -23
- package/dist/index.es.js +737 -675
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/VolumeIcon.d.ts +2 -0
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/index.d.ts +1 -1
- package/dist/types/components/Dropdown/DropdownTrigger.d.ts +4 -2
- package/dist/types/components/SortableList/useSortableListItem.d.ts +1 -0
- package/package.json +23 -8
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/VolumeTriggerBtn.d.ts +0 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- markdownlint-disable MD033 MD041 MD028 -->
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img width="
|
|
4
|
+
<img width="12%" src="https://raw.githubusercontent.com/slash9494/react-modern-audio-player/main/package/assets/icon.png" alt="rm-audio-player" />
|
|
5
5
|
<h1 align="center">React Modern Audio Player</h1>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
@@ -15,31 +15,56 @@
|
|
|
15
15
|
<a href="https://www.npmjs.com/package/react-modern-audio-player">
|
|
16
16
|
<img src="https://img.shields.io/npm/dt/react-modern-audio-player" alt="Download">
|
|
17
17
|
</a>
|
|
18
|
-
<a href="https://bundlephobia.com/package/react-modern-audio-player@0.0
|
|
18
|
+
<a href="https://bundlephobia.com/package/react-modern-audio-player@2.0.0">
|
|
19
19
|
<img src="https://img.shields.io/bundlephobia/minzip/react-modern-audio-player" alt="BundleSize">
|
|
20
20
|
</a>
|
|
21
|
+
<a href="https://github.com/slash9494/react-modern-audio-player/actions/workflows/integration.yml">
|
|
22
|
+
<img src="https://github.com/slash9494/react-modern-audio-player/actions/workflows/integration.yml/badge.svg?branch=main" alt="CI">
|
|
23
|
+
</a>
|
|
24
|
+
<img src="https://img.shields.io/badge/TypeScript-first-3178C6?logo=typescript&logoColor=white" alt="TypeScript">
|
|
21
25
|
</p>
|
|
22
26
|
|
|
27
|
+
## Highlights
|
|
28
|
+
|
|
29
|
+
- **Waveform** progress bar powered by `wavesurfer.js`
|
|
30
|
+
- **Playlist** with drag-and-drop reorder, repeat, shuffle
|
|
31
|
+
- **Fully customizable** — swap any sub-component, CSS variable theming, light & dark themes
|
|
32
|
+
- **Accessible** — WAI-ARIA patterns, full keyboard navigation, axe-tested
|
|
33
|
+
- **TypeScript-first** — typed props and hooks (`useAudioPlayer`, sub-hooks)
|
|
34
|
+
- **SSR-friendly** — works with Next.js App Router / Server Components
|
|
35
|
+
|
|
23
36
|
## DEMO
|
|
24
37
|
|
|
25
|
-
<https://codesandbox.io/
|
|
38
|
+
<https://codesandbox.io/p/sandbox/basic-nfrpfq>
|
|
26
39
|
|
|
27
40
|
# **Flexible and Customizable UI**
|
|
28
41
|
|
|
29
|
-
##
|
|
42
|
+
## Waveform progress with `wavesurfer.js`
|
|
30
43
|
|
|
31
|
-
<img width="100%" src="https://
|
|
44
|
+
<img width="100%" src="https://raw.githubusercontent.com/slash9494/react-modern-audio-player/main/package/assets/screenshots/waveform-light.png" alt="Waveform view" />
|
|
32
45
|
|
|
33
|
-
##
|
|
46
|
+
## Customizable layout and placement — with light & dark themes
|
|
34
47
|
|
|
35
|
-
|
|
36
|
-
> <img width="100%" src="https://user-images.githubusercontent.com/70849655/180435489-263fae23-f066-4a37-a524-58918eb40b0c.png" alt="">
|
|
48
|
+
### Full View
|
|
37
49
|
|
|
38
|
-
>
|
|
39
|
-
|
|
50
|
+
<p align="center">
|
|
51
|
+
<img width="49%" src="https://raw.githubusercontent.com/slash9494/react-modern-audio-player/main/package/assets/screenshots/full-view-light.png" alt="Full view — light" />
|
|
52
|
+
<img width="49%" src="https://raw.githubusercontent.com/slash9494/react-modern-audio-player/main/package/assets/screenshots/full-view-dark.png" alt="Full view — dark" />
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
### Position Change
|
|
56
|
+
|
|
57
|
+
<p align="center">
|
|
58
|
+
<img width="49%" src="https://raw.githubusercontent.com/slash9494/react-modern-audio-player/main/package/assets/screenshots/position-change-light.png" alt="Position change — light" />
|
|
59
|
+
<img width="49%" src="https://raw.githubusercontent.com/slash9494/react-modern-audio-player/main/package/assets/screenshots/position-change-dark.png" alt="Position change — dark" />
|
|
60
|
+
</p>
|
|
40
61
|
|
|
41
|
-
|
|
42
|
-
|
|
62
|
+
### Particular View
|
|
63
|
+
|
|
64
|
+
<p align="center" style="display:flex; gap: 10%;">
|
|
65
|
+
<img width="39%" src="https://raw.githubusercontent.com/slash9494/react-modern-audio-player/main/package/assets/screenshots/particular-view-dark.png" alt="Particular view — compact compound" />
|
|
66
|
+
<img width="10%" height="50%" src="https://raw.githubusercontent.com/slash9494/react-modern-audio-player/main/package/assets/screenshots/particular-view-play-only-dark.png" alt="Particular view — play button only" />
|
|
67
|
+
</p>
|
|
43
68
|
|
|
44
69
|
# **Installation**
|
|
45
70
|
|
|
@@ -83,7 +108,13 @@ This library includes the `'use client'` directive and can be imported directly
|
|
|
83
108
|
import AudioPlayer from "react-modern-audio-player";
|
|
84
109
|
|
|
85
110
|
const playList = [
|
|
86
|
-
{
|
|
111
|
+
{
|
|
112
|
+
name: "track",
|
|
113
|
+
writer: "artist",
|
|
114
|
+
img: "cover.jpg",
|
|
115
|
+
src: "audio.mp3",
|
|
116
|
+
id: 1,
|
|
117
|
+
},
|
|
87
118
|
];
|
|
88
119
|
|
|
89
120
|
export default function Page() {
|
|
@@ -124,6 +155,7 @@ export default function PlayerPage() {
|
|
|
124
155
|
| **Override & Style** | [CustomIcons](#customicons) · [CoverImgsCss](#coverimgscss) · [Theme mode](#theme-mode-dark-mode) · [ID & Classnames](#id--classnames) |
|
|
125
156
|
| **Player Hook API** | [useAudioPlayer](#useaudioplayer) · [AudioPlayerControls](#audioplayercontrols) · [Sub-Hooks](#sub-hooks) |
|
|
126
157
|
| **Custom Component** | [Custom Component](#custom-component) |
|
|
158
|
+
| **Accessibility** | [Keyboard support](#keyboard-support) |
|
|
127
159
|
| **Example** | [Example](#example) |
|
|
128
160
|
|
|
129
161
|
# Props
|
|
@@ -173,6 +205,26 @@ type AudioData = {
|
|
|
173
205
|
};
|
|
174
206
|
```
|
|
175
207
|
|
|
208
|
+
### Empty playlist handling
|
|
209
|
+
|
|
210
|
+
Passing `playList={[]}` renders the player in an empty state without crashing. This is useful while waiting for asynchronous track data:
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
function App() {
|
|
214
|
+
const [tracks, setTracks] = useState<PlayList>([]);
|
|
215
|
+
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
fetchTracks().then(setTracks);
|
|
218
|
+
}, []);
|
|
219
|
+
|
|
220
|
+
// Safe — the player mounts with no audio source and activates once tracks arrive.
|
|
221
|
+
return <AudioPlayer playList={tracks} />;
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
- When the playlist becomes empty after updates, playback stops and all time state resets.
|
|
226
|
+
- When `audioInitialState.curPlayId` doesn't match any track in the current list, the player falls back to `playList[0]` automatically.
|
|
227
|
+
|
|
176
228
|
## InitialStates
|
|
177
229
|
|
|
178
230
|
```tsx
|
|
@@ -389,8 +441,7 @@ function PlayerControls() {
|
|
|
389
441
|
<button onClick={() => setVolume(0.5)}>Volume 50%</button>
|
|
390
442
|
<button onClick={() => setTrack(1)}>Track 2</button>
|
|
391
443
|
<p>
|
|
392
|
-
{currentTrack?.name} — {currentTime.toFixed(0)}s / {duration.toFixed(0)}
|
|
393
|
-
s
|
|
444
|
+
{currentTrack?.name} — {currentTime.toFixed(0)}s / {duration.toFixed(0)}s
|
|
394
445
|
</p>
|
|
395
446
|
</div>
|
|
396
447
|
);
|
|
@@ -451,17 +502,21 @@ function PlayButton() {
|
|
|
451
502
|
// Only re-renders on time updates
|
|
452
503
|
function TimeDisplay() {
|
|
453
504
|
const { currentTime, duration } = useAudioPlayerTime();
|
|
454
|
-
return
|
|
505
|
+
return (
|
|
506
|
+
<span>
|
|
507
|
+
{currentTime.toFixed(0)}s / {duration.toFixed(0)}s
|
|
508
|
+
</span>
|
|
509
|
+
);
|
|
455
510
|
}
|
|
456
511
|
```
|
|
457
512
|
|
|
458
|
-
| Hook
|
|
459
|
-
|
|
|
460
|
-
| `useAudioPlayerPlayback`
|
|
461
|
-
| `useAudioPlayerTrack`
|
|
462
|
-
| `useAudioPlayerVolume`
|
|
463
|
-
| `useAudioPlayerTime`
|
|
464
|
-
| `useAudioPlayerElement`
|
|
513
|
+
| Hook | Returns |
|
|
514
|
+
| ------------------------ | ------------------------------------------------------------------------------- |
|
|
515
|
+
| `useAudioPlayerPlayback` | `{ isPlaying, repeatType, play, pause, togglePlay }` |
|
|
516
|
+
| `useAudioPlayerTrack` | `{ currentPlayId, currentIndex, playList, currentTrack, setTrack, next, prev }` |
|
|
517
|
+
| `useAudioPlayerVolume` | `{ volume, muted, setVolume, toggleMute }` |
|
|
518
|
+
| `useAudioPlayerTime` | `{ currentTime, duration, seek }` |
|
|
519
|
+
| `useAudioPlayerElement` | `{ audioEl, waveformInst }` (advanced) |
|
|
465
520
|
|
|
466
521
|
# Context Hooks
|
|
467
522
|
|
|
@@ -535,6 +590,24 @@ const CustomComponent = () => {
|
|
|
535
590
|
</AudioPlayer>;
|
|
536
591
|
```
|
|
537
592
|
|
|
593
|
+
# **Accessibility**
|
|
594
|
+
|
|
595
|
+
The player follows WAI-ARIA patterns and is fully navigable by keyboard and screen readers.
|
|
596
|
+
|
|
597
|
+
## Keyboard support
|
|
598
|
+
|
|
599
|
+
All controls are reachable via `Tab` and respond to standard keyboard activation. The playlist uses the WAI-ARIA "Listbox with Rearrangeable Options" pattern:
|
|
600
|
+
|
|
601
|
+
| Key | Action |
|
|
602
|
+
| --- | --- |
|
|
603
|
+
| `Tab` / `Shift+Tab` | Move focus between player controls |
|
|
604
|
+
| `Space` / `Enter` | Activate the focused button (play/pause, prev/next, repeat, mute, playlist) |
|
|
605
|
+
| `ArrowUp` / `ArrowDown` | Move focus between playlist items |
|
|
606
|
+
| `Alt+ArrowUp` / `Alt+ArrowDown` | Reorder the focused playlist item |
|
|
607
|
+
| `Enter` / `Space` on a playlist item | Select and play that track |
|
|
608
|
+
|
|
609
|
+
Drag-and-drop reordering is preserved as an alternative — keyboard and mouse both call the same `onReorder` handler.
|
|
610
|
+
|
|
538
611
|
# **Example**
|
|
539
612
|
|
|
540
613
|
```tsx
|