media-cast-button
Accessible Cast toggle button with state reflection and keyboard support
Anatomy
<CastButton /><media-cast-button></media-cast-button>Behavior
Toggles a Google Cast session. Clicking the button while disconnected opens the Cast device picker; clicking while connected ends the session.
The button derives its presentation from availability:
"unsupported"— the HTML custom element receives the nativehiddenattribute; the React component returnsnull."unavailable"— the button remains visible and focusable witharia-disabled="true"anddata-disabled, but does not open the picker. This lets a tooltip explain that no Cast device is reachable."available"— the button is fully interactive unless thedisabledprop is set.
Cast sessions come from the Google Cast component. Add it to the player next to your media element; without it the button drives the browser’s native Remote Playback API instead, which offers no receiver or load-request configuration.
Styling
Style based on cast and disabled state:
/* During an active session */
media-cast-button[data-cast-state="connected"] {
color: blue;
}
/* Cast is supported, but no device is reachable */
media-cast-button[data-disabled] {
cursor: not-allowed;
opacity: 0.5;
}React renders a <button> element. Add a className to style it:
/* During an active session */
.cast-button[data-cast-state="connected"] {
color: blue;
}
/* Cast is supported, but no device is reachable */
.cast-button[data-disabled] {
cursor: not-allowed;
opacity: 0.5;
}Unsupported buttons are hidden automatically. No availability selector or extra hiding CSS is required.
Accessibility
Renders a <button> with an automatic aria-label:
| Cast state | Default label |
|---|---|
'disconnected' |
“Start casting” |
'connecting' |
“Connecting” |
'connected' |
“Stop casting” |
Override with the label prop. Keyboard activation: Enter / Space.
Examples
Basic Usage
import { CastButton, createPlayer } from '@videojs/react';
import { HlsJsVideo } from '@videojs/react/media/hlsjs-video';
import { videoFeatures } from '@videojs/react/video';
const Player = createPlayer({ features: videoFeatures });
export default function BasicUsage() {
return (
<Player.Provider>
<Player.Container className="media-container">
<HlsJsVideo src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8" autoPlay muted playsInline loop />
<CastButton
className="media-cast-button"
render={(props, state) => (
<button {...props}>{state.connection === 'connected' ? 'Stop casting' : 'Start casting'}</button>
)}
/>
</Player.Container>
</Player.Provider>
);
}
.media-container {
position: relative;
}
.media-container video {
width: 100%;
}
.media-cast-button {
position: absolute;
right: 10px;
bottom: 10px;
padding-block: 8px;
padding-inline: 20px;
color: black;
cursor: pointer;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 9999px;
backdrop-filter: blur(10px);
}
.media-cast-button[data-disabled] {
cursor: not-allowed;
opacity: 0.5;
filter: grayscale(1);
}
<video-player class="video-player">
<media-container>
<hlsjs-video
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8"
autoplay
muted
playsinline
loop
></hlsjs-video>
<media-cast-button class="media-cast-button">
<span class="connected">Stop casting</span>
<span class="disconnected">Start casting</span>
</media-cast-button>
</media-container>
</video-player>
.video-player {
position: relative;
display: block;
}
.video-player video {
width: 100%;
}
.media-cast-button {
position: absolute;
right: 10px;
bottom: 10px;
padding-block: 8px;
padding-inline: 20px;
color: black;
cursor: pointer;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 9999px;
backdrop-filter: blur(10px);
}
.media-cast-button[data-disabled] {
cursor: not-allowed;
opacity: 0.5;
filter: grayscale(1);
}
.media-cast-button .connected {
display: none;
}
.media-cast-button .disconnected {
display: none;
}
.media-cast-button[data-cast-state="connected"] .connected {
display: inline;
}
.media-cast-button:not([data-cast-state="connected"]) .disconnected {
display: inline;
}
import '@videojs/html/video/player';
import '@videojs/html/media/hlsjs-video';
import '@videojs/html/ui/cast-button';
API Reference
Props
| Prop | Type | Default | Details |
|---|---|---|---|
disabled | boolean | false | |
| |||
label | Text | string | Text) | function | '' | |
| |||
State
render, className, and style props.| Property | Type | Details |
|---|---|---|
connection | 'disconnected' | 'connecting' | 'conn... | |
| ||
availability | 'available' | 'unavailable' | 'unsupp... | |
| ||
disabled | boolean | |
| ||
label | Text | string | |
Data attributes
| Attribute | Type | Details |
|---|---|---|
data-cast-state | 'disconnected' | 'connecting' | 'conn... | |
| ||
data-availability | 'available' | 'unavailable' | 'unsupp... | |
| ||
data-disabled | ||
| ||