react-modern-audio-player 1.4.0-rc.1 → 2.0.0-beta.1
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 +297 -103
- package/dist/index.css +1 -1
- package/dist/index.es.js +1925 -7956
- package/dist/types/api/index.d.ts +6 -0
- package/dist/types/api/useAudioPlayer.d.ts +27 -0
- package/dist/types/api/useAudioPlayerElement.d.ts +6 -0
- package/dist/types/api/useAudioPlayerPlayback.d.ts +9 -0
- package/dist/types/api/useAudioPlayerTime.d.ts +6 -0
- package/dist/types/api/useAudioPlayerTrack.d.ts +11 -0
- package/dist/types/api/useAudioPlayerVolume.d.ts +7 -0
- package/dist/types/components/AudioPlayer/Audio/index.d.ts +2 -2
- package/dist/types/components/AudioPlayer/Audio/useAudio.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Container/AudioPlayerContainer.d.ts +5 -0
- package/dist/types/components/AudioPlayer/Container/index.d.ts +1 -0
- package/dist/types/components/AudioPlayer/Context/AudioAttrsContext.d.ts +15 -0
- package/dist/types/components/AudioPlayer/Context/PlaybackContext.d.ts +10 -0
- package/dist/types/components/AudioPlayer/Context/ResourceContext.d.ts +7 -0
- package/dist/types/components/AudioPlayer/Context/StateContext/audio.d.ts +20 -12
- package/dist/types/components/AudioPlayer/Context/StateContext/element.d.ts +8 -13
- package/dist/types/components/AudioPlayer/Context/StateContext/index.d.ts +12 -8
- package/dist/types/components/AudioPlayer/Context/StateContext/placement.d.ts +9 -9
- package/dist/types/components/AudioPlayer/Context/TimeContext.d.ts +6 -0
- package/dist/types/components/AudioPlayer/Context/TrackContext.d.ts +7 -0
- package/dist/types/components/AudioPlayer/Context/UIContext.d.ts +11 -0
- package/dist/types/components/AudioPlayer/Context/dispatchContext.d.ts +15 -7
- package/dist/types/components/AudioPlayer/Context/index.d.ts +10 -3
- package/dist/types/components/AudioPlayer/Context/providerProps.d.ts +14 -0
- package/dist/types/components/AudioPlayer/Context/reducer.d.ts +2 -2
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/NextBtn.d.ts +6 -0
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/PlayBtn.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/PrevBtn.d.ts +6 -0
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/RepeatTypeBtn.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/VolumeTriggerBtn.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/index.d.ts +5 -5
- package/dist/types/components/AudioPlayer/Interface/Controller/Drawer/SortablePlayList/Content/PlayListItem.d.ts +3 -3
- package/dist/types/components/AudioPlayer/Interface/Controller/Drawer/SortablePlayList/Content/index.d.ts +2 -6
- package/dist/types/components/AudioPlayer/Interface/Controller/Drawer/SortablePlayList/Content/usePlayList.d.ts +3 -4
- package/dist/types/components/AudioPlayer/Interface/Controller/Drawer/SortablePlayList/PlayListIcon.d.ts +2 -0
- package/dist/types/components/AudioPlayer/Interface/Controller/Drawer/SortablePlayList/index.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/Drawer/index.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/Icon.d.ts +3 -3
- package/dist/types/components/AudioPlayer/Interface/Controller/Input/Progress/BarProgress.d.ts +2 -4
- package/dist/types/components/AudioPlayer/Interface/Controller/Input/Progress/WaveformProgress.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/Input/Progress/index.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/Input/Progress/useProgress.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/Input/Progress/useProgressKeyDown.d.ts +2 -0
- package/dist/types/components/AudioPlayer/Interface/Controller/Input/index.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/Tooltip/Volume/Content.d.ts +2 -2
- package/dist/types/components/AudioPlayer/Interface/Controller/Tooltip/Volume/index.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/Tooltip/Volume/useVolume.d.ts +2 -2
- package/dist/types/components/AudioPlayer/Interface/Controller/Tooltip/index.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Controller/index.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/CustomComponent/index.d.ts +2 -2
- package/dist/types/components/AudioPlayer/Interface/Information/Artwork.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Information/TrackInfo.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Information/TrackTime/Current.d.ts +2 -2
- package/dist/types/components/AudioPlayer/Interface/Information/TrackTime/Duration.d.ts +2 -2
- package/dist/types/components/AudioPlayer/Interface/Information/TrackTime/TrackTimeContainer.d.ts +6 -0
- package/dist/types/components/AudioPlayer/Interface/Information/TrackTime/Types.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Information/TrackTime/index.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/Information/index.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Interface/index.d.ts +1 -1
- package/dist/types/components/AudioPlayer/Player/index.d.ts +9 -14
- package/dist/types/components/AudioPlayer/Player/usePropsStateEffect.d.ts +2 -2
- package/dist/types/components/AudioPlayer/Provider/AudioPlayerStateProvider.d.ts +7 -0
- package/dist/types/components/AudioPlayer/Provider/index.d.ts +1 -0
- package/dist/types/components/AudioPlayer/index.d.ts +10 -11
- package/dist/types/components/Drawer/Drawer.d.ts +5 -6
- package/dist/types/components/Drawer/DrawerContent.d.ts +4 -3
- package/dist/types/components/Drawer/DrawerContext.d.ts +2 -1
- package/dist/types/components/Drawer/DrawerTrigger.d.ts +7 -2
- package/dist/types/components/Drawer/index.d.ts +2 -2
- package/dist/types/components/Dropdown/Dropdown.d.ts +6 -6
- package/dist/types/components/Dropdown/DropdownContent.d.ts +3 -3
- package/dist/types/components/Dropdown/DropdownContext.d.ts +2 -1
- package/dist/types/components/Dropdown/DropdownTrigger.d.ts +2 -2
- package/dist/types/components/Dropdown/index.d.ts +2 -2
- package/dist/types/components/Dropdown/useDropdown.d.ts +3 -3
- package/dist/types/components/Dropdown/useDropdownPlacementStyle.d.ts +3 -0
- package/dist/types/components/Grid/Grid.d.ts +12 -8
- package/dist/types/components/Grid/Item.d.ts +8 -5
- package/dist/types/components/Grid/index.d.ts +8 -1
- package/dist/types/components/SortableList/SortableList.d.ts +4 -4
- package/dist/types/components/SortableList/SortableListItem.d.ts +5 -5
- package/dist/types/components/SortableList/index.d.ts +5 -5
- package/dist/types/components/SortableList/useSortableListItem.d.ts +1 -1
- package/dist/types/components/icons/index.d.ts +16 -0
- package/dist/types/hooks/context/index.d.ts +7 -0
- package/dist/types/hooks/context/useAudioAttrsContext.d.ts +2 -0
- package/dist/types/hooks/{useNonNullableContext.d.ts → context/useNonNullableContext.d.ts} +1 -1
- package/dist/types/hooks/context/usePlaybackContext.d.ts +2 -0
- package/dist/types/hooks/context/useResourceContext.d.ts +2 -0
- package/dist/types/hooks/context/useTimeContext.d.ts +2 -0
- package/dist/types/hooks/context/useTrackContext.d.ts +2 -0
- package/dist/types/hooks/context/useUIContext.d.ts +1 -0
- package/dist/types/hooks/index.d.ts +5 -4
- package/dist/types/hooks/useClickOutside.d.ts +1 -1
- package/dist/types/hooks/useDidUpdateEffect.d.ts +16 -0
- package/dist/types/hooks/useRefsDispatch.d.ts +1 -1
- package/dist/types/hooks/useVariableColor.d.ts +2 -2
- package/dist/types/index.d.ts +7 -5
- package/dist/types/test/setup.d.ts +0 -0
- package/dist/types/{components → ui}/CssTransition.d.ts +1 -3
- package/dist/types/ui/StyledBtn.d.ts +1 -0
- package/dist/types/utils/clampVolume.d.ts +5 -0
- package/dist/types/utils/generateUnionNumType.d.ts +2 -2
- package/dist/types/utils/refs.d.ts +1 -0
- package/dist/types/utils/safeRatio.d.ts +5 -0
- package/dist/types/utils/ssr.d.ts +5 -0
- package/dist/wavesurfer-_j5aw4gZ.mjs +4471 -0
- package/package.json +33 -22
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/PlayListTriggerBtn.d.ts +0 -5
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/PrevNnextBtn.d.ts +0 -7
- package/dist/types/components/AudioPlayer/Interface/Controller/Button/StyledBtn.d.ts +0 -1
- package/dist/types/components/AudioPlayer/Interface/Information/TrackTime/Styles.d.ts +0 -6
- package/dist/types/components/Provider/AudioPlayerProvider.d.ts +0 -3
- package/dist/types/components/Provider/SpectrumProvider.d.ts +0 -7
- package/dist/types/components/Provider/index.d.ts +0 -2
- package/dist/types/styles/GlobalStyle.d.ts +0 -1
- package/dist/types/utils/resetAudioValues.d.ts +0 -2
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<!-- markdownlint-disable MD033 MD041 MD028 -->
|
|
2
|
+
|
|
1
3
|
<p align="center">
|
|
2
4
|
<img width="20%" src="https://user-images.githubusercontent.com/70849655/180391190-2b268d23-c9f3-4e95-9fce-090897842c04.png" alt="rm-audio-player" />
|
|
3
5
|
<h1 align="center">React Modern Audio Player</h1>
|
|
@@ -19,62 +21,117 @@
|
|
|
19
21
|
</p>
|
|
20
22
|
|
|
21
23
|
## DEMO
|
|
22
|
-
https://codesandbox.io/s/basic-91y82y?file=/src/App.tsx
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
<https://codesandbox.io/s/basic-91y82y?file=/src/App.tsx>
|
|
26
|
+
|
|
27
|
+
# **Flexible and Customizable UI**
|
|
28
|
+
|
|
25
29
|
## This can offer waveform by `wavesurfer.js`
|
|
30
|
+
|
|
26
31
|
<img width="100%" src="https://user-images.githubusercontent.com/70849655/180435472-f043dbb4-54df-43e0-bc5c-67492510e817.png" alt="">
|
|
27
32
|
|
|
28
33
|
## This can offer various UI and you can also customize each component position
|
|
34
|
+
|
|
29
35
|
> Full View
|
|
30
36
|
> <img width="100%" src="https://user-images.githubusercontent.com/70849655/180435489-263fae23-f066-4a37-a524-58918eb40b0c.png" alt="">
|
|
31
37
|
|
|
32
38
|
> Position Change
|
|
33
39
|
> <img width="110%" src="https://user-images.githubusercontent.com/70849655/180435493-2c2e08c5-b67b-4ab7-aded-5a0403d42050.png" alt="">
|
|
34
40
|
|
|
35
|
-
|
|
36
41
|
> Particular View
|
|
37
|
-
>
|
|
38
|
-
><img width="50%" margin='10px' src="https://user-images.githubusercontent.com/70849655/180435497-0f839cd1-e1fd-400f-a013-82ba441ca79b.png" alt="">
|
|
39
|
-
><img width="20%" margin='10px' src="https://user-images.githubusercontent.com/70849655/180435479-4f056620-f850-4d21-ab23-24efc4300d68.png" alt="">
|
|
40
|
-
> </br>
|
|
41
|
-
><img width="20%" margin='10px' src="https://user-images.githubusercontent.com/70849655/180435484-3331b7cb-1555-4ffb-a36c-a5343f72c8c3.png" alt="">
|
|
42
|
-
> <img width="50%" margin='10px' src="https://user-images.githubusercontent.com/70849655/180435486-2402ba80-7121-410c-9a06-9a737be72ec2.png" alt="">
|
|
43
|
-
|
|
42
|
+
> <br/> > <img width="50%" margin='10px' src="https://user-images.githubusercontent.com/70849655/180435497-0f839cd1-e1fd-400f-a013-82ba441ca79b.png" alt=""> > <img width="20%" margin='10px' src="https://user-images.githubusercontent.com/70849655/180435479-4f056620-f850-4d21-ab23-24efc4300d68.png" alt=""> > <br/> > <img width="20%" margin='10px' src="https://user-images.githubusercontent.com/70849655/180435484-3331b7cb-1555-4ffb-a36c-a5343f72c8c3.png" alt=""> > <img width="50%" margin='10px' src="https://user-images.githubusercontent.com/70849655/180435486-2402ba80-7121-410c-9a06-9a737be72ec2.png" alt="">
|
|
44
43
|
|
|
45
|
-
#
|
|
44
|
+
# **Installation**
|
|
46
45
|
|
|
47
46
|
```tsx
|
|
48
47
|
npm install --save react-modern-audio-player
|
|
49
48
|
```
|
|
50
49
|
|
|
51
|
-
#
|
|
50
|
+
# **Requirements**
|
|
51
|
+
|
|
52
|
+
- React **18.0.0** or higher
|
|
53
|
+
- react-dom **18.0.0** or higher
|
|
54
|
+
> For React 16/17 projects, use v1.x of this library.
|
|
55
|
+
|
|
56
|
+
# **Quick Start**
|
|
52
57
|
|
|
53
58
|
```tsx
|
|
54
|
-
import AudioPlayer from
|
|
59
|
+
import AudioPlayer from "react-modern-audio-player";
|
|
55
60
|
|
|
56
61
|
const playList = [
|
|
57
62
|
{
|
|
58
|
-
name:
|
|
59
|
-
writer:
|
|
60
|
-
img:
|
|
61
|
-
src:
|
|
63
|
+
name: "name",
|
|
64
|
+
writer: "writer",
|
|
65
|
+
img: "image.jpg",
|
|
66
|
+
src: "audio.mp3",
|
|
62
67
|
id: 1,
|
|
63
68
|
},
|
|
64
|
-
]
|
|
65
|
-
function Player
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
];
|
|
70
|
+
function Player() {
|
|
71
|
+
return <AudioPlayer playList={playList} />;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
# **Next.js / Server Components**
|
|
76
|
+
|
|
77
|
+
This library includes the `'use client'` directive and can be imported directly in Next.js App Router.
|
|
78
|
+
|
|
79
|
+
**Server Component** — render `<AudioPlayer>` with static props (no hooks, no compound components):
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
// app/page.tsx — Server Component, no 'use client' needed
|
|
83
|
+
import AudioPlayer from "react-modern-audio-player";
|
|
84
|
+
|
|
85
|
+
const playList = [
|
|
86
|
+
{ name: "track", writer: "artist", img: "cover.jpg", src: "audio.mp3", id: 1 },
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
export default function Page() {
|
|
90
|
+
return <AudioPlayer playList={playList} activeUI={{ playButton: true }} />;
|
|
69
91
|
}
|
|
70
92
|
```
|
|
71
93
|
|
|
94
|
+
**Client Component** — use `useAudioPlayer` hooks or `AudioPlayer.CustomComponent`:
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
"use client";
|
|
98
|
+
// app/player/page.tsx — Client Component required for hooks & compound pattern
|
|
99
|
+
import AudioPlayer, { useAudioPlayer } from "react-modern-audio-player";
|
|
100
|
+
|
|
101
|
+
function Controls() {
|
|
102
|
+
const { isPlaying, togglePlay } = useAudioPlayer();
|
|
103
|
+
return <button onClick={togglePlay}>{isPlaying ? "Pause" : "Play"}</button>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export default function PlayerPage() {
|
|
107
|
+
return (
|
|
108
|
+
<AudioPlayer playList={playList}>
|
|
109
|
+
<AudioPlayer.CustomComponent id="controls">
|
|
110
|
+
<Controls />
|
|
111
|
+
</AudioPlayer.CustomComponent>
|
|
112
|
+
</AudioPlayer>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
> **Why `'use client'`?** The library's `'use client'` directive marks the **client boundary** — it allows Server Components to import and render `<AudioPlayer>`. However, `useAudioPlayer()` hooks and `AudioPlayer.CustomComponent` require client-side React features (state, context), so components using them must be Client Components.
|
|
118
|
+
|
|
119
|
+
## Table of Contents
|
|
120
|
+
|
|
121
|
+
| Category | Sections |
|
|
122
|
+
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
123
|
+
| **Props** | [PlayList](#playlist) · [InitialStates](#initialstates) · [ActiveUI](#activeui) · [Placement](#placement) · [RootContainerProps](#rootcontainerprops) |
|
|
124
|
+
| **Override & Style** | [CustomIcons](#customicons) · [CoverImgsCss](#coverimgscss) · [Theme mode](#theme-mode-dark-mode) · [ID & Classnames](#id--classnames) |
|
|
125
|
+
| **Player Hook API** | [useAudioPlayer](#useaudioplayer) · [AudioPlayerControls](#audioplayercontrols) · [Sub-Hooks](#sub-hooks) |
|
|
126
|
+
| **Custom Component** | [Custom Component](#custom-component) |
|
|
127
|
+
| **Example** | [Example](#example) |
|
|
128
|
+
|
|
72
129
|
# Props
|
|
73
130
|
|
|
74
131
|
```tsx
|
|
75
132
|
interface AudioPlayerProps {
|
|
76
133
|
playList: PlayList;
|
|
77
|
-
audioInitialState?:
|
|
134
|
+
audioInitialState?: InitialStates;
|
|
78
135
|
audioRef?: React.MutableRefObject<HTMLAudioElement>;
|
|
79
136
|
activeUI?: ActiveUI;
|
|
80
137
|
customIcons?: CustomIcons;
|
|
@@ -85,19 +142,21 @@ interface AudioPlayerProps {
|
|
|
85
142
|
interface?: InterfacePlacement;
|
|
86
143
|
volumeSlider?: VolumeSliderPlacement;
|
|
87
144
|
};
|
|
88
|
-
rootContainerProps?: RootContainerProps
|
|
145
|
+
rootContainerProps?: RootContainerProps;
|
|
146
|
+
colorScheme?: "light" | "dark";
|
|
89
147
|
}
|
|
90
148
|
```
|
|
91
149
|
|
|
92
|
-
Prop
|
|
93
|
-
|
|
94
|
-
`playList`
|
|
95
|
-
`audioInitialState`
|
|
96
|
-
`activeUI`
|
|
97
|
-
`customIcons`
|
|
98
|
-
`coverImgsCss`
|
|
99
|
-
`placement`
|
|
100
|
-
`rootContainerProps` | [RootContainerProps](#rootcontainerprops) |
|
|
150
|
+
| Prop | Type | Default |
|
|
151
|
+
| -------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
152
|
+
| `playList` | [PlayList](#playlist) | [ ] |
|
|
153
|
+
| `audioInitialState` | [InitialStates](#initialstates) | isPlaying: false </br>repeatType: "ALL" </br>volume: 1 |
|
|
154
|
+
| `activeUI` | [ActiveUI](#activeui) | playButton : true |
|
|
155
|
+
| `customIcons` | [CustomIcons](#customicons) | undefined |
|
|
156
|
+
| `coverImgsCss` | [CoverImgsCss](#coverimgscss) | undefined |
|
|
157
|
+
| `placement` | [Placement](#placement) | playListPlacement : "bottom" </br>interfacePlacement :[DefaultInterfacePlacement](#default-interface-placement) |
|
|
158
|
+
| `rootContainerProps` | [RootContainerProps](#rootcontainerprops) | width: 100%<br/>position: 'static'<br/>className: rmap-player-provider |
|
|
159
|
+
| `colorScheme` | `"light" \| "dark"` | undefined (follows OS `prefers-color-scheme`) |
|
|
101
160
|
|
|
102
161
|
## PlayList
|
|
103
162
|
|
|
@@ -106,22 +165,22 @@ type PlayList = Array<AudioData>;
|
|
|
106
165
|
type AudioData = {
|
|
107
166
|
src: string;
|
|
108
167
|
id: number;
|
|
109
|
-
name?: string
|
|
110
|
-
writer?: string
|
|
168
|
+
name?: string;
|
|
169
|
+
writer?: string;
|
|
111
170
|
img?: string;
|
|
112
171
|
description?: string | ReactNode;
|
|
113
172
|
customTrackInfo?: string | ReactNode;
|
|
114
173
|
};
|
|
115
174
|
```
|
|
116
175
|
|
|
117
|
-
##
|
|
176
|
+
## InitialStates
|
|
118
177
|
|
|
119
178
|
```tsx
|
|
120
|
-
type
|
|
179
|
+
type InitialStates = Omit<
|
|
121
180
|
React.AudioHTMLAttributes<HTMLAudioElement>,
|
|
122
181
|
"autoPlay"
|
|
123
182
|
> & {
|
|
124
|
-
|
|
183
|
+
isPlaying?: boolean;
|
|
125
184
|
repeatType?: RepeatType;
|
|
126
185
|
volume?: number;
|
|
127
186
|
currentTime?: number;
|
|
@@ -203,7 +262,7 @@ type InterfacePlacementKey =
|
|
|
203
262
|
| Exclude<keyof ActiveUI, "all" | "prevNnext" | "trackTime">
|
|
204
263
|
| "trackTimeCurrent"
|
|
205
264
|
| "trackTimeDuration";
|
|
206
|
-
|
|
265
|
+
|
|
207
266
|
type InterfacePlacementValue = "row1-1" | "row1-2" | "row1-3" | "row1-4" | ... more ... | "row9-9"
|
|
208
267
|
/** if you apply custom components, values must be "row1-1" ~ any more */
|
|
209
268
|
|
|
@@ -212,16 +271,17 @@ type InterfaceGridTemplateArea = Record<InterfacePlacementKey,InterfacePlacement
|
|
|
212
271
|
type InterfaceGridCustomComponentsArea = Record<componentId,InterfacePlacementValue>;
|
|
213
272
|
|
|
214
273
|
type InterfaceGridItemArea = Partial<Record<InterfacePlacementKey, string>>;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
274
|
+
/** example
|
|
275
|
+
* progress : 2-4
|
|
276
|
+
* repeatBtn : row1-4 / 2 / row1-4 / 10
|
|
277
|
+
*
|
|
278
|
+
* check MDN - grid area
|
|
279
|
+
* https://developer.mozilla.org/ko/docs/Web/CSS/grid-area
|
|
280
|
+
*/
|
|
222
281
|
```
|
|
223
282
|
|
|
224
283
|
### Default interface placement
|
|
284
|
+
|
|
225
285
|
```tsx
|
|
226
286
|
const defaultInterfacePlacement = {
|
|
227
287
|
templateArea: {
|
|
@@ -239,19 +299,27 @@ const defaultInterfacePlacement = {
|
|
|
239
299
|
```
|
|
240
300
|
|
|
241
301
|
## RootContainerProps
|
|
242
|
-
> it is same with spectrum provider props
|
|
243
|
-
> </br>
|
|
244
|
-
> https://react-spectrum.adobe.com/react-spectrum/Provider.html#themes
|
|
245
302
|
|
|
303
|
+
`rootContainerProps` accepts any standard `HTMLAttributes<HTMLDivElement>` (e.g. `className`, `style`, `data-*`). The root container always has the class `rmap-player-provider` applied automatically.
|
|
304
|
+
|
|
305
|
+
> ⚠️ Setting the native CSS `color-scheme` property via `rootContainerProps={{ style: { colorScheme: "dark" } }}` will **not** toggle the player's theme. The library's theme is driven by the `prefers-color-scheme` media query and the `[data-theme]` attribute selector — use the top-level [`colorScheme`](#theme-mode-dark-mode) prop instead.
|
|
246
306
|
|
|
247
307
|
# Override Style
|
|
248
308
|
|
|
249
|
-
|
|
309
|
+
## Theme mode (dark mode)
|
|
250
310
|
|
|
251
|
-
>
|
|
252
|
-
>
|
|
253
|
-
>
|
|
311
|
+
> Dark mode is driven by `system-theme` (`prefers-color-scheme: dark`) by default.
|
|
312
|
+
> To force a specific theme regardless of OS preference, pass the top-level `colorScheme="light" | "dark"` prop on `<AudioPlayer>` — this applies a `data-theme` attribute on `.rmap-player-provider` which overrides the media query.
|
|
313
|
+
> You can override any color by redefining the CSS variables below on `.rmap-player-provider`.
|
|
254
314
|
|
|
315
|
+
```css
|
|
316
|
+
@media (prefers-color-scheme: dark) {
|
|
317
|
+
.rmap-player-provider {
|
|
318
|
+
--rm-audio-player-interface-container: #1e1e1e;
|
|
319
|
+
/* override other variables as needed */
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
255
323
|
|
|
256
324
|
## ID & Classnames
|
|
257
325
|
|
|
@@ -261,39 +329,175 @@ const defaultInterfacePlacement = {
|
|
|
261
329
|
|
|
262
330
|
### root ClassName
|
|
263
331
|
|
|
264
|
-
-
|
|
332
|
+
- rmap-player-provider
|
|
265
333
|
|
|
266
334
|
### color variables
|
|
267
335
|
|
|
336
|
+
```css
|
|
337
|
+
.rmap-player-provider {
|
|
338
|
+
--rm-audio-player-text-color: #2c2c2c;
|
|
339
|
+
--rm-audio-player-shadow: 0 0 0;
|
|
340
|
+
--rm-audio-player-interface-container: #f5f5f5;
|
|
341
|
+
--rm-audio-player-volume-background: #ccc;
|
|
342
|
+
--rm-audio-player-volume-panel-background: #f2f2f2;
|
|
343
|
+
--rm-audio-player-volume-panel-border: #ccc;
|
|
344
|
+
--rm-audio-player-volume-thumb: #5c5c5c;
|
|
345
|
+
--rm-audio-player-volume-fill: rgba(0, 0, 0, 0.5);
|
|
346
|
+
--rm-audio-player-volume-track: #ababab;
|
|
347
|
+
--rm-audio-player-track-current-time: #0072f5;
|
|
348
|
+
--rm-audio-player-track-duration: #8c8c8c;
|
|
349
|
+
--rm-audio-player-progress-bar: #0072f5;
|
|
350
|
+
--rm-audio-player-progress-bar-background: #393939;
|
|
351
|
+
--rm-audio-player-waveform-cursor: #4b4b4b;
|
|
352
|
+
--rm-audio-player-waveform-background: var(
|
|
353
|
+
--rm-audio-player-progress-bar-background
|
|
354
|
+
);
|
|
355
|
+
--rm-audio-player-waveform-bar: var(--rm-audio-player-progress-bar);
|
|
356
|
+
--rm-audio-player-sortable-list: #eaeaea;
|
|
357
|
+
--rm-audio-player-sortable-list-button-active: #0072f5;
|
|
358
|
+
--rm-audio-player-selected-list-item-background: #b3b3b3;
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
# useAudioPlayer
|
|
363
|
+
|
|
364
|
+
Control the player externally using the `useAudioPlayer` hook. Must be called inside `AudioPlayerStateProvider` (or `AudioPlayer` which wraps it).
|
|
365
|
+
|
|
268
366
|
```tsx
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
367
|
+
import AudioPlayer, { useAudioPlayer } from "react-modern-audio-player";
|
|
368
|
+
|
|
369
|
+
function PlayerControls() {
|
|
370
|
+
const {
|
|
371
|
+
isPlaying,
|
|
372
|
+
currentTrack,
|
|
373
|
+
currentTime,
|
|
374
|
+
duration,
|
|
375
|
+
togglePlay,
|
|
376
|
+
next,
|
|
377
|
+
prev,
|
|
378
|
+
seek,
|
|
379
|
+
setVolume,
|
|
380
|
+
setTrack,
|
|
381
|
+
} = useAudioPlayer();
|
|
382
|
+
|
|
383
|
+
return (
|
|
384
|
+
<div>
|
|
385
|
+
<button onClick={togglePlay}>{isPlaying ? "Pause" : "Play"}</button>
|
|
386
|
+
<button onClick={prev}>Prev</button>
|
|
387
|
+
<button onClick={next}>Next</button>
|
|
388
|
+
<button onClick={() => seek(30)}>+30s</button>
|
|
389
|
+
<button onClick={() => setVolume(0.5)}>Volume 50%</button>
|
|
390
|
+
<button onClick={() => setTrack(1)}>Track 2</button>
|
|
391
|
+
<p>
|
|
392
|
+
{currentTrack?.name} — {currentTime.toFixed(0)}s / {duration.toFixed(0)}
|
|
393
|
+
s
|
|
394
|
+
</p>
|
|
395
|
+
</div>
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function App() {
|
|
400
|
+
const playList = [{ id: 1, src: "audio.mp3", name: "Track 1" }];
|
|
401
|
+
return (
|
|
402
|
+
<AudioPlayer playList={playList}>
|
|
403
|
+
<PlayerControls />
|
|
404
|
+
</AudioPlayer>
|
|
405
|
+
);
|
|
406
|
+
}
|
|
288
407
|
```
|
|
408
|
+
|
|
409
|
+
## AudioPlayerControls
|
|
410
|
+
|
|
411
|
+
| Property | Type | Description |
|
|
412
|
+
| ----------------- | -------------------------- | ------------------------- |
|
|
413
|
+
| `isPlaying` | `boolean` | Current playback state |
|
|
414
|
+
| `volume` | `number` | Current volume (0–1) |
|
|
415
|
+
| `currentTime` | `number` | Elapsed time in seconds |
|
|
416
|
+
| `duration` | `number` | Track duration in seconds |
|
|
417
|
+
| `repeatType` | `RepeatType` | Current repeat mode |
|
|
418
|
+
| `muted` | `boolean` | Whether audio is muted |
|
|
419
|
+
| `currentTrack` | `AudioData \| null` | Currently playing track |
|
|
420
|
+
| `currentIndex` | `number` | Index in playlist |
|
|
421
|
+
| `playList` | `PlayList` | Full playlist |
|
|
422
|
+
| `play()` | `() => void` | Start playback |
|
|
423
|
+
| `pause()` | `() => void` | Pause playback |
|
|
424
|
+
| `togglePlay()` | `() => void` | Toggle play/pause |
|
|
425
|
+
| `next()` | `() => void` | Skip to next track |
|
|
426
|
+
| `prev()` | `() => void` | Skip to previous track |
|
|
427
|
+
| `seek(time)` | `(time: number) => void` | Seek to time in seconds |
|
|
428
|
+
| `setVolume(vol)` | `(volume: number) => void` | Set volume (0–1, clamped) |
|
|
429
|
+
| `toggleMute()` | `() => void` | Toggle mute on/off |
|
|
430
|
+
| `setTrack(index)` | `(index: number) => void` | Jump to playlist index |
|
|
431
|
+
|
|
432
|
+
## Sub-Hooks
|
|
433
|
+
|
|
434
|
+
`useAudioPlayer` subscribes to all context slices. For fine-grained re-render control, use domain-specific sub-hooks:
|
|
435
|
+
|
|
436
|
+
```tsx
|
|
437
|
+
import {
|
|
438
|
+
useAudioPlayerPlayback,
|
|
439
|
+
useAudioPlayerTrack,
|
|
440
|
+
useAudioPlayerVolume,
|
|
441
|
+
useAudioPlayerTime,
|
|
442
|
+
useAudioPlayerElement,
|
|
443
|
+
} from "react-modern-audio-player";
|
|
444
|
+
|
|
445
|
+
// Only re-renders on play/pause and repeat type changes
|
|
446
|
+
function PlayButton() {
|
|
447
|
+
const { isPlaying, togglePlay } = useAudioPlayerPlayback();
|
|
448
|
+
return <button onClick={togglePlay}>{isPlaying ? "Pause" : "Play"}</button>;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Only re-renders on time updates
|
|
452
|
+
function TimeDisplay() {
|
|
453
|
+
const { currentTime, duration } = useAudioPlayerTime();
|
|
454
|
+
return <span>{currentTime.toFixed(0)}s / {duration.toFixed(0)}s</span>;
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
| Hook | Returns |
|
|
459
|
+
| -------------------------- | ------------------------------------------------------------------------------- |
|
|
460
|
+
| `useAudioPlayerPlayback` | `{ isPlaying, repeatType, play, pause, togglePlay }` |
|
|
461
|
+
| `useAudioPlayerTrack` | `{ currentPlayId, currentIndex, playList, currentTrack, setTrack, next, prev }` |
|
|
462
|
+
| `useAudioPlayerVolume` | `{ volume, muted, setVolume, toggleMute }` |
|
|
463
|
+
| `useAudioPlayerTime` | `{ currentTime, duration, seek }` |
|
|
464
|
+
| `useAudioPlayerElement` | `{ audioEl, waveformInst }` (advanced) |
|
|
465
|
+
|
|
466
|
+
# Context Hooks
|
|
467
|
+
|
|
468
|
+
Components inside `AudioPlayer` can subscribe to only the state slice they need, avoiding unnecessary re-renders.
|
|
469
|
+
|
|
470
|
+
```tsx
|
|
471
|
+
import {
|
|
472
|
+
usePlaybackContext, // curAudioState: { isPlaying, repeatType, volume, muted, isLoadedMetaData }
|
|
473
|
+
useTrackContext, // playList, curIdx, curPlayId
|
|
474
|
+
useUIContext, // activeUI, interfacePlacement, playListPlacement, playerPlacement, volumeSliderPlacement
|
|
475
|
+
useResourceContext, // elementRefs, customIcons, coverImgsCss
|
|
476
|
+
} from "react-modern-audio-player";
|
|
477
|
+
|
|
478
|
+
const MyComponent = () => {
|
|
479
|
+
const { curAudioState } = usePlaybackContext();
|
|
480
|
+
return <span>{curAudioState.isPlaying ? "Playing" : "Paused"}</span>;
|
|
481
|
+
};
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
| Hook | Returns |
|
|
485
|
+
| -------------------- | --------------------------------------------------------------------------------------------- |
|
|
486
|
+
| `usePlaybackContext` | `{ curAudioState: AudioState }` |
|
|
487
|
+
| `useTrackContext` | `{ playList, curIdx, curPlayId }` |
|
|
488
|
+
| `useUIContext` | `{ activeUI, interfacePlacement, playListPlacement, playerPlacement, volumeSliderPlacement }` |
|
|
489
|
+
| `useResourceContext` | `{ elementRefs, customIcons, coverImgsCss }` |
|
|
490
|
+
|
|
289
491
|
# Custom Component
|
|
290
|
-
> you can apply custom component to `AudioPlayer` by `CustomComponent`
|
|
291
|
-
> </br>
|
|
292
|
-
> you can also set `viewProps` to `CustomComponent`
|
|
293
|
-
> </br>
|
|
294
|
-
> (https://react-spectrum.adobe.com/react-spectrum/View.html#props)
|
|
295
492
|
|
|
296
|
-
|
|
493
|
+
You can place a custom component anywhere in the player interface using `AudioPlayer.CustomComponent`. Use `useAudioPlayer` inside it to access player state and controls.
|
|
494
|
+
|
|
495
|
+
```tsx
|
|
496
|
+
import AudioPlayer, {
|
|
497
|
+
useAudioPlayer,
|
|
498
|
+
InterfacePlacement,
|
|
499
|
+
} from "react-modern-audio-player";
|
|
500
|
+
|
|
297
501
|
const activeUI: ActiveUI = {
|
|
298
502
|
all: true,
|
|
299
503
|
};
|
|
@@ -305,44 +509,34 @@ const placement = {
|
|
|
305
509
|
},
|
|
306
510
|
} as InterfacePlacement<11>,
|
|
307
511
|
/**
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
|
|
512
|
+
* set the generic value of InterfacePlacement to the max interface length + 1
|
|
513
|
+
* for correct "row1-10" autocompletion
|
|
514
|
+
*/
|
|
311
515
|
};
|
|
312
516
|
|
|
313
|
-
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
}: {
|
|
317
|
-
audioPlayerState?: AudioPlayerStateContext;
|
|
318
|
-
}) => {
|
|
319
|
-
const audioEl = audioPlayerState?.elementRefs?.audioEl;
|
|
320
|
-
const handOverTime = () => {
|
|
321
|
-
if (audioEl) {
|
|
322
|
-
audioEl.currentTime += 30;
|
|
323
|
-
}
|
|
324
|
-
};
|
|
517
|
+
const CustomComponent = () => {
|
|
518
|
+
const { currentTime, duration, seek, isPlaying, togglePlay } =
|
|
519
|
+
useAudioPlayer();
|
|
325
520
|
return (
|
|
326
521
|
<>
|
|
327
|
-
<button onClick={
|
|
522
|
+
<button onClick={() => seek(currentTime + 30)}>+30s</button>
|
|
523
|
+
<button onClick={togglePlay}>{isPlaying ? "Pause" : "Play"}</button>
|
|
524
|
+
<span>
|
|
525
|
+
{currentTime.toFixed(0)}s / {duration.toFixed(0)}s
|
|
526
|
+
</span>
|
|
328
527
|
</>
|
|
329
528
|
);
|
|
330
529
|
};
|
|
331
530
|
|
|
332
|
-
<AudioPlayer
|
|
333
|
-
playList={playList}
|
|
334
|
-
placement={placement}
|
|
335
|
-
activeUI={activeUI}
|
|
336
|
-
>
|
|
531
|
+
<AudioPlayer playList={playList} placement={placement} activeUI={activeUI}>
|
|
337
532
|
<AudioPlayer.CustomComponent id="playerCustomComponent">
|
|
338
533
|
<CustomComponent />
|
|
339
534
|
</AudioPlayer.CustomComponent>
|
|
340
|
-
</AudioPlayer
|
|
535
|
+
</AudioPlayer>;
|
|
341
536
|
```
|
|
342
537
|
|
|
538
|
+
# **Example**
|
|
343
539
|
|
|
344
|
-
|
|
345
|
-
# ****Example****
|
|
346
540
|
```tsx
|
|
347
541
|
function App() {
|
|
348
542
|
return (
|