MediaControls

Transport controls for any media source: play/pause, seek bar, time, mute and volume, plus optional previous/next and fullscreen. They only report what the user does, so they drive a video, an audio file, a YouTube player or a speaker in another room alike.

import { MediaControls } from 'jarvis-react-ui';

Basic

MediaControls is fully controlled: pass playing, currentTime, duration, volume and muted from your player and handle the callbacks. onSeek fires once when a drag on the seek bar ends, so a player is not flooded with seeks while dragging; the time readout follows the drag meanwhile. Buttons for previous, next and fullscreen appear when you pass their handler.

import { useEffect, useState } from 'react';
import { MediaControls } from 'jarvis-react-ui';

const DURATION = 214;

export default function Basic() {
    const [playing, setPlaying] = useState(false);
    const [time, setTime] = useState(37);
    const [volume, setVolume] = useState(0.7);
    const [muted, setMuted] = useState(false);

    // Stands in for a real player: advances the time while "playing".
    useEffect(() => {
        if (!playing) return;
        const id = setInterval(() => setTime((t) => Math.min(DURATION, t + 1)), 1000);
        return () => clearInterval(id);
    }, [playing]);

    return (
        <MediaControls
            title="Mission briefing · 03"
            playing={playing}
            currentTime={time}
            duration={DURATION}
            volume={volume}
            muted={muted}
            onPlayPause={() => setPlaying(!playing)}
            onSeek={setTime}
            onVolumeChange={setVolume}
            onMutedChange={setMuted}
            onPrevious={() => setTime(0)}
            onNext={() => setTime(DURATION)}
        />
    );
}

Live and minimal

A duration of 0, NaN or Infinity means unknown or live: the seek bar is disabled and LIVE replaces the total time. Without onVolumeChange and onMutedChange the volume controls are hidden.

import { useState } from 'react';
import { MediaControls } from 'jarvis-react-ui';

export default function Live() {
    const [playing, setPlaying] = useState(true);

    return (
        <MediaControls
            size="sm"
            aria-label="Radio controls"
            playing={playing}
            currentTime={0}
            duration={Infinity}
            onPlayPause={() => setPlaying(!playing)}
        />
    );
}

For a ready-made player use MediaPlayer (video and audio files) or YouTubePlayer.

Sound

The buttons play hover_button and click; dragging a slider plays drag_start and drag_end, through the nearest SfxProvider. See Sound effects.

Accessibility

  • The controls are a role="group" named Media controls (change it with aria-label). The buttons are named Play / Pause, Mute / Unmute (with aria-pressed), Previous, Next and Fullscreen; the sliders Seek (with the time as aria-valuetext) and Volume.
  • Shortcuts while focus is inside the controls: K plays or pauses, M mutes, ← and → seek 5 seconds. Keys a focused slider uses itself are left to it.

API

Prop Type Default Description
currentTime (required) number Playback position in seconds.
duration (required) number Length in seconds. 0, NaN or Infinity (unknown or live) disables the seek bar and shows LIVE instead of the total time.
onPlayPause (required) () => void Called when the play/pause button is pressed (or K while the controls have focus).
playing (required) boolean Whether the media is playing; switches the play/pause button.
aria-label string Media controls Accessible name of the controls group.
className string Additional class names for the root role="group" element.
disabled boolean false Disables all controls, e.g. while the media is loading.
muted boolean false Whether the sound is muted; switches the mute button.
onFullscreen (() => void) Shows a fullscreen button.
onMutedChange ((muted: boolean) => void) Called with the new muted state (mute button or M). Hides the mute button if omitted.
onNext (() => void) Shows a next-track button.
onPrevious (() => void) Shows a previous-track button.
onSeek ((time: number) => void) Called with the target time in seconds when the user seeks: at the end of a drag on the seek bar, on its arrow keys, or with ←/→ (±5 s) while the controls have focus.
onVolumeChange ((volume: number) => void) Called with the new volume (0–1) while the volume slider moves. Hides the slider if omitted.
size 'sm' | 'md' 'md' Button and text size.
title ReactNode Title shown above the controls, e.g. the track name.
volume number 1 Volume from 0 to 1.