Auto-hide
Hides the controls when the viewer isn't using them.
import { idle } from "react-video-kit/idle";Adds 667 B to a player790 B on its ownSource
The idle plugin hides the controls during playback, and brings them back when the viewer moves the mouse, taps, or uses the keyboard. Press the play button in the middle of the video below and leave the mouse still: the label in the corner changes to hidden after 3 seconds. Move the mouse off the player and it takes 0.8 seconds. Pause, or open the settings menu, and the controls stay up.
Controls: shown. Video: paused.
"use client";import { useVideoState } from "react-video-kit";import { idle } from "react-video-kit/idle";import { VideoPlayer } from "react-video-kit/player";import { speed } from "react-video-kit/speed";// Speed is here so there's a settings menu to open.const plugins = [idle(), speed()];function ControlsLabel() { const visible = useVideoState(idle, (state) => state.visible); const paused = useVideoState((media) => media.paused); return ( <p className="pointer-events-none absolute top-3 left-1/2 -translate-x-1/2 rounded-full bg-black/45 px-3 py-1 text-xs whitespace-nowrap text-white backdrop-blur-md"> Controls: {visible ? "shown" : "hidden"}. Video: {paused ? "paused" : "playing"}. </p> );}export default function Idle() { return ( <VideoPlayer src="/media/sample-720.mp4" poster="/media/poster.jpg" plugins={plugins} load="visible"> <ControlsLabel /> </VideoPlayer> );}Usage
import { idle } from "react-video-kit/idle";import { VideoPlayer } from "react-video-kit/player";const plugins = [idle()];<VideoPlayer src="/video.mp4" plugins={plugins} />;Without this plugin, the controls never hide. To change how long they wait, pass any of the three timeouts, in milliseconds:
idle({ mouseTimeout: 5000, touchTimeout: 6000, leaveTimeout: 300 });When the controls hide
During playback, the controls hide:
- 3 seconds (
mouseTimeout) after the last mouse movement over the player, the last key press inside it, or keyboard focus moving inside it. The same wait starts when playback starts or resumes, and when a timeline drag ends. - 0.8 seconds (
leaveTimeout) after the mouse leaves the player. - 4 seconds (
touchTimeout) after a touch brings them back. - At once when the viewer taps outside the controls while they're showing.
What keeps them up
The plugin won't hide the controls while any of these is true:
- The video is paused or has ended.
- Playback has failed with an error.
- The viewer is dragging the timeline.
- The mouse is over the controls.
- A control has keyboard focus.
- A menu is open.
- The video is casting to a Chromecast.
The first three bring hidden controls back at once. The others only stop a hide: when one comes due and something's still in use, the plugin looks again every mouseTimeout. So after a menu closes, the controls can take up to 3 seconds to hide.
On touch
Touch has no hover, so a tap toggles the controls:
- A tap anywhere outside the controls hides them if they're showing and nothing above keeps them up. Otherwise it shows them for 4 seconds.
- A tap on the controls, or a touch that moves more than 10px, never hides them. It shows them for 4 seconds.
Fade your own UI with the controls
The plugin writes data-controls="shown" or data-controls="hidden" on the player's root, so CSS can follow it with no render:
[data-controls="hidden"] .video-title { opacity: 0;}When you need the value in a component, read the plugin's state. Render the component inside the player:
"use client";import { useVideoState } from "react-video-kit";import { idle } from "react-video-kit/idle";function VideoTitle() { const visible = useVideoState(idle, (state) => state.visible); return visible ? <h2>Trailer</h2> : null;}Hide the controls in your own layout
The default skin does the hiding, so a headless layout needs its own rule. Keep the controls in the page while they're hidden, because Tab has to be able to reach them. Use display: none and it can't.
[data-controls="hidden"] [data-part="controls"] { opacity: 0; pointer-events: none;}[data-controls="hidden"] [data-part="controls"]:has(:focus-visible) { opacity: 1;}Build the bar with Controls, and menus with Menu and MenuContent. The hover, focus, and open menu checks look for their data-part and data-state attributes.
Behaviour
- The default skin also hides the cursor while the controls are hidden.
- A key press inside the player counts as activity. So does a hotkey that reaches the player while focus is elsewhere, which calls
show. showbrings the controls back and starts the usualmouseTimeoutwait, so they hide again afterwards.hideandtoggleset the state directly and skip the checks above.hideworks while the video is paused, and the controls stay hidden until the next activity.
API
Options
| Option | Type | Description |
|---|---|---|
| mouseTimeout? | number | Hide this long after the last mouse activity, in milliseconds. |
| touchTimeout? | number | Hide this long after a touch reveals the controls, in milliseconds. |
| leaveTimeout? | number | Hide this long after the mouse leaves the player, in milliseconds. |
State
Read it with useVideoState(idle, (state) => …).
| Field | Type | Description |
|---|---|---|
| visible | boolean | True while the controls are showing. |
Commands
Call them with useCommands(idle).
| Command | Type | Description |
|---|---|---|
| show | () => void | Reveals the controls, which then hide again as usual. |
| hide | () => void | Hides the controls until the viewer's next activity. |
| toggle | () => void | Shows the controls if hidden, and hides them if showing. |