Skip to content

Commit

Permalink
add i18n support to aria labels
Browse files Browse the repository at this point in the history
  • Loading branch information
lhz516 committed Nov 19, 2021
1 parent ebf5690 commit e67fe0c
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 11 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* Audio player component that provides consistent UI/UX on different browsers.
* Super customizable layout
* Flexbox css with SVG icons. Mobile friendly.
* Accessibility supported, keyboards events supported.
* I18n and a11y supported, keyboards events supported.
* Support Media Source Extensions (MSE) and Encrypted Media Extensions (EME)
* Written in TypeScript.

Expand Down Expand Up @@ -120,6 +120,7 @@ The `controls` attribute defaults to `false` and should never be changed to `tru
| customControlsSection | [Array<string \|<br>ReactElement>](https://github.com/lhz516/react-h5-audio-player/blob/fa1a61eb7f77146e1ce4547a14181279be68ecfd/src/index.tsx#L92) | [ADDITIONAL_CONTROLS,<br>MAIN_CONTROLS,<br>VOLUME_CONTROLS] | [Custom layout](https://static.hanzluo.com/react-h5-audio-player-storybook/index.html?path=/docs/layouts-advanced) of controls section |
| customAdditionalControls | [Array<string \|<br>ReactElement>](https://github.com/lhz516/react-h5-audio-player/blob/fa1a61eb7f77146e1ce4547a14181279be68ecfd/src/index.tsx#L93) | [LOOP] | [Custom layout](https://static.hanzluo.com/react-h5-audio-player-storybook/index.html?path=/docs/layouts-advanced) of additional controls |
| customVolumeControls | [Array<string \|<br>ReactElement>](https://github.com/lhz516/react-h5-audio-player/blob/fa1a61eb7f77146e1ce4547a14181279be68ecfd/src/index.tsx#L94) | [VOLUME] | [Custom layout](https://static.hanzluo.com/react-h5-audio-player-storybook/index.html?path=/docs/layouts-advanced) of volume controls |
| i18nAriaLabels | Object | I18nAriaLabels | A configuration object to overwrite the default `aria-label` on the action buttons |
| mse | Object | null | A configuration object so the player can play audio chunks, MSE streams and encrypted audio (See [section about Media Source Extensions](#media-source-extensions-and-encrypted-media-extensions) in this Readme) |
| mse.srcDuration | number | - | The complete duration of the MSE audio chunks together (this is a key of the _mse_ prop) |
| mse.onSeek | Function (Event) | - | The callback to be used when seek happens (this is a key of the _mse_ prop) |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-h5-audio-player",
"version": "3.7.4",
"version": "3.8.0",
"description": "A customizable React audio player. Written in TypeScript. Mobile compatible. Keyboard friendly",
"main": "./lib/index.js",
"module": "./es/index.js",
Expand Down
5 changes: 3 additions & 2 deletions src/ProgressBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface ProgressBarForwardRefProps {
srcDuration?: number
onSeek?: OnSeek
onChangeCurrentTimeError?: () => void
i18nProgressBar: string
}
interface ProgressBarProps extends ProgressBarForwardRefProps {
progressBar: React.RefObject<HTMLDivElement>
Expand Down Expand Up @@ -209,14 +210,14 @@ class ProgressBar extends Component<ProgressBarProps, ProgressBarState> {
}

render(): React.ReactNode {
const { showDownloadProgress, showFilledProgress, progressBar } = this.props
const { showDownloadProgress, showFilledProgress, progressBar, i18nProgressBar } = this.props
const { currentTimePos, downloadProgressArr, hasDownloadProgressAnimation } = this.state

return (
<div
className="rhap_progress-container"
ref={progressBar}
aria-label="Audio Progress Control"
aria-label={i18nProgressBar}
role="progressbar"
aria-valuemin={0}
aria-valuemax={100}
Expand Down
5 changes: 3 additions & 2 deletions src/VolumeBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ interface VolumeControlsProps {
volume: number
onMuteChange: () => void
showFilledVolume: boolean
i18nVolumeControl: string
}

interface VolumeControlsState {
Expand Down Expand Up @@ -164,7 +165,7 @@ class VolumeControls extends Component<VolumeControlsProps, VolumeControlsState>
}

render(): React.ReactNode {
const { audio, showFilledVolume } = this.props
const { audio, showFilledVolume, i18nVolumeControl } = this.props
const { currentVolumePos, hasVolumeAnimation } = this.state

const { volume } = audio || {}
Expand All @@ -175,7 +176,7 @@ class VolumeControls extends Component<VolumeControlsProps, VolumeControlsState>
onTouchStart={this.handleVolumnControlMouseOrTouchDown}
onContextMenu={this.handleContextMenu}
role="progressbar"
aria-label="volume Control"
aria-label={i18nVolumeControl}
aria-valuemin={0}
aria-valuemax={100}
aria-valuenow={Number((volume * 100).toFixed(0))}
Expand Down
46 changes: 41 additions & 5 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ interface PlayerProps {
customControlsSection?: CustomUIModules
customAdditionalControls?: CustomUIModules
customVolumeControls?: CustomUIModules
i18nAriaLabels?: I18nAriaLabels
children?: ReactNode
style?: CSSProperties
}
Expand All @@ -134,6 +135,22 @@ interface CustomIcons {
volumeMute?: ReactNode
}

interface I18nAriaLabels {
player?: string
progressControl?: string
volumeControl?: string
play?: string
pause?: string
rewind?: string
forward?: string
previous?: string
next?: string
loop?: string
loopOff?: string
volume?: string
volumeMute?: string
}

class H5AudioPlayer extends Component<PlayerProps> {
static defaultProps: PlayerProps = {
autoPlay: false,
Expand Down Expand Up @@ -163,6 +180,21 @@ class H5AudioPlayer extends Component<PlayerProps> {
customVolumeControls: [RHAP_UI.VOLUME],
layout: 'stacked',
hasDefaultKeyBindings: true,
i18nAriaLabels: {
player: 'Audio player',
progressControl: 'Audio progress control',
volumeControl: 'Volume control',
play: 'Play',
pause: 'Pause',
rewind: 'Rewind',
forward: 'Forward',
previous: 'Previous',
next: 'Skip',
loop: 'Disable loop',
loopOff: 'Enable loop',
volume: 'Mute',
volumeMute: 'Unmute',
},
}

audio = createRef<HTMLAudioElement>()
Expand Down Expand Up @@ -356,6 +388,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
volume: volumeProp,
loop: loopProp,
mse,
i18nAriaLabels,
} = this.props

switch (comp) {
Expand Down Expand Up @@ -393,6 +426,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
onSeek={mse && mse.onSeek}
onChangeCurrentTimeError={onChangeCurrentTimeError}
srcDuration={mse && mse.srcDuration}
i18nProgressBar={i18nAriaLabels.progressControl}
/>
)
case RHAP_UI.DURATION:
Expand Down Expand Up @@ -423,7 +457,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
<div key={key} className="rhap_main-controls">
{showSkipControls && (
<button
aria-label="Previous"
aria-label={i18nAriaLabels.previous}
className="rhap_button-clear rhap_main-controls-button rhap_skip-button"
type="button"
onClick={onClickPrevious}
Expand All @@ -433,7 +467,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
)}
{showJumpControls && (
<button
aria-label="Rewind"
aria-label={i18nAriaLabels.rewind}
className="rhap_button-clear rhap_main-controls-button rhap_rewind-button"
type="button"
onClick={this.handleClickRewind}
Expand All @@ -442,7 +476,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
</button>
)}
<button
aria-label={isPlaying ? 'Pause' : 'Play'}
aria-label={isPlaying ? i18nAriaLabels.pause : i18nAriaLabels.play}
className="rhap_button-clear rhap_main-controls-button rhap_play-pause-button"
type="button"
onClick={this.togglePlay}
Expand Down Expand Up @@ -490,7 +524,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
return (
<button
key={key}
aria-label={loop ? 'Enable Loop' : 'Disable Loop'}
aria-label={loop ? i18nAriaLabels.loop : i18nAriaLabels.loopOff}
className="rhap_button-clear rhap_repeat-button"
type="button"
onClick={this.handleClickLoopButton}
Expand Down Expand Up @@ -523,6 +557,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
volume={volume}
onMuteChange={this.handleMuteChange}
showFilledVolume={showFilledVolume}
i18nVolumeControl={i18nAriaLabels.volumeControl}
/>
</div>
)
Expand Down Expand Up @@ -684,6 +719,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
customControlsSection,
children,
style,
i18nAriaLabels,
} = this.props
const loop = this.audio.current ? this.audio.current.loop : loopProp
const loopClass = loop ? 'rhap_loop--on' : 'rhap_loop--off'
Expand All @@ -696,7 +732,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
role="group"
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
tabIndex={0}
aria-label="Audio Player"
aria-label={i18nAriaLabels.player}
className={`rhap_container ${loopClass} ${isPlayingClass} ${className}`}
onKeyDown={this.handleKeyDown}
ref={this.container}
Expand Down

0 comments on commit e67fe0c

Please sign in to comment.