Skip to content

Commit e67fe0c

Browse files
committed
add i18n support to aria labels
1 parent ebf5690 commit e67fe0c

File tree

5 files changed

+50
-11
lines changed

5 files changed

+50
-11
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* Audio player component that provides consistent UI/UX on different browsers.
2020
* Super customizable layout
2121
* Flexbox css with SVG icons. Mobile friendly.
22-
* Accessibility supported, keyboards events supported.
22+
* I18n and a11y supported, keyboards events supported.
2323
* Support Media Source Extensions (MSE) and Encrypted Media Extensions (EME)
2424
* Written in TypeScript.
2525

@@ -120,6 +120,7 @@ The `controls` attribute defaults to `false` and should never be changed to `tru
120120
| 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 |
121121
| 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 |
122122
| 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 |
123+
| i18nAriaLabels | Object | I18nAriaLabels | A configuration object to overwrite the default `aria-label` on the action buttons |
123124
| 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) |
124125
| mse.srcDuration | number | - | The complete duration of the MSE audio chunks together (this is a key of the _mse_ prop) |
125126
| mse.onSeek | Function (Event) | - | The callback to be used when seek happens (this is a key of the _mse_ prop) |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-h5-audio-player",
3-
"version": "3.7.4",
3+
"version": "3.8.0",
44
"description": "A customizable React audio player. Written in TypeScript. Mobile compatible. Keyboard friendly",
55
"main": "./lib/index.js",
66
"module": "./es/index.js",

src/ProgressBar.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ interface ProgressBarForwardRefProps {
1010
srcDuration?: number
1111
onSeek?: OnSeek
1212
onChangeCurrentTimeError?: () => void
13+
i18nProgressBar: string
1314
}
1415
interface ProgressBarProps extends ProgressBarForwardRefProps {
1516
progressBar: React.RefObject<HTMLDivElement>
@@ -209,14 +210,14 @@ class ProgressBar extends Component<ProgressBarProps, ProgressBarState> {
209210
}
210211

211212
render(): React.ReactNode {
212-
const { showDownloadProgress, showFilledProgress, progressBar } = this.props
213+
const { showDownloadProgress, showFilledProgress, progressBar, i18nProgressBar } = this.props
213214
const { currentTimePos, downloadProgressArr, hasDownloadProgressAnimation } = this.state
214215

215216
return (
216217
<div
217218
className="rhap_progress-container"
218219
ref={progressBar}
219-
aria-label="Audio Progress Control"
220+
aria-label={i18nProgressBar}
220221
role="progressbar"
221222
aria-valuemin={0}
222223
aria-valuemax={100}

src/VolumeBar.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ interface VolumeControlsProps {
66
volume: number
77
onMuteChange: () => void
88
showFilledVolume: boolean
9+
i18nVolumeControl: string
910
}
1011

1112
interface VolumeControlsState {
@@ -164,7 +165,7 @@ class VolumeControls extends Component<VolumeControlsProps, VolumeControlsState>
164165
}
165166

166167
render(): React.ReactNode {
167-
const { audio, showFilledVolume } = this.props
168+
const { audio, showFilledVolume, i18nVolumeControl } = this.props
168169
const { currentVolumePos, hasVolumeAnimation } = this.state
169170

170171
const { volume } = audio || {}
@@ -175,7 +176,7 @@ class VolumeControls extends Component<VolumeControlsProps, VolumeControlsState>
175176
onTouchStart={this.handleVolumnControlMouseOrTouchDown}
176177
onContextMenu={this.handleContextMenu}
177178
role="progressbar"
178-
aria-label="volume Control"
179+
aria-label={i18nVolumeControl}
179180
aria-valuemin={0}
180181
aria-valuemax={100}
181182
aria-valuenow={Number((volume * 100).toFixed(0))}

src/index.tsx

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ interface PlayerProps {
117117
customControlsSection?: CustomUIModules
118118
customAdditionalControls?: CustomUIModules
119119
customVolumeControls?: CustomUIModules
120+
i18nAriaLabels?: I18nAriaLabels
120121
children?: ReactNode
121122
style?: CSSProperties
122123
}
@@ -134,6 +135,22 @@ interface CustomIcons {
134135
volumeMute?: ReactNode
135136
}
136137

138+
interface I18nAriaLabels {
139+
player?: string
140+
progressControl?: string
141+
volumeControl?: string
142+
play?: string
143+
pause?: string
144+
rewind?: string
145+
forward?: string
146+
previous?: string
147+
next?: string
148+
loop?: string
149+
loopOff?: string
150+
volume?: string
151+
volumeMute?: string
152+
}
153+
137154
class H5AudioPlayer extends Component<PlayerProps> {
138155
static defaultProps: PlayerProps = {
139156
autoPlay: false,
@@ -163,6 +180,21 @@ class H5AudioPlayer extends Component<PlayerProps> {
163180
customVolumeControls: [RHAP_UI.VOLUME],
164181
layout: 'stacked',
165182
hasDefaultKeyBindings: true,
183+
i18nAriaLabels: {
184+
player: 'Audio player',
185+
progressControl: 'Audio progress control',
186+
volumeControl: 'Volume control',
187+
play: 'Play',
188+
pause: 'Pause',
189+
rewind: 'Rewind',
190+
forward: 'Forward',
191+
previous: 'Previous',
192+
next: 'Skip',
193+
loop: 'Disable loop',
194+
loopOff: 'Enable loop',
195+
volume: 'Mute',
196+
volumeMute: 'Unmute',
197+
},
166198
}
167199

168200
audio = createRef<HTMLAudioElement>()
@@ -356,6 +388,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
356388
volume: volumeProp,
357389
loop: loopProp,
358390
mse,
391+
i18nAriaLabels,
359392
} = this.props
360393

361394
switch (comp) {
@@ -393,6 +426,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
393426
onSeek={mse && mse.onSeek}
394427
onChangeCurrentTimeError={onChangeCurrentTimeError}
395428
srcDuration={mse && mse.srcDuration}
429+
i18nProgressBar={i18nAriaLabels.progressControl}
396430
/>
397431
)
398432
case RHAP_UI.DURATION:
@@ -423,7 +457,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
423457
<div key={key} className="rhap_main-controls">
424458
{showSkipControls && (
425459
<button
426-
aria-label="Previous"
460+
aria-label={i18nAriaLabels.previous}
427461
className="rhap_button-clear rhap_main-controls-button rhap_skip-button"
428462
type="button"
429463
onClick={onClickPrevious}
@@ -433,7 +467,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
433467
)}
434468
{showJumpControls && (
435469
<button
436-
aria-label="Rewind"
470+
aria-label={i18nAriaLabels.rewind}
437471
className="rhap_button-clear rhap_main-controls-button rhap_rewind-button"
438472
type="button"
439473
onClick={this.handleClickRewind}
@@ -442,7 +476,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
442476
</button>
443477
)}
444478
<button
445-
aria-label={isPlaying ? 'Pause' : 'Play'}
479+
aria-label={isPlaying ? i18nAriaLabels.pause : i18nAriaLabels.play}
446480
className="rhap_button-clear rhap_main-controls-button rhap_play-pause-button"
447481
type="button"
448482
onClick={this.togglePlay}
@@ -490,7 +524,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
490524
return (
491525
<button
492526
key={key}
493-
aria-label={loop ? 'Enable Loop' : 'Disable Loop'}
527+
aria-label={loop ? i18nAriaLabels.loop : i18nAriaLabels.loopOff}
494528
className="rhap_button-clear rhap_repeat-button"
495529
type="button"
496530
onClick={this.handleClickLoopButton}
@@ -523,6 +557,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
523557
volume={volume}
524558
onMuteChange={this.handleMuteChange}
525559
showFilledVolume={showFilledVolume}
560+
i18nVolumeControl={i18nAriaLabels.volumeControl}
526561
/>
527562
</div>
528563
)
@@ -684,6 +719,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
684719
customControlsSection,
685720
children,
686721
style,
722+
i18nAriaLabels,
687723
} = this.props
688724
const loop = this.audio.current ? this.audio.current.loop : loopProp
689725
const loopClass = loop ? 'rhap_loop--on' : 'rhap_loop--off'
@@ -696,7 +732,7 @@ class H5AudioPlayer extends Component<PlayerProps> {
696732
role="group"
697733
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
698734
tabIndex={0}
699-
aria-label="Audio Player"
735+
aria-label={i18nAriaLabels.player}
700736
className={`rhap_container ${loopClass} ${isPlayingClass} ${className}`}
701737
onKeyDown={this.handleKeyDown}
702738
ref={this.container}

0 commit comments

Comments
 (0)