UNPKG

react-modern-audio-player

Version:

<p align="center"> <img width="20%" src="https://user-images.githubusercontent.com/70849655/180391190-2b268d23-c9f3-4e95-9fce-090897842c04.png" alt="rm-audio-player" /> <h1 align="center">React Modern Audio Player</h1> </p>

378 lines (319 loc) 10 kB
<p align="center"> <img width="20%" src="https://user-images.githubusercontent.com/70849655/180391190-2b268d23-c9f3-4e95-9fce-090897842c04.png" alt="rm-audio-player" /> <h1 align="center">React Modern Audio Player</h1> </p> <p align="center"> <a href="https://github.com/slash9494/react-modern-audio-player/blob/main/package/LICENSE"> <img src="https://img.shields.io/npm/l/react-modern-audio-player" alt="License"> </a> <a href="https://www.npmjs.com/package/react-modern-audio-player"> <img src="https://img.shields.io/npm/v/react-modern-audio-player" alt="Version"> </a> <a href="https://www.npmjs.com/package/react-modern-audio-player"> <img src="https://img.shields.io/npm/dt/react-modern-audio-player" alt="Download"> </a> <a href="https://bundlephobia.com/package/react-modern-audio-player@0.0.3"> <img src="https://img.shields.io/bundlephobia/minzip/react-modern-audio-player" alt="BundleSize"> </a> </p> ## DEMO https://codesandbox.io/s/basic-91y82y?file=/src/App.tsx # ****Flexible and Customizable UI**** ## This can offer waveform by `wavesurfer.js` <img width="100%" src="https://user-images.githubusercontent.com/70849655/180435472-f043dbb4-54df-43e0-bc5c-67492510e817.png" alt=""> ## This can offer various UI and you can also customize each component position > Full View > <img width="100%" src="https://user-images.githubusercontent.com/70849655/180435489-263fae23-f066-4a37-a524-58918eb40b0c.png" alt=""> > Position Change > <img width="110%" src="https://user-images.githubusercontent.com/70849655/180435493-2c2e08c5-b67b-4ab7-aded-5a0403d42050.png" alt=""> > Particular View > </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=""> # ****Installation**** ```tsx npm install --save react-modern-audio-player ``` # ****Quick Start**** ```tsx import AudioPlayer from 'react-modern-audio-player'; const playList = [ { name: 'name', writer: 'writer', img: 'image.jpg', src: 'audio.mp3', id: 1, }, ] function Player (){ return ( <AudioPlayer playList={playList} /> ) } ``` # Props ```tsx interface AudioPlayerProps { playList: PlayList; audioInitialState?: InitialStates; audioRef?: React.MutableRefObject<HTMLAudioElement>; activeUI?: ActiveUI; customIcons?: CustomIcons; coverImgsCss?: CoverImgsCss; placement?: { player?: PlayerPlacement; playList?: PlayListPlacement; interface?: InterfacePlacement; volumeSlider?: VolumeSliderPlacement; }; rootContainerProps?: RootContainerProps } ``` Prop | Type | Default --- | --- | --- `playList` | [PlayList](#playlist) | [ ] `audioInitialState` | [InitialStates](#InitialStates) | isPlaying: false </br>repeatType: "ALL" </br>volume: 1 `activeUI` | [ActiveUI](#activeui) | playButton : true `customIcons` | [CustomIcons](#customicons) | undefined `coverImgsCss` | [CoverImgsCss](#coverimgscss) | undefined `placement` | [Placement](#placement) | playListPlacement : "bottom" </br>interfacePlacement :[DefaultInterfacePlacement](#default-interface-placement) `rootContainerProps` | [RootContainerProps](#rootcontainerprops) | theme: spectrum-theme-default<br/>width: 100% <br/>position: 'static'<br/>UNSAFE_className: rm-audio-player-provider ## PlayList ```tsx type PlayList = Array<AudioData>; type AudioData = { src: string; id: number; name?: string | ReactNode; writer?: string | ReactNode; img?: string; description?: string | ReactNode; customTrackInfo?: string | ReactNode; }; ``` ## InitialStates ```tsx type InitialStates = Omit< React.AudioHTMLAttributes<HTMLAudioElement>, "autoPlay" > & { isPlaying?: boolean; repeatType?: RepeatType; volume?: number; currentTime?: number; duration?: number; curPlayId: number; }; ``` ## ActiveUI ```tsx type ActiveUI = { all: boolean; playButton: boolean; playList: PlayListUI; prevNnext: boolean; volume: boolean; volumeSlider: boolean; repeatType: boolean; trackTime: boolean; trackInfo: boolean; artwork: boolean; progress: ProgressUI; }; type ProgressUI = "waveform" | "bar" | false; type PlayListUI = "sortable" | "unSortable" | false; ``` ## CustomIcons ```tsx type CustomIcons = { play: ReactNode; pause: ReactNode; prev: ReactNode; next: ReactNode; repeatOne: ReactNode; repeatAll: ReactNode; repeatNone: ReactNode; repeatShuffle: ReactNode; volumeFull: ReactNode; volumeHalf: ReactNode; volumeMuted: ReactNode; playList: ReactNode; }; ``` ## CoverImgsCss ```tsx interface CoverImgsCss { artwork?: React.CSSProperties; listThumbnail?: React.CSSProperties; } ``` ## Placement ```tsx type PlayerPlacement = | "bottom" | "top" | "bottom-left" | "bottom-right" | "top-left" | "top-right"; type VolumeSliderPlacement = "bottom" | "top" | 'left' | 'right'; type PlayListPlacement = "bottom" | "top"; type InterfacePlacement = { templateArea?: InterfaceGridTemplateArea; customComponentsArea?: InterfaceGridCustomComponentsArea<TMaxLength>; itemCustomArea?: InterfaceGridItemArea; }; type InterfacePlacementKey = | Exclude<keyof ActiveUI, "all" | "prevNnext" | "trackTime"> | "trackTimeCurrent" | "trackTimeDuration"; type InterfacePlacementValue = "row1-1" | "row1-2" | "row1-3" | "row1-4" | ... more ... | "row9-9" /** if you apply custom components, values must be "row1-1" ~ any more */ type InterfaceGridTemplateArea = Record<InterfacePlacementKey,InterfacePlacementValue>; type InterfaceGridCustomComponentsArea = Record<componentId,InterfacePlacementValue>; type InterfaceGridItemArea = Partial<Record<InterfacePlacementKey, string>>; /** example * progress : 2-4 * repeatBtn : row1-4 / 2 / row1-4 / 10 * * check MDN - grid area * https://developer.mozilla.org/ko/docs/Web/CSS/grid-area */ ``` ### Default interface placement ```tsx const defaultInterfacePlacement = { templateArea: { artwork: "row1-1", trackInfo: "row1-2", trackTimeCurrent: "row1-3", trackTimeDuration: "row1-4", progress: "row1-5", repeatType: "row1-6", volume: "row1-7", playButton: "row1-8", playList: "row1-9", }, }; ``` ## RootContainerProps > it is same with spectrum provider props > </br> > https://react-spectrum.adobe.com/react-spectrum/Provider.html#themes # Override Style ### Theme mode ( dark-mode ) > it apply dark-mode depending on `system-theme` > </br> > you can customize color-theme by `css-variable` of `react-spectrum` `theme-default` ## ID & Classnames ### root ID - rm-audio-player ### root ClassName - rm-audio-player-provider ### color variables ```tsx --rm-audio-player-interface-container:var(--spectrum-global-color-gray-100); --rm-audio-player-volume-background: #ccc; --rm-audio-player-volume-panel-background:#f2f2f2; --rm-audio-player-volume-panel-border:#ccc; --rm-audio-player-volume-thumb: #d3d3d3; --rm-audio-player-volume-fill:rgba(0, 0, 0, 0.5); --rm-audio-player-volume-track:#ababab; --rm-audio-player-track-current-time:#0072F5; --rm-audio-player-track-duration:#8c8c8c; --rm-audio-player-progress-bar:#0072F5; --rm-audio-player-progress-bar-background:#D1D1D1; --rm-audio-player-waveform-cursor:var(--spectrum-global-color-gray-800); --rm-audio-player-waveform-background:var(--rm-audio-player-progress-bar-background); --rm-audio-player-waveform-bar:var(--rm-audio-player-progress-bar); --rm-audio-player-sortable-list:var(--spectrum-global-color-gray-200); --rm-audio-player-sortable-list-button-active:#0072F5; --rm-audio-player-selected-list-item-background:var(--spectrum-global-color-gray-500); // ...spectrum theme palette and so on... // ``` # Custom Component > you can apply custom component to `AudioPlayer` by `CustomComponent` > </br> > you can also set `viewProps` to `CustomComponent` > </br> > (https://react-spectrum.adobe.com/react-spectrum/View.html#props) ``` tsx const activeUI: ActiveUI = { all: true, }; const placement = { interface: { customComponentsArea: { playerCustomComponent: "row1-10", }, } as InterfacePlacement<11>, /** * you should set generic value of `InterfacePlacement` as interfaces max length for auto-complete aria type such as "row-1-10" * generic value must plus 1 than interfaces length because of 0 index */ }; /** you can get audioPlayerState by props */ const CustomComponent = ({ audioPlayerState, }: { audioPlayerState?: AudioPlayerStateContext; }) => { const audioEl = audioPlayerState?.elementRefs?.audioEl; const handOverTime = () => { if (audioEl) { audioEl.currentTime += 30; } }; return ( <> <button onClick={handOverTime}>+30</button> </> ); }; <AudioPlayer playList={playList} placement={placement} activeUI={activeUI} > <AudioPlayer.CustomComponent id="playerCustomComponent"> <CustomComponent /> </AudioPlayer.CustomComponent> </AudioPlayer> ``` # ****Example**** ```tsx function App() { return ( <div> <AudioPlayer playList={playList} audioInitialState={{ muted: true, volume: 0.2, curPlayId: 1, }} placement={{ interface: { templateArea: { trackTimeDuration: "row1-5", progress: "row1-4", playButton: "row1-6", repeatType: "row1-7", volume: "row1-8", }, }, player: "bottom-left", }} activeUI={{ all: true, progress: "waveform", }} /> </div> ); } ```