Render these inside Player.Root, next to a Media.Video or Media.Audio.
If your CSS hides the slider with [data-volume-change-unsupported], it appears a moment after the other controls: the attribute stays set until support has been detected.
Parts accept the attributes of the element they render, plus a ref, except where noted. Every part that renders an element also sets the media state attributes. Passing aria-label replaces a default label.
Volume.Mute
renders <button>
Mutes and unmutes the media. Its aria-label is "Mute video", or "Unmute video" while muted.
Data attribute
Description
data-muted
The media is muted.
Your onClick runs before the built-in one; call event.preventDefault() in it to skip the built-in behavior.
Volume.Slider
renders <div role="slider">
The interactive volume slider. Click, drag or use the keyboard to set the volume. Changing the volume also unmutes.
It can take keyboard focus and keeps aria-valuenow and aria-valuetext up to date. Its default aria-label is "Video volume slider". While muted, its value is 0. It is always position: relative; touch-action: none.
Prop
Type
Default
Description
volumeInterval
number
0.05
Volume change per arrow key press. Above 0 and up to 1. Anything else throws a ReactMediaKitError.
computeAriaValueText
({ volume, isMuted }) => string
—
Builds the aria-valuetext. It receives the actual volume, even while muted, and the mute state. The default is a percentage with two decimals, such as "50.00%", or "0.00%" while muted.
Data attribute
Description
data-muted
The media is muted.
data-dragging
A pointer is pressed on the slider, for a click or a drag. Removed on release.
CSS variable
Description
--progress-percent
The volume shown on the slider, as a plain number from 0 to 100, such as 42.50. Use calc(var(--progress-percent) * 1%) to turn it into a percentage length. The parts inside use it.
Your onKeyDown, onPointerDown, onPointerMove and onLostPointerCapture handlers run before the built-in ones; call event.preventDefault() in one to skip its built-in behavior.
Volume.Track
renders <div>
The rail, inside Volume.Slider. It holds Volume.Progress and Volume.Thumb, and follows the same rules as Seekbar.Track: give it a size, but don’t change its position.
Volume.Progress
renders <div>
The filled part, inside Volume.Track. Its width follows --progress-percent. It is position: absolute; height: 100% with an inline width, so don’t set those in CSS.
Volume.Thumb
renders <div>
The handle at the current position. It sits inside a full-size wrapper that moves it along the track with --progress-percent. className, ref and other <div> attributes are applied to the thumb itself.
The thumb is centered with an inline transform, so a transform in your CSS has no effect. Use scale, translate or rotate instead. The wrapper ignores pointer events, and the thumb inherits that.
CSS variable
Description
--seekbar-thumb-z-index
Sets the z-index of the wrapper around the thumb. Defaults to 9999. The name is shared with the seekbar thumb.
Keyboard interactions
Active while the volume slider has focus.
Key
Action
←Left arrow↓Down arrow
Lower the volume by volumeInterval.
→Right arrow↑Up arrow
Raise the volume by volumeInterval.
Home
Set the volume to 0.
End
Set the volume to 1.
Media state attributes
Five of these describe loading, and exactly one of them is set at a time. The other three mark features the browser lacks. Use them to hide controls that can’t work, or to style the player while it loads.
Data attribute
Description
data-media-pending
Loading hasn’t started. This is the initial state.
data-media-loading
The media has started loading.
data-media-metadata-loaded
The duration and dimensions are known, but there isn’t enough data to play yet.
data-media-playable
The media can play. It stays set if playback later stalls to buffer.
data-media-error
The media element reported an error, such as a network or decoding failure. A blocked play() call doesn’t set it; use onError for that.
data-fullscreen-unsupported
The browser can’t go fullscreen, or support hasn’t been detected yet.
data-pip-unsupported
Picture-in-picture isn’t available, such as for audio, or support hasn’t been detected yet.
data-volume-change-unsupported
The browser doesn’t let scripts set the volume, such as on iOS, or support hasn’t been detected yet.