Skip to content
FrameworkStyle

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.

The HTML trigger can target the popup with commandfor. An immediately adjacent trigger is linked automatically when neither element has an authored ID.

Styling

The popup reflects data-availability="available" while it can render volume controls. HTML also receives native hidden and data-hidden when it cannot.

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 volume availability and the popover interaction lifecycle.

Props

PropTypeDefaultDetails
align'start' | 'center' | 'end'
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'
availabilityMediaFeatureAvailability
hiddenboolean

Data attributes

AttributeTypeDetails
data-open
data-side'top' | 'bottom' | 'left' | 'right'
data-align'start' | 'center' | 'end'
data-starting-style
data-ending-style
data-availabilityMediaFeatureAvailability
data-hidden

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

PropTypeDefaultDetails
classNamestring | ((state: PopoverState) => string | undefined)
renderReactElement | ((props: HTMLProps, state: PopoverState) => ReactElement | null)
styleCSSProperties | ((state: PopoverState) => CSSProperties | undefined)

Trigger

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

Props

PropTypeDefaultDetails
classNamestring | ((state: PopoverState) => string | undefined)
renderReactElement | ((props: HTMLProps, state: PopoverState) => ReactElement | null)
styleCSSProperties | ((state: PopoverState) => CSSProperties | undefined)