1.4.0-rc.2 • Published 1 year ago

react-modern-audio-player v1.4.0-rc.2

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

DEMO

https://codesandbox.io/s/basic-91y82y?file=/src/App.tsx

**Flexible and Customizable UI**

This can offer waveform by wavesurfer.js

This can offer various UI and you can also customize each component position

Full View

Position Change

Particular View

**Installation**

npm install --save react-modern-audio-player

**Quick Start**

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

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
}
PropTypeDefault
playListPlayList
audioInitialStateInitialStatesisPlaying: false repeatType: "ALL" volume: 1
activeUIActiveUIplayButton : true
customIconsCustomIconsundefined
coverImgsCssCoverImgsCssundefined
placementPlacementplayListPlacement : "bottom" interfacePlacement :DefaultInterfacePlacement
rootContainerPropsRootContainerPropstheme: spectrum-theme-defaultwidth: 100% position: 'static'UNSAFE_className: rm-audio-player-provider

PlayList

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

type InitialStates = Omit<
  React.AudioHTMLAttributes<HTMLAudioElement>,
  "autoPlay"
> & {
	isPlaying?: boolean;
  repeatType?: RepeatType;
  volume?: number;
  currentTime?: number;
  duration?: number;
  curPlayId: number;
};

ActiveUI

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

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

interface CoverImgsCss {
  artwork?: React.CSSProperties;
  listThumbnail?: React.CSSProperties;
}

Placement

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

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 https://react-spectrum.adobe.com/react-spectrum/Provider.html#themes

Override Style

Theme mode ( dark-mode )

it apply dark-mode depending on system-theme 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

--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 you can also set viewProps to CustomComponent (https://react-spectrum.adobe.com/react-spectrum/View.html#props)

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**

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>
  );
}
1.4.0-rc.2

1 year ago

1.4.0-rc.1

1 year ago

1.2.5

2 years ago

1.2.4

2 years ago

1.2.3

2 years ago

1.3.0

2 years ago

1.4.0-rc.0

1 year ago

1.2.0

2 years ago

1.1.5

2 years ago

1.1.4

2 years ago

1.2.2

2 years ago

1.1.3

2 years ago

1.2.1

2 years ago

1.1.2

2 years ago

1.1.1

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago