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 witharia-label). The buttons are named Play / Pause, Mute / Unmute (witharia-pressed), Previous, Next and Fullscreen; the sliders Seek (with the time asaria-valuetext) and Volume. - Shortcuts while focus is inside the controls:
Kplays or pauses,Mmutes, ← 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. |