mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
docs(site): add menu reference (#1673)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
---
|
||||
import HtmlDemo from '@/components/docs/demos/HtmlDemo.astro';
|
||||
import html from './BasicUsage.html?raw';
|
||||
---
|
||||
|
||||
<HtmlDemo html={html} />
|
||||
<script>
|
||||
import "./BasicUsage.ts";
|
||||
</script>
|
||||
@@ -0,0 +1,169 @@
|
||||
.video-player,
|
||||
.video-player media-container {
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.video-media {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.menu-bar {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
.settings-trigger {
|
||||
padding: 6px 16px;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
border: 1px solid rgba(255, 255, 255, 0.35);
|
||||
border-radius: 9999px;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.menu {
|
||||
--media-menu-side-offset: 8px;
|
||||
--menu-transition-duration: 220ms;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: var(--media-menu-width);
|
||||
min-width: 180px;
|
||||
max-width: var(--media-menu-available-width, var(--media-popover-available-width, none));
|
||||
height: var(--media-menu-height);
|
||||
max-height: var(--media-menu-available-height, var(--media-popover-available-height, none));
|
||||
padding: 6px;
|
||||
overflow: hidden;
|
||||
overscroll-behavior: none;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
background: rgba(0, 0, 0, 0.88);
|
||||
border-radius: 8px;
|
||||
backdrop-filter: blur(10px);
|
||||
transition-timing-function: ease-in-out;
|
||||
transition-duration: var(--menu-transition-duration);
|
||||
transition-property: width, height, opacity, filter;
|
||||
}
|
||||
|
||||
.menu-panel {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
padding: 6px;
|
||||
overflow: auto;
|
||||
overscroll-behavior: none;
|
||||
outline: none;
|
||||
translate: 0 0;
|
||||
transition-timing-function: ease-in-out;
|
||||
transition-duration: var(--menu-transition-duration);
|
||||
transition-property: translate, filter;
|
||||
will-change: translate;
|
||||
}
|
||||
|
||||
.menu-panel[data-starting-style],
|
||||
.menu-panel[data-ending-style] {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.menu-panel[data-menu-root-view][data-menu-view-state="inactive"] {
|
||||
filter: blur(8px);
|
||||
translate: -100% 0;
|
||||
}
|
||||
|
||||
.menu-panel[data-submenu] {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.menu-panel[data-submenu]:not([data-open], [data-ending-style]) {
|
||||
translate: -100% 0;
|
||||
transition-property: none;
|
||||
}
|
||||
|
||||
.menu-panel[data-submenu][data-starting-style],
|
||||
.menu-panel[data-submenu][data-ending-style] {
|
||||
pointer-events: none;
|
||||
filter: blur(8px);
|
||||
}
|
||||
|
||||
.menu-panel[data-submenu][data-starting-style][data-direction="forward"],
|
||||
.menu-panel[data-submenu][data-ending-style][data-direction="back"] {
|
||||
translate: 100% 0;
|
||||
}
|
||||
|
||||
.menu-panel[data-submenu][data-ending-style][data-direction="forward"],
|
||||
.menu-panel[data-submenu][data-starting-style][data-direction="back"] {
|
||||
translate: -100% 0;
|
||||
}
|
||||
|
||||
.menu-item,
|
||||
.menu-back {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 32px;
|
||||
padding: 0 10px;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.menu-item[data-highlighted],
|
||||
.menu-back:hover {
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.menu-back {
|
||||
gap: 8px;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.menu-item[data-availability="unavailable"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu-value {
|
||||
display: inline-flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
}
|
||||
|
||||
.menu-value [aria-hidden] {
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.menu-back [aria-hidden] {
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
}
|
||||
|
||||
.menu-group {
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.menu-tier {
|
||||
margin-left: 2px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.menu-badge {
|
||||
margin-left: auto;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
}
|
||||
|
||||
.menu-indicator {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
media-menu-radio-item[aria-checked="true"] .menu-indicator {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<video-player class="video-player">
|
||||
<media-container>
|
||||
<hlsjs-video
|
||||
class="video-media"
|
||||
src="https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4.m3u8"
|
||||
autoplay
|
||||
crossorigin="anonymous"
|
||||
muted
|
||||
playsinline
|
||||
loop
|
||||
>
|
||||
<track kind="captions" src="/docs/demos/captions-button/captions.vtt" srclang="en" label="English" />
|
||||
<track kind="subtitles" src="/docs/demos/captions-button/captions.vtt" srclang="es" label="Spanish" />
|
||||
</hlsjs-video>
|
||||
<div class="menu-bar">
|
||||
<button type="button" commandfor="settings-menu" class="settings-trigger">Settings</button>
|
||||
<media-menu id="settings-menu" side="top" align="end" class="menu">
|
||||
<media-menu-view class="menu-panel">
|
||||
<media-menu-item commandfor="quality-menu" type="quality" class="menu-item">
|
||||
<span>Quality</span>
|
||||
<span class="menu-value">
|
||||
<media-menu-item-value></media-menu-item-value>
|
||||
<span aria-hidden="true">›</span>
|
||||
</span>
|
||||
</media-menu-item>
|
||||
<media-menu-item commandfor="audio-menu" type="audio-track" class="menu-item">
|
||||
<span>Audio</span>
|
||||
<span class="menu-value">
|
||||
<media-menu-item-value></media-menu-item-value>
|
||||
<span aria-hidden="true">›</span>
|
||||
</span>
|
||||
</media-menu-item>
|
||||
<media-menu-item commandfor="speed-menu" type="playback-rate" class="menu-item">
|
||||
<span>Speed</span>
|
||||
<span class="menu-value">
|
||||
<media-menu-item-value></media-menu-item-value>
|
||||
<span aria-hidden="true">›</span>
|
||||
</span>
|
||||
</media-menu-item>
|
||||
<media-menu-item commandfor="captions-menu" type="captions" class="menu-item">
|
||||
<span>Captions</span>
|
||||
<span class="menu-value">
|
||||
<media-menu-item-value></media-menu-item-value>
|
||||
<span aria-hidden="true">›</span>
|
||||
</span>
|
||||
</media-menu-item>
|
||||
<media-menu-item class="menu-item">Copy link</media-menu-item>
|
||||
</media-menu-view>
|
||||
|
||||
<media-menu id="quality-menu" class="menu-panel">
|
||||
<media-menu-back class="menu-back">
|
||||
<span aria-hidden="true">‹</span>
|
||||
Quality
|
||||
</media-menu-back>
|
||||
<media-quality-radio-group class="menu-group">
|
||||
<template>
|
||||
<media-menu-radio-item class="menu-item">
|
||||
<span>
|
||||
<span data-part="label"></span>
|
||||
<sup data-part="tier" class="menu-tier"></sup>
|
||||
</span>
|
||||
<span data-part="badge" class="menu-badge"></span>
|
||||
<media-menu-item-indicator force-mount class="menu-indicator">✓</media-menu-item-indicator>
|
||||
</media-menu-radio-item>
|
||||
</template>
|
||||
</media-quality-radio-group>
|
||||
</media-menu>
|
||||
|
||||
<media-menu id="audio-menu" class="menu-panel">
|
||||
<media-menu-back class="menu-back">
|
||||
<span aria-hidden="true">‹</span>
|
||||
Audio
|
||||
</media-menu-back>
|
||||
<media-audio-track-radio-group class="menu-group">
|
||||
<template>
|
||||
<media-menu-radio-item class="menu-item">
|
||||
<span data-part="label"></span>
|
||||
<media-menu-item-indicator force-mount class="menu-indicator">✓</media-menu-item-indicator>
|
||||
</media-menu-radio-item>
|
||||
</template>
|
||||
</media-audio-track-radio-group>
|
||||
</media-menu>
|
||||
|
||||
<media-menu id="speed-menu" class="menu-panel">
|
||||
<media-menu-back class="menu-back">
|
||||
<span aria-hidden="true">‹</span>
|
||||
Speed
|
||||
</media-menu-back>
|
||||
<media-playback-rate-radio-group class="menu-group">
|
||||
<template>
|
||||
<media-menu-radio-item class="menu-item">
|
||||
<span data-part="label"></span>
|
||||
<media-menu-item-indicator force-mount class="menu-indicator">✓</media-menu-item-indicator>
|
||||
</media-menu-radio-item>
|
||||
</template>
|
||||
</media-playback-rate-radio-group>
|
||||
</media-menu>
|
||||
|
||||
<media-menu id="captions-menu" class="menu-panel">
|
||||
<media-menu-back class="menu-back">
|
||||
<span aria-hidden="true">‹</span>
|
||||
Captions
|
||||
</media-menu-back>
|
||||
<media-captions-radio-group class="menu-group">
|
||||
<template>
|
||||
<media-menu-radio-item class="menu-item">
|
||||
<span data-part="label"></span>
|
||||
<media-menu-item-indicator force-mount class="menu-indicator">✓</media-menu-item-indicator>
|
||||
</media-menu-radio-item>
|
||||
</template>
|
||||
</media-captions-radio-group>
|
||||
</media-menu>
|
||||
</media-menu>
|
||||
</div>
|
||||
</media-container>
|
||||
</video-player>
|
||||
@@ -0,0 +1,7 @@
|
||||
import '@videojs/html/video/player';
|
||||
import '@videojs/html/media/hlsjs-video';
|
||||
import '@videojs/html/ui/menu';
|
||||
import '@videojs/html/ui/quality-radio-group';
|
||||
import '@videojs/html/ui/audio-track-radio-group';
|
||||
import '@videojs/html/ui/playback-rate-radio-group';
|
||||
import '@videojs/html/ui/captions-radio-group';
|
||||
@@ -0,0 +1,162 @@
|
||||
.media-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.media-container video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.menu-bar {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
.settings-trigger {
|
||||
padding: 6px 16px;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
border: 1px solid rgba(255, 255, 255, 0.35);
|
||||
border-radius: 9999px;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.menu {
|
||||
--media-menu-side-offset: 8px;
|
||||
--menu-transition-duration: 220ms;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: var(--media-menu-width);
|
||||
min-width: 180px;
|
||||
max-width: var(--media-menu-available-width, var(--media-popover-available-width, none));
|
||||
height: var(--media-menu-height);
|
||||
max-height: var(--media-menu-available-height, var(--media-popover-available-height, none));
|
||||
padding: 6px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
overscroll-behavior: none;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
background: rgba(0, 0, 0, 0.88);
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
backdrop-filter: blur(10px);
|
||||
transition-timing-function: ease-in-out;
|
||||
transition-duration: var(--menu-transition-duration);
|
||||
transition-property: width, height, opacity, filter;
|
||||
}
|
||||
|
||||
.menu-panel {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
padding: 6px;
|
||||
overflow: auto;
|
||||
overscroll-behavior: none;
|
||||
outline: none;
|
||||
translate: 0 0;
|
||||
transition-timing-function: ease-in-out;
|
||||
transition-duration: var(--menu-transition-duration);
|
||||
transition-property: translate, filter;
|
||||
will-change: translate;
|
||||
}
|
||||
|
||||
.menu-panel[data-starting-style],
|
||||
.menu-panel[data-ending-style] {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.menu-panel[data-menu-root-view][data-menu-view-state="inactive"] {
|
||||
filter: blur(8px);
|
||||
translate: -100% 0;
|
||||
}
|
||||
|
||||
.menu-panel[data-submenu] {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.menu-panel[data-submenu]:not([data-open], [data-ending-style]) {
|
||||
translate: -100% 0;
|
||||
transition-property: none;
|
||||
}
|
||||
|
||||
.menu-panel[data-submenu][data-starting-style],
|
||||
.menu-panel[data-submenu][data-ending-style] {
|
||||
pointer-events: none;
|
||||
filter: blur(8px);
|
||||
}
|
||||
|
||||
.menu-panel[data-submenu][data-starting-style][data-direction="forward"],
|
||||
.menu-panel[data-submenu][data-ending-style][data-direction="back"] {
|
||||
translate: 100% 0;
|
||||
}
|
||||
|
||||
.menu-panel[data-submenu][data-ending-style][data-direction="forward"],
|
||||
.menu-panel[data-submenu][data-starting-style][data-direction="back"] {
|
||||
translate: -100% 0;
|
||||
}
|
||||
|
||||
.menu-item,
|
||||
.menu-back {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 32px;
|
||||
padding: 0 10px;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.menu-item[data-highlighted],
|
||||
.menu-back:hover {
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.menu-back {
|
||||
gap: 8px;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.menu-value {
|
||||
display: inline-flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
}
|
||||
|
||||
.menu-group {
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.menu-tier {
|
||||
margin-left: 2px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.menu-badge {
|
||||
margin-left: auto;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
}
|
||||
|
||||
.menu-back [aria-hidden],
|
||||
[role="menuitemradio"] [aria-hidden],
|
||||
.menu-item [aria-hidden] {
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
}
|
||||
|
||||
.menu-indicator {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
[role="menuitemradio"][aria-checked="true"] .menu-indicator {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
import {
|
||||
createPlayer,
|
||||
Menu,
|
||||
useAudioTrackOptions,
|
||||
useCaptionsOptions,
|
||||
usePlaybackRateOptions,
|
||||
useQualityOptions,
|
||||
} from '@videojs/react';
|
||||
import { HlsJsVideo } from '@videojs/react/media/hlsjs-video';
|
||||
import { videoFeatures } from '@videojs/react/video';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
const Player = createPlayer({ features: videoFeatures });
|
||||
const src = 'https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4.m3u8';
|
||||
|
||||
function SettingsMenu(): ReactNode {
|
||||
const playbackRate = usePlaybackRateOptions();
|
||||
const quality = useQualityOptions();
|
||||
const audioTrack = useAudioTrackOptions();
|
||||
const captions = useCaptionsOptions();
|
||||
const hasPlaybackRate = playbackRate?.state.availability === 'available';
|
||||
const hasQuality = quality?.state.availability === 'available';
|
||||
const hasAudioTrack = audioTrack?.state.availability === 'available';
|
||||
const hasCaptions = captions?.state.availability === 'available';
|
||||
|
||||
if (!hasPlaybackRate && !hasQuality && !hasAudioTrack && !hasCaptions) return null;
|
||||
|
||||
return (
|
||||
<Menu.Root side="top" align="end">
|
||||
<Menu.Trigger className="settings-trigger" aria-label="Settings" render={<button type="button" />}>
|
||||
Settings
|
||||
</Menu.Trigger>
|
||||
<Menu.Content className="menu">
|
||||
<Menu.View className="menu-panel">
|
||||
{hasQuality ? (
|
||||
<Menu.Root>
|
||||
<Menu.Trigger
|
||||
type="quality"
|
||||
className="menu-item"
|
||||
render={(props) => (
|
||||
<div {...props}>
|
||||
<span>Quality</span>
|
||||
<span className="menu-value">
|
||||
<Menu.ItemValue />
|
||||
<span aria-hidden="true">›</span>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
<Menu.Content className="menu-panel">
|
||||
<Menu.Back className="menu-back">
|
||||
<span aria-hidden="true">‹</span>
|
||||
Quality
|
||||
</Menu.Back>
|
||||
<Menu.RadioGroup
|
||||
className="menu-group"
|
||||
value={quality.value}
|
||||
onValueChange={quality.setValue}
|
||||
aria-label="Quality"
|
||||
>
|
||||
{quality.options.map((option) => (
|
||||
<Menu.RadioItem
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
disabled={option.disabled}
|
||||
className="menu-item"
|
||||
>
|
||||
<span>
|
||||
{option.label}
|
||||
{option.tier ? <sup className="menu-tier">{option.tier}</sup> : null}
|
||||
</span>
|
||||
{option.badge ? <span className="menu-badge">{option.badge}</span> : null}
|
||||
<Menu.ItemIndicator
|
||||
checked={option.value === quality.value}
|
||||
forceMount
|
||||
className="menu-indicator"
|
||||
>
|
||||
✓
|
||||
</Menu.ItemIndicator>
|
||||
</Menu.RadioItem>
|
||||
))}
|
||||
</Menu.RadioGroup>
|
||||
</Menu.Content>
|
||||
</Menu.Root>
|
||||
) : null}
|
||||
|
||||
{hasAudioTrack ? (
|
||||
<Menu.Root>
|
||||
<Menu.Trigger
|
||||
type="audio-track"
|
||||
className="menu-item"
|
||||
render={(props) => (
|
||||
<div {...props}>
|
||||
<span>Audio</span>
|
||||
<span className="menu-value">
|
||||
<Menu.ItemValue />
|
||||
<span aria-hidden="true">›</span>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
<Menu.Content className="menu-panel">
|
||||
<Menu.Back className="menu-back">
|
||||
<span aria-hidden="true">‹</span>
|
||||
Audio
|
||||
</Menu.Back>
|
||||
<Menu.RadioGroup
|
||||
className="menu-group"
|
||||
value={audioTrack.value}
|
||||
onValueChange={audioTrack.setValue}
|
||||
aria-label="Audio tracks"
|
||||
>
|
||||
{audioTrack.options.map((option) => (
|
||||
<Menu.RadioItem
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
disabled={option.disabled}
|
||||
className="menu-item"
|
||||
>
|
||||
<span>{option.label}</span>
|
||||
<Menu.ItemIndicator
|
||||
checked={option.value === audioTrack.value}
|
||||
forceMount
|
||||
className="menu-indicator"
|
||||
>
|
||||
✓
|
||||
</Menu.ItemIndicator>
|
||||
</Menu.RadioItem>
|
||||
))}
|
||||
</Menu.RadioGroup>
|
||||
</Menu.Content>
|
||||
</Menu.Root>
|
||||
) : null}
|
||||
|
||||
{hasPlaybackRate ? (
|
||||
<Menu.Root>
|
||||
<Menu.Trigger
|
||||
type="playback-rate"
|
||||
className="menu-item"
|
||||
render={(props) => (
|
||||
<div {...props}>
|
||||
<span>Speed</span>
|
||||
<span className="menu-value">
|
||||
<Menu.ItemValue />
|
||||
<span aria-hidden="true">›</span>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
<Menu.Content className="menu-panel">
|
||||
<Menu.Back className="menu-back">
|
||||
<span aria-hidden="true">‹</span>
|
||||
Speed
|
||||
</Menu.Back>
|
||||
<Menu.RadioGroup
|
||||
className="menu-group"
|
||||
value={playbackRate.value}
|
||||
onValueChange={playbackRate.setValue}
|
||||
aria-label="Playback rate"
|
||||
>
|
||||
{playbackRate.options.map((option) => (
|
||||
<Menu.RadioItem
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
disabled={option.disabled}
|
||||
className="menu-item"
|
||||
>
|
||||
<span>{option.label}</span>
|
||||
<Menu.ItemIndicator
|
||||
checked={option.value === playbackRate.value}
|
||||
forceMount
|
||||
className="menu-indicator"
|
||||
>
|
||||
✓
|
||||
</Menu.ItemIndicator>
|
||||
</Menu.RadioItem>
|
||||
))}
|
||||
</Menu.RadioGroup>
|
||||
</Menu.Content>
|
||||
</Menu.Root>
|
||||
) : null}
|
||||
|
||||
{hasCaptions ? (
|
||||
<Menu.Root>
|
||||
<Menu.Trigger
|
||||
type="captions"
|
||||
className="menu-item"
|
||||
render={(props) => (
|
||||
<div {...props}>
|
||||
<span>Captions</span>
|
||||
<span className="menu-value">
|
||||
<Menu.ItemValue />
|
||||
<span aria-hidden="true">›</span>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
<Menu.Content className="menu-panel">
|
||||
<Menu.Back className="menu-back">
|
||||
<span aria-hidden="true">‹</span>
|
||||
Captions
|
||||
</Menu.Back>
|
||||
<Menu.RadioGroup
|
||||
className="menu-group"
|
||||
value={captions.value}
|
||||
onValueChange={captions.setValue}
|
||||
aria-label="Captions"
|
||||
>
|
||||
{captions.options.map((option) => (
|
||||
<Menu.RadioItem
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
disabled={option.disabled}
|
||||
className="menu-item"
|
||||
>
|
||||
<span>{option.label}</span>
|
||||
<Menu.ItemIndicator
|
||||
checked={option.value === captions.value}
|
||||
forceMount
|
||||
className="menu-indicator"
|
||||
>
|
||||
✓
|
||||
</Menu.ItemIndicator>
|
||||
</Menu.RadioItem>
|
||||
))}
|
||||
</Menu.RadioGroup>
|
||||
</Menu.Content>
|
||||
</Menu.Root>
|
||||
) : null}
|
||||
|
||||
<Menu.Item className="menu-item" onSelect={() => navigator.clipboard?.writeText(window.location.href)}>
|
||||
Copy link
|
||||
</Menu.Item>
|
||||
</Menu.View>
|
||||
</Menu.Content>
|
||||
</Menu.Root>
|
||||
);
|
||||
}
|
||||
|
||||
export default function BasicUsage() {
|
||||
return (
|
||||
<Player.Provider>
|
||||
<Player.Container className="media-container">
|
||||
<HlsJsVideo src={src} autoPlay crossOrigin="anonymous" muted playsInline loop>
|
||||
<track kind="captions" src="/docs/demos/captions-button/captions.vtt" srcLang="en" label="English" />
|
||||
<track kind="subtitles" src="/docs/demos/captions-button/captions.vtt" srcLang="es" label="Spanish" />
|
||||
</HlsJsVideo>
|
||||
<div className="menu-bar">
|
||||
<SettingsMenu />
|
||||
</div>
|
||||
</Player.Container>
|
||||
</Player.Provider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user