Skip to content

ReferenceMenus

VolumePopover

A volume-aware popover that keeps mute available when volume level controls are unavailable

Import

import { VolumePopover } from '@videojs/react';

Anatomy

<VolumePopover.Root>
  <VolumePopover.Trigger render={<MuteButton />} />
  <VolumePopover.Popup>
    <VolumeSlider.Root />
  </VolumePopover.Popup>
</VolumePopover.Root>

Behavior

VolumePopover combines popover behavior with volume availability. When volume level controls are unavailable, it closes and omits the popup while keeping the mute trigger rendered. This lets media with fixed volume keep mute control without exposing a nonfunctional slider.

Styling

The popup reflects data-availability="available" while it can render volume controls.

React renders the popup as a standard <div>. Add a className to select it:

.volume-popup[data-open] {
  opacity: 1;
}

Accessibility

The trigger receives aria-haspopup, aria-expanded, and aria-controls while the volume popup is available. When only mute is available, the trigger keeps the mute button’s own accessible name and behavior without popup ARIA.

Examples

Basic usage

import { Container, createPlayer, MuteButton, VolumePopover, VolumeSlider } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';

const { Player } = createPlayer({ features: videoFeatures });

export default function BasicUsage() {
  return (
    <Player>
      <Container className="react-volume-popover-basic">
        <Video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoPlay muted playsInline loop />
        <div className="react-volume-popover-basic__controls">
          <VolumePopover.Root openOnHover side="top">
            <VolumePopover.Trigger
              className="react-volume-popover-basic__trigger"
              render={
                <MuteButton render={(props, state) => <button {...props}>{state.muted ? 'Unmute' : 'Mute'}</button>} />
              }
            />
            <VolumePopover.Popup className="react-volume-popover-basic__popup">
              <VolumeSlider.Root orientation="vertical" className="react-volume-popover-basic__slider">
                <VolumeSlider.Track className="react-volume-popover-basic__track">
                  <VolumeSlider.Fill className="react-volume-popover-basic__fill" />
                </VolumeSlider.Track>
                <VolumeSlider.Thumb className="react-volume-popover-basic__thumb" />
              </VolumeSlider.Root>
            </VolumePopover.Popup>
          </VolumePopover.Root>
        </div>
      </Container>
    </Player>
  );
}

API Reference

Root

Owns the popover interaction lifecycle and provides volume availability to the parts.

Props

PropTypeDefaultDetails
align'start' | 'center' | 'end'—
boundary'viewport' | 'container' | string & {}—
closeDelaynumber—
closeOnEscapeboolean—
closeOnOutsideClickboolean—
defaultOpenboolean—
delaynumber—
modalboolean | 'trap-focus'—
openboolean—
openOnHoverboolean—
side'top' | 'bottom' | 'left' | 'right'—

State

State is accessible via the render, className, and style props.

PropertyTypeDetails
transitionStartingboolean
transitionEndingboolean
openboolean
status'idle' | 'starting' | 'ending'
side'top' | 'bottom' | 'left' | 'right'
align'start' | 'center' | 'end'
modalboolean | 'trap-focus'
availability'available' | 'unavailable' | 'unsupp...
hiddenboolean

Data attributes

AttributeTypeDetails
data-open—
data-side'top' | 'bottom' | 'left' | 'right'
data-align'start' | 'center' | 'end'
data-starting-style—
data-ending-style—
data-availability'available' | 'unavailable' | 'unsupp...
data-hidden—

Positioned volume content. Omitted when volume level controls are unavailable.

PropTypeDefaultDetails
classNamestring | function—
renderReactElement | function—
styleCSSProperties | function—

Trigger

Opens the volume popup, or renders its mute-button fallback when volume level controls are unavailable.

Props

PropTypeDefaultDetails
classNamestring | function—
renderReactElement | function—
styleCSSProperties | function—