Volume

A mute button and a slider for setting the volume.

import { Volume } from 'react-media-kit'
import { Volume } from 'react-media-kit'

<div className="volume">
  <Volume.Mute className="mute">Mute</Volume.Mute>
  <Volume.Slider className="volume-slider">
    <Volume.Track className="volume-track">
      <Volume.Progress className="volume-progress" />
      <Volume.Thumb className="volume-thumb" />
    </Volume.Track>
  </Volume.Slider>
</div>

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.

Anatomy

How the parts nest.

<Volume.Mute />
<Volume.Slider>
  <Volume.Track>
    <Volume.Progress />
    <Volume.Thumb />
  </Volume.Track>
</Volume.Slider>

API reference

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 attributeDescription
data-mutedThe 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.

PropTypeDefaultDescription
volumeIntervalnumber0.05Volume 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 attributeDescription
data-mutedThe media is muted.
data-draggingA pointer is pressed on the slider, for a click or a drag. Removed on release.
CSS variableDescription
--progress-percentThe 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 variableDescription
--seekbar-thumb-z-indexSets 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.

KeyAction
Left arrowDown arrowLower the volume by volumeInterval.
Right arrowUp arrowRaise the volume by volumeInterval.
HomeSet the volume to 0.
EndSet 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 attributeDescription
data-media-pendingLoading hasn’t started. This is the initial state.
data-media-loadingThe media has started loading.
data-media-metadata-loadedThe duration and dimensions are known, but there isn’t enough data to play yet.
data-media-playableThe media can play. It stays set if playback later stalls to buffer.
data-media-errorThe 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-unsupportedThe browser can’t go fullscreen, or support hasn’t been detected yet.
data-pip-unsupportedPicture-in-picture isn’t available, such as for audio, or support hasn’t been detected yet.
data-volume-change-unsupportedThe browser doesn’t let scripts set the volume, such as on iOS, or support hasn’t been detected yet.