mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(packages): add live-video and live-audio presets (#1399)
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/minimal/css/audio.css";
|
||||
@@ -0,0 +1,86 @@
|
||||
import { renderIcon } from '@videojs/icons/render/minimal';
|
||||
import {
|
||||
button,
|
||||
buttonGroup,
|
||||
controls,
|
||||
error,
|
||||
icon,
|
||||
iconState,
|
||||
popup,
|
||||
root,
|
||||
slider,
|
||||
} from '@videojs/skins/minimal/tailwind/audio.tailwind';
|
||||
import { createTemplate } from '@videojs/utils/dom';
|
||||
import { cn } from '@videojs/utils/style';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { SkinElement } from '../skin-element';
|
||||
|
||||
// Reuse the audio preset's minimal UI element registrations.
|
||||
import '../audio/minimal-ui';
|
||||
|
||||
function getTemplateHTML() {
|
||||
return /*html*/ `
|
||||
<media-container class="${root}">
|
||||
<!-- @deprecated slot="media" is no longer required, use the default slot instead -->
|
||||
<slot name="media"></slot>
|
||||
<slot></slot>
|
||||
|
||||
<media-error-dialog class="${error.root}">
|
||||
<div class="${error.dialog}">
|
||||
<div class="${error.content}">
|
||||
<media-alert-dialog-title class="${error.title}">Something went wrong.</media-alert-dialog-title>
|
||||
<media-alert-dialog-description class="${error.description}"></media-alert-dialog-description>
|
||||
</div>
|
||||
<div class="${error.actions}">
|
||||
<media-alert-dialog-close class="${cn(button.base, button.subtle)}">OK</media-alert-dialog-close>
|
||||
</div>
|
||||
</div>
|
||||
</media-error-dialog>
|
||||
|
||||
<div class="${controls}">
|
||||
<media-tooltip-group>
|
||||
<div class="${buttonGroup}">
|
||||
<media-play-button commandfor="play-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.play.button)}">
|
||||
${renderIcon('restart', { class: cn(icon, iconState.play.restart) })}
|
||||
${renderIcon('play', { class: cn(icon, iconState.play.play) })}
|
||||
${renderIcon('pause', { class: cn(icon, iconState.play.pause) })}
|
||||
</media-play-button>
|
||||
<media-tooltip id="play-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="grow" aria-hidden="true"></div>
|
||||
|
||||
<div class="${buttonGroup}">
|
||||
<media-mute-button commandfor="live-audio-volume-popover" class="${cn(button.base, button.subtle, button.icon, iconState.mute.button)}">
|
||||
${renderIcon('volume-off', { class: cn(icon, iconState.mute.volumeOff) })}
|
||||
${renderIcon('volume-low', { class: cn(icon, iconState.mute.volumeLow) })}
|
||||
${renderIcon('volume-high', { class: cn(icon, iconState.mute.volumeHigh) })}
|
||||
</media-mute-button>
|
||||
|
||||
<media-popover id="live-audio-volume-popover" open-on-hover delay="200" close-delay="100" side="left" class="${cn(popup.volume)}">
|
||||
<media-volume-slider class="${slider.root}" orientation="horizontal" thumb-alignment="edge">
|
||||
<media-slider-track class="${slider.track}">
|
||||
<media-slider-fill class="${cn(slider.fill.base, slider.fill.fill)}"></media-slider-fill>
|
||||
</media-slider-track>
|
||||
<media-slider-thumb class="${slider.thumb.base}"></media-slider-thumb>
|
||||
</media-volume-slider>
|
||||
</media-popover>
|
||||
</div>
|
||||
</media-tooltip-group>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
export class MinimalLiveAudioSkinTailwindElement extends SkinElement {
|
||||
static readonly tagName = 'live-audio-minimal-skin-tailwind';
|
||||
static template = createTemplate(getTemplateHTML());
|
||||
}
|
||||
|
||||
safeDefine(MinimalLiveAudioSkinTailwindElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[MinimalLiveAudioSkinTailwindElement.tagName]: MinimalLiveAudioSkinTailwindElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import { renderIcon } from '@videojs/icons/render/minimal';
|
||||
import { createShadowStyle, createTemplate } from '@videojs/utils/dom';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { SkinElement } from '../skin-element';
|
||||
import styles from './minimal-skin.css?inline';
|
||||
|
||||
// Reuse the audio preset's minimal UI element registrations.
|
||||
import '../audio/minimal-ui';
|
||||
|
||||
function getTemplateHTML() {
|
||||
return /*html*/ `
|
||||
<media-container class="media-minimal-skin media-minimal-skin--audio">
|
||||
<!-- @deprecated slot="media" is no longer required, use the default slot instead -->
|
||||
<slot name="media"></slot>
|
||||
<slot></slot>
|
||||
|
||||
<media-error-dialog class="media-error">
|
||||
<div class="media-error__dialog">
|
||||
<div class="media-error__content">
|
||||
<media-alert-dialog-title class="media-error__title">Something went wrong.</media-alert-dialog-title>
|
||||
<media-alert-dialog-description class="media-error__description"></media-alert-dialog-description>
|
||||
</div>
|
||||
<div class="media-error__actions">
|
||||
<media-alert-dialog-close class="media-button media-button--subtle">OK</media-alert-dialog-close>
|
||||
</div>
|
||||
</div>
|
||||
</media-error-dialog>
|
||||
|
||||
<div class="media-controls">
|
||||
<media-tooltip-group>
|
||||
<div class="media-button-group">
|
||||
<media-play-button commandfor="play-tooltip" class="media-button media-button--subtle media-button--icon media-button--play">
|
||||
${renderIcon('restart', { class: 'media-icon media-icon--restart' })}
|
||||
${renderIcon('play', { class: 'media-icon media-icon--play' })}
|
||||
${renderIcon('pause', { class: 'media-icon media-icon--pause' })}
|
||||
</media-play-button>
|
||||
<media-tooltip id="play-tooltip" side="top" class="media-tooltip"></media-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="media-time-controls" aria-hidden="true"></div>
|
||||
|
||||
<div class="media-button-group">
|
||||
<media-mute-button commandfor="live-audio-volume-popover" class="media-button media-button--subtle media-button--icon media-button--mute">
|
||||
${renderIcon('volume-off', { class: 'media-icon media-icon--volume-off' })}
|
||||
${renderIcon('volume-low', { class: 'media-icon media-icon--volume-low' })}
|
||||
${renderIcon('volume-high', { class: 'media-icon media-icon--volume-high' })}
|
||||
</media-mute-button>
|
||||
|
||||
<media-popover id="live-audio-volume-popover" open-on-hover delay="200" close-delay="100" side="left" class="media-popover media-popover--volume">
|
||||
<media-volume-slider class="media-slider" orientation="horizontal" thumb-alignment="edge">
|
||||
<media-slider-track class="media-slider__track">
|
||||
<media-slider-fill class="media-slider__fill"></media-slider-fill>
|
||||
</media-slider-track>
|
||||
<media-slider-thumb class="media-slider__thumb media-slider__thumb--persistent"></media-slider-thumb>
|
||||
</media-volume-slider>
|
||||
</media-popover>
|
||||
</div>
|
||||
</media-tooltip-group>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
export class MinimalLiveAudioSkinElement extends SkinElement {
|
||||
static readonly tagName = 'live-audio-minimal-skin';
|
||||
static styles = createShadowStyle(styles);
|
||||
static template = createTemplate(getTemplateHTML());
|
||||
}
|
||||
|
||||
safeDefine(MinimalLiveAudioSkinElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[MinimalLiveAudioSkinElement.tagName]: MinimalLiveAudioSkinElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/default/css/audio.css";
|
||||
@@ -0,0 +1,86 @@
|
||||
import { renderIcon } from '@videojs/icons/render';
|
||||
import {
|
||||
button,
|
||||
buttonGroup,
|
||||
controls,
|
||||
error,
|
||||
icon,
|
||||
iconState,
|
||||
popup,
|
||||
root,
|
||||
slider,
|
||||
} from '@videojs/skins/default/tailwind/audio.tailwind';
|
||||
import { createTemplate } from '@videojs/utils/dom';
|
||||
import { cn } from '@videojs/utils/style';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { SkinElement } from '../skin-element';
|
||||
|
||||
// Reuse the audio preset's UI element registrations.
|
||||
import '../audio/ui';
|
||||
|
||||
function getTemplateHTML() {
|
||||
return /*html*/ `
|
||||
<media-container class="${root}">
|
||||
<!-- @deprecated slot="media" is no longer required, use the default slot instead -->
|
||||
<slot name="media"></slot>
|
||||
<slot></slot>
|
||||
|
||||
<media-error-dialog class="${error.root}">
|
||||
<div class="${error.dialog}">
|
||||
<div class="${error.content}">
|
||||
<media-alert-dialog-title class="${error.title}">Something went wrong.</media-alert-dialog-title>
|
||||
<media-alert-dialog-description class="${error.description}"></media-alert-dialog-description>
|
||||
</div>
|
||||
<div class="${error.actions}">
|
||||
<media-alert-dialog-close class="${cn(button.base, button.subtle)}">OK</media-alert-dialog-close>
|
||||
</div>
|
||||
</div>
|
||||
</media-error-dialog>
|
||||
|
||||
<div class="${controls}">
|
||||
<media-tooltip-group>
|
||||
<div class="${buttonGroup}">
|
||||
<media-play-button commandfor="play-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.play.button)}">
|
||||
${renderIcon('restart', { class: cn(icon, iconState.play.restart) })}
|
||||
${renderIcon('play', { class: cn(icon, iconState.play.play) })}
|
||||
${renderIcon('pause', { class: cn(icon, iconState.play.pause) })}
|
||||
</media-play-button>
|
||||
<media-tooltip id="play-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="grow" aria-hidden="true"></div>
|
||||
|
||||
<div class="${buttonGroup}">
|
||||
<media-mute-button commandfor="live-audio-volume-popover" class="${cn(button.base, button.subtle, button.icon, iconState.mute.button)}">
|
||||
${renderIcon('volume-off', { class: cn(icon, iconState.mute.volumeOff) })}
|
||||
${renderIcon('volume-low', { class: cn(icon, iconState.mute.volumeLow) })}
|
||||
${renderIcon('volume-high', { class: cn(icon, iconState.mute.volumeHigh) })}
|
||||
</media-mute-button>
|
||||
|
||||
<media-popover id="live-audio-volume-popover" open-on-hover delay="200" close-delay="100" side="top" class="${cn(popup.popover, popup.volume)}">
|
||||
<media-volume-slider class="${slider.root}" orientation="vertical" thumb-alignment="edge">
|
||||
<media-slider-track class="${slider.track}">
|
||||
<media-slider-fill class="${cn(slider.fill.base, slider.fill.fill)}"></media-slider-fill>
|
||||
</media-slider-track>
|
||||
<media-slider-thumb class="${cn(slider.thumb.base, slider.thumb.persistent)}"></media-slider-thumb>
|
||||
</media-volume-slider>
|
||||
</media-popover>
|
||||
</div>
|
||||
</media-tooltip-group>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
export class LiveAudioSkinTailwindElement extends SkinElement {
|
||||
static readonly tagName = 'live-audio-skin-tailwind';
|
||||
static template = createTemplate(getTemplateHTML());
|
||||
}
|
||||
|
||||
safeDefine(LiveAudioSkinTailwindElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[LiveAudioSkinTailwindElement.tagName]: LiveAudioSkinTailwindElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import { renderIcon } from '@videojs/icons/render';
|
||||
import { createShadowStyle, createTemplate } from '@videojs/utils/dom';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { SkinElement } from '../skin-element';
|
||||
import styles from './skin.css?inline';
|
||||
|
||||
// Reuse the audio preset's UI element registrations.
|
||||
import '../audio/ui';
|
||||
|
||||
function getTemplateHTML() {
|
||||
return /*html*/ `
|
||||
<media-container class="media-default-skin media-default-skin--audio">
|
||||
<!-- @deprecated slot="media" is no longer required, use the default slot instead -->
|
||||
<slot name="media"></slot>
|
||||
<slot></slot>
|
||||
|
||||
<media-error-dialog class="media-error">
|
||||
<div class="media-error__dialog">
|
||||
<div class="media-error__content">
|
||||
<media-alert-dialog-title class="media-error__title">Something went wrong.</media-alert-dialog-title>
|
||||
<media-alert-dialog-description class="media-error__description"></media-alert-dialog-description>
|
||||
</div>
|
||||
<div class="media-error__actions">
|
||||
<media-alert-dialog-close class="media-button media-button--subtle">OK</media-alert-dialog-close>
|
||||
</div>
|
||||
</div>
|
||||
</media-error-dialog>
|
||||
|
||||
<div class="media-surface media-controls">
|
||||
<media-tooltip-group>
|
||||
<div class="media-button-group">
|
||||
<media-play-button commandfor="play-tooltip" class="media-button media-button--subtle media-button--icon media-button--play">
|
||||
${renderIcon('restart', { class: 'media-icon media-icon--restart' })}
|
||||
${renderIcon('play', { class: 'media-icon media-icon--play' })}
|
||||
${renderIcon('pause', { class: 'media-icon media-icon--pause' })}
|
||||
</media-play-button>
|
||||
<media-tooltip id="play-tooltip" side="top" class="media-surface media-tooltip"></media-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="media-time-controls" aria-hidden="true"></div>
|
||||
|
||||
<div class="media-button-group">
|
||||
<media-mute-button commandfor="live-audio-volume-popover" class="media-button media-button--subtle media-button--icon media-button--mute">
|
||||
${renderIcon('volume-off', { class: 'media-icon media-icon--volume-off' })}
|
||||
${renderIcon('volume-low', { class: 'media-icon media-icon--volume-low' })}
|
||||
${renderIcon('volume-high', { class: 'media-icon media-icon--volume-high' })}
|
||||
</media-mute-button>
|
||||
|
||||
<media-popover id="live-audio-volume-popover" open-on-hover delay="200" close-delay="100" side="top" class="media-surface media-popover media-popover--volume">
|
||||
<media-volume-slider class="media-slider" orientation="vertical" thumb-alignment="edge">
|
||||
<media-slider-track class="media-slider__track">
|
||||
<media-slider-fill class="media-slider__fill"></media-slider-fill>
|
||||
</media-slider-track>
|
||||
<media-slider-thumb class="media-slider__thumb media-slider__thumb--persistent"></media-slider-thumb>
|
||||
</media-volume-slider>
|
||||
</media-popover>
|
||||
</div>
|
||||
</media-tooltip-group>
|
||||
</div>
|
||||
|
||||
<!-- Hotkeys -->
|
||||
<media-hotkey keys="Space" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="k" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="m" action="toggleMuted"></media-hotkey>
|
||||
<media-hotkey keys="ArrowUp" action="volumeStep" value="0.05"></media-hotkey>
|
||||
<media-hotkey keys="ArrowDown" action="volumeStep" value="-0.05"></media-hotkey>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
export class LiveAudioSkinElement extends SkinElement {
|
||||
static readonly tagName = 'live-audio-skin';
|
||||
static styles = createShadowStyle(styles);
|
||||
static template = createTemplate(getTemplateHTML());
|
||||
}
|
||||
|
||||
safeDefine(LiveAudioSkinElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[LiveAudioSkinElement.tagName]: LiveAudioSkinElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/minimal/css/video.css";
|
||||
@@ -0,0 +1,120 @@
|
||||
import { renderIcon } from '@videojs/icons/render/minimal';
|
||||
import {
|
||||
bufferingIndicator,
|
||||
button,
|
||||
buttonGroupEnd,
|
||||
buttonGroupStart,
|
||||
controls,
|
||||
error,
|
||||
icon,
|
||||
iconState,
|
||||
overlay,
|
||||
popup,
|
||||
poster,
|
||||
root,
|
||||
slider,
|
||||
} from '@videojs/skins/minimal/tailwind/video.tailwind';
|
||||
import { createTemplate } from '@videojs/utils/dom';
|
||||
import { cn } from '@videojs/utils/style';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { SkinElement } from '../skin-element';
|
||||
|
||||
// Reuse the video preset's minimal UI element registrations.
|
||||
import '../video/minimal-ui';
|
||||
|
||||
function getTemplateHTML() {
|
||||
return /*html*/ `
|
||||
<media-container class="${root(true)}">
|
||||
<!-- @deprecated slot="media" is no longer required, use the default slot instead -->
|
||||
<slot name="media"></slot>
|
||||
<slot></slot>
|
||||
|
||||
<media-poster class="${poster(true)}">
|
||||
<slot name="poster"></slot>
|
||||
</media-poster>
|
||||
|
||||
<media-buffering-indicator class="${bufferingIndicator}">
|
||||
${renderIcon('spinner')}
|
||||
</media-buffering-indicator>
|
||||
|
||||
<media-error-dialog class="${error.root}">
|
||||
<div class="${error.dialog}">
|
||||
<div class="${error.content}">
|
||||
<media-alert-dialog-title class="${error.title}">Something went wrong.</media-alert-dialog-title>
|
||||
<media-alert-dialog-description class="${error.description}"></media-alert-dialog-description>
|
||||
</div>
|
||||
<div class="${error.actions}">
|
||||
<media-alert-dialog-close class="${cn(button.base, button.primary)}">OK</media-alert-dialog-close>
|
||||
</div>
|
||||
</div>
|
||||
</media-error-dialog>
|
||||
|
||||
<media-controls data-controls="" class="${controls}">
|
||||
<media-tooltip-group>
|
||||
<div class="${buttonGroupStart}">
|
||||
<media-play-button commandfor="play-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.play.button)}">
|
||||
${renderIcon('restart', { class: cn(icon, iconState.play.restart) })}
|
||||
${renderIcon('play', { class: cn(icon, iconState.play.play) })}
|
||||
${renderIcon('pause', { class: cn(icon, iconState.play.pause) })}
|
||||
</media-play-button>
|
||||
<media-tooltip id="play-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="grow" aria-hidden="true"></div>
|
||||
|
||||
<div class="${buttonGroupEnd}">
|
||||
<media-mute-button commandfor="live-video-volume-popover" class="${cn(button.base, button.subtle, button.icon, iconState.mute.button)}">
|
||||
${renderIcon('volume-off', { class: cn(icon, iconState.mute.volumeOff) })}
|
||||
${renderIcon('volume-low', { class: cn(icon, iconState.mute.volumeLow) })}
|
||||
${renderIcon('volume-high', { class: cn(icon, iconState.mute.volumeHigh) })}
|
||||
</media-mute-button>
|
||||
|
||||
<media-popover id="live-video-volume-popover" open-on-hover delay="200" close-delay="100" side="top" class="${cn(popup.volume)}">
|
||||
<media-volume-slider class="${slider.root}" orientation="vertical" thumb-alignment="edge">
|
||||
<media-slider-track class="${slider.track}">
|
||||
<media-slider-fill class="${cn(slider.fill.base, slider.fill.fill)}"></media-slider-fill>
|
||||
</media-slider-track>
|
||||
<media-slider-thumb class="${slider.thumb.base}"></media-slider-thumb>
|
||||
</media-volume-slider>
|
||||
</media-popover>
|
||||
<media-captions-button commandfor="captions-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.captions.button)}">
|
||||
${renderIcon('captions-off', { class: cn(icon, iconState.captions.off) })}
|
||||
${renderIcon('captions-on', { class: cn(icon, iconState.captions.on) })}
|
||||
</media-captions-button>
|
||||
<media-tooltip id="captions-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
<media-cast-button commandfor="cast-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.cast.button)}">
|
||||
${renderIcon('cast-enter', { class: cn(icon, iconState.cast.enter) })}
|
||||
${renderIcon('cast-exit', { class: cn(icon, iconState.cast.exit) })}
|
||||
</media-cast-button>
|
||||
<media-tooltip id="cast-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
<media-pip-button commandfor="pip-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.pip.button)}">
|
||||
${renderIcon('pip-enter', { class: cn(icon, iconState.pip.off) })}
|
||||
${renderIcon('pip-exit', { class: cn(icon, iconState.pip.on) })}
|
||||
</media-pip-button>
|
||||
<media-tooltip id="pip-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
<media-fullscreen-button commandfor="fullscreen-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.fullscreen.button)}">
|
||||
${renderIcon('fullscreen-enter', { class: cn(icon, iconState.fullscreen.enter) })}
|
||||
${renderIcon('fullscreen-exit', { class: cn(icon, iconState.fullscreen.exit) })}
|
||||
</media-fullscreen-button>
|
||||
<media-tooltip id="fullscreen-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
</div>
|
||||
</media-tooltip-group>
|
||||
</media-controls>
|
||||
|
||||
<div class="${overlay}"></div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
export class MinimalLiveVideoSkinTailwindElement extends SkinElement {
|
||||
static readonly tagName = 'live-video-minimal-skin-tailwind';
|
||||
static template = createTemplate(getTemplateHTML());
|
||||
}
|
||||
|
||||
safeDefine(MinimalLiveVideoSkinTailwindElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[MinimalLiveVideoSkinTailwindElement.tagName]: MinimalLiveVideoSkinTailwindElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import { renderIcon } from '@videojs/icons/render/minimal';
|
||||
import { createShadowStyle, createTemplate } from '@videojs/utils/dom';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { SkinElement } from '../skin-element';
|
||||
import styles from './minimal-skin.css?inline';
|
||||
|
||||
// Reuse the video preset's minimal UI element registrations.
|
||||
import '../video/minimal-ui';
|
||||
|
||||
function getTemplateHTML() {
|
||||
return /*html*/ `
|
||||
<media-container class="media-minimal-skin media-minimal-skin--video">
|
||||
<!-- @deprecated slot="media" is no longer required, use the default slot instead -->
|
||||
<slot name="media"></slot>
|
||||
<slot></slot>
|
||||
|
||||
<media-poster>
|
||||
<slot name="poster"></slot>
|
||||
</media-poster>
|
||||
|
||||
<media-buffering-indicator class="media-buffering-indicator">
|
||||
${renderIcon('spinner', { class: 'media-icon' })}
|
||||
</media-buffering-indicator>
|
||||
|
||||
<media-error-dialog class="media-error">
|
||||
<div class="media-error__dialog">
|
||||
<div class="media-error__content">
|
||||
<media-alert-dialog-title class="media-error__title">Something went wrong.</media-alert-dialog-title>
|
||||
<media-alert-dialog-description class="media-error__description"></media-alert-dialog-description>
|
||||
</div>
|
||||
<div class="media-error__actions">
|
||||
<media-alert-dialog-close class="media-button media-button--primary">OK</media-alert-dialog-close>
|
||||
</div>
|
||||
</div>
|
||||
</media-error-dialog>
|
||||
|
||||
<media-controls class="media-controls">
|
||||
<media-tooltip-group>
|
||||
<div class="media-button-group">
|
||||
<media-play-button commandfor="play-tooltip" class="media-button media-button--subtle media-button--icon media-button--play">
|
||||
${renderIcon('restart', { class: 'media-icon media-icon--restart' })}
|
||||
${renderIcon('play', { class: 'media-icon media-icon--play' })}
|
||||
${renderIcon('pause', { class: 'media-icon media-icon--pause' })}
|
||||
</media-play-button>
|
||||
<media-tooltip id="play-tooltip" side="top" class="media-tooltip"></media-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="media-time-controls" aria-hidden="true"></div>
|
||||
|
||||
<div class="media-button-group">
|
||||
<media-mute-button commandfor="live-video-volume-popover" class="media-button media-button--subtle media-button--icon media-button--mute">
|
||||
${renderIcon('volume-off', { class: 'media-icon media-icon--volume-off' })}
|
||||
${renderIcon('volume-low', { class: 'media-icon media-icon--volume-low' })}
|
||||
${renderIcon('volume-high', { class: 'media-icon media-icon--volume-high' })}
|
||||
</media-mute-button>
|
||||
|
||||
<media-popover id="live-video-volume-popover" open-on-hover delay="200" close-delay="100" side="top" class="media-popover media-popover--volume">
|
||||
<media-volume-slider class="media-slider" orientation="vertical" thumb-alignment="edge">
|
||||
<media-slider-track class="media-slider__track">
|
||||
<media-slider-fill class="media-slider__fill"></media-slider-fill>
|
||||
</media-slider-track>
|
||||
<media-slider-thumb class="media-slider__thumb media-slider__thumb--persistent"></media-slider-thumb>
|
||||
</media-volume-slider>
|
||||
</media-popover>
|
||||
|
||||
<media-captions-button commandfor="captions-tooltip" class="media-button media-button--subtle media-button--icon media-button--captions">
|
||||
${renderIcon('captions-off', { class: 'media-icon media-icon--captions-off' })}
|
||||
${renderIcon('captions-on', { class: 'media-icon media-icon--captions-on' })}
|
||||
</media-captions-button>
|
||||
<media-tooltip id="captions-tooltip" side="top" class="media-tooltip">
|
||||
Toggle captions
|
||||
</media-tooltip>
|
||||
|
||||
<media-cast-button commandfor="cast-tooltip" class="media-button media-button--subtle media-button--icon media-button--cast">
|
||||
${renderIcon('cast-enter', { class: 'media-icon media-icon--cast-enter' })}
|
||||
${renderIcon('cast-exit', { class: 'media-icon media-icon--cast-exit' })}
|
||||
</media-cast-button>
|
||||
<media-tooltip id="cast-tooltip" side="top" class="media-tooltip"></media-tooltip>
|
||||
|
||||
<media-pip-button commandfor="pip-tooltip" class="media-button media-button--subtle media-button--icon media-button--pip">
|
||||
${renderIcon('pip-enter', { class: 'media-icon media-icon--pip-enter' })}
|
||||
${renderIcon('pip-exit', { class: 'media-icon media-icon--pip-exit' })}
|
||||
</media-pip-button>
|
||||
<media-tooltip id="pip-tooltip" side="top" class="media-tooltip"></media-tooltip>
|
||||
|
||||
<media-fullscreen-button commandfor="fullscreen-tooltip" class="media-button media-button--subtle media-button--icon media-button--fullscreen">
|
||||
${renderIcon('fullscreen-enter', { class: 'media-icon media-icon--fullscreen-enter' })}
|
||||
${renderIcon('fullscreen-exit', { class: 'media-icon media-icon--fullscreen-exit' })}
|
||||
</media-fullscreen-button>
|
||||
<media-tooltip id="fullscreen-tooltip" side="top" class="media-tooltip"></media-tooltip>
|
||||
</div>
|
||||
</media-tooltip-group>
|
||||
</media-controls>
|
||||
|
||||
<div class="media-overlay"></div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
export class MinimalLiveVideoSkinElement extends SkinElement {
|
||||
static readonly tagName = 'live-video-minimal-skin';
|
||||
static styles = createShadowStyle(styles);
|
||||
static template = createTemplate(getTemplateHTML());
|
||||
}
|
||||
|
||||
safeDefine(MinimalLiveVideoSkinElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[MinimalLiveVideoSkinElement.tagName]: MinimalLiveVideoSkinElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/default/css/video.css";
|
||||
@@ -0,0 +1,122 @@
|
||||
import { renderIcon } from '@videojs/icons/render';
|
||||
import {
|
||||
bufferingIndicator,
|
||||
button,
|
||||
buttonGroupEnd,
|
||||
buttonGroupStart,
|
||||
controls,
|
||||
error,
|
||||
icon,
|
||||
iconState,
|
||||
overlay,
|
||||
popup,
|
||||
poster,
|
||||
root,
|
||||
slider,
|
||||
} from '@videojs/skins/default/tailwind/video.tailwind';
|
||||
import { createTemplate } from '@videojs/utils/dom';
|
||||
import { cn } from '@videojs/utils/style';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { SkinElement } from '../skin-element';
|
||||
|
||||
// Reuse the video preset's UI element registrations.
|
||||
import '../video/ui';
|
||||
|
||||
function getTemplateHTML() {
|
||||
return /*html*/ `
|
||||
<media-container class="${root(true)}">
|
||||
<!-- @deprecated slot="media" is no longer required, use the default slot instead -->
|
||||
<slot name="media"></slot>
|
||||
<slot></slot>
|
||||
|
||||
<media-poster class="${poster(true)}">
|
||||
<slot name="poster"></slot>
|
||||
</media-poster>
|
||||
|
||||
<media-buffering-indicator class="${bufferingIndicator.root}">
|
||||
<div class="${bufferingIndicator.container}">
|
||||
${renderIcon('spinner')}
|
||||
</div>
|
||||
</media-buffering-indicator>
|
||||
|
||||
<media-error-dialog class="${error.root}">
|
||||
<div class="${error.dialog}">
|
||||
<div class="${error.content}">
|
||||
<media-alert-dialog-title class="${error.title}">Something went wrong.</media-alert-dialog-title>
|
||||
<media-alert-dialog-description class="${error.description}"></media-alert-dialog-description>
|
||||
</div>
|
||||
<div class="${error.actions}">
|
||||
<media-alert-dialog-close class="${cn(button.base, button.primary)}">OK</media-alert-dialog-close>
|
||||
</div>
|
||||
</div>
|
||||
</media-error-dialog>
|
||||
|
||||
<media-controls data-controls="" class="${controls}">
|
||||
<media-tooltip-group>
|
||||
<div class="${buttonGroupStart}">
|
||||
<media-play-button commandfor="play-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.play.button)}">
|
||||
${renderIcon('restart', { class: cn(icon, iconState.play.restart) })}
|
||||
${renderIcon('play', { class: cn(icon, iconState.play.play) })}
|
||||
${renderIcon('pause', { class: cn(icon, iconState.play.pause) })}
|
||||
</media-play-button>
|
||||
<media-tooltip id="play-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="grow" aria-hidden="true"></div>
|
||||
|
||||
<div class="${buttonGroupEnd}">
|
||||
<media-mute-button commandfor="live-video-volume-popover" class="${cn(button.base, button.subtle, button.icon, iconState.mute.button)}">
|
||||
${renderIcon('volume-off', { class: cn(icon, iconState.mute.volumeOff) })}
|
||||
${renderIcon('volume-low', { class: cn(icon, iconState.mute.volumeLow) })}
|
||||
${renderIcon('volume-high', { class: cn(icon, iconState.mute.volumeHigh) })}
|
||||
</media-mute-button>
|
||||
|
||||
<media-popover id="live-video-volume-popover" open-on-hover delay="200" close-delay="100" side="top" class="${cn(popup.popover, popup.volume)}">
|
||||
<media-volume-slider class="${slider.root}" orientation="vertical" thumb-alignment="edge">
|
||||
<media-slider-track class="${slider.track}">
|
||||
<media-slider-fill class="${cn(slider.fill.base, slider.fill.fill)}"></media-slider-fill>
|
||||
</media-slider-track>
|
||||
<media-slider-thumb class="${cn(slider.thumb.base, slider.thumb.persistent)}"></media-slider-thumb>
|
||||
</media-volume-slider>
|
||||
</media-popover>
|
||||
<media-captions-button commandfor="captions-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.captions.button)}">
|
||||
${renderIcon('captions-off', { class: cn(icon, iconState.captions.off) })}
|
||||
${renderIcon('captions-on', { class: cn(icon, iconState.captions.on) })}
|
||||
</media-captions-button>
|
||||
<media-tooltip id="captions-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
<media-cast-button commandfor="cast-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.cast.button)}">
|
||||
${renderIcon('cast-enter', { class: cn(icon, iconState.cast.enter) })}
|
||||
${renderIcon('cast-exit', { class: cn(icon, iconState.cast.exit) })}
|
||||
</media-cast-button>
|
||||
<media-tooltip id="cast-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
<media-pip-button commandfor="pip-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.pip.button)}">
|
||||
${renderIcon('pip-enter', { class: cn(icon, iconState.pip.off) })}
|
||||
${renderIcon('pip-exit', { class: cn(icon, iconState.pip.on) })}
|
||||
</media-pip-button>
|
||||
<media-tooltip id="pip-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
<media-fullscreen-button commandfor="fullscreen-tooltip" class="${cn(button.base, button.subtle, button.icon, iconState.fullscreen.button)}">
|
||||
${renderIcon('fullscreen-enter', { class: cn(icon, iconState.fullscreen.enter) })}
|
||||
${renderIcon('fullscreen-exit', { class: cn(icon, iconState.fullscreen.exit) })}
|
||||
</media-fullscreen-button>
|
||||
<media-tooltip id="fullscreen-tooltip" side="top" class="${cn(popup.tooltip)}"></media-tooltip>
|
||||
</div>
|
||||
</media-tooltip-group>
|
||||
</media-controls>
|
||||
|
||||
<div class="${overlay}"></div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
export class LiveVideoSkinTailwindElement extends SkinElement {
|
||||
static readonly tagName = 'live-video-skin-tailwind';
|
||||
static template = createTemplate(getTemplateHTML());
|
||||
}
|
||||
|
||||
safeDefine(LiveVideoSkinTailwindElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[LiveVideoSkinTailwindElement.tagName]: LiveVideoSkinTailwindElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import { renderIcon } from '@videojs/icons/render';
|
||||
import { createShadowStyle, createTemplate } from '@videojs/utils/dom';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { SkinElement } from '../skin-element';
|
||||
import styles from './skin.css?inline';
|
||||
|
||||
// Reuse the video preset's UI element registrations (player, container,
|
||||
// controls, buttons, etc.) — the live variant only differs in its template.
|
||||
import '../video/ui';
|
||||
|
||||
function getTemplateHTML() {
|
||||
return /*html*/ `
|
||||
<media-container class="media-default-skin media-default-skin--video">
|
||||
<!-- @deprecated slot="media" is no longer required, use the default slot instead -->
|
||||
<slot name="media"></slot>
|
||||
<slot></slot>
|
||||
|
||||
<media-poster>
|
||||
<slot name="poster"></slot>
|
||||
</media-poster>
|
||||
|
||||
<media-buffering-indicator class="media-buffering-indicator">
|
||||
<div class="media-surface">
|
||||
${renderIcon('spinner', { class: 'media-icon' })}
|
||||
</div>
|
||||
</media-buffering-indicator>
|
||||
|
||||
<media-error-dialog class="media-error">
|
||||
<div class="media-error__dialog media-surface">
|
||||
<div class="media-error__content">
|
||||
<media-alert-dialog-title class="media-error__title">Something went wrong.</media-alert-dialog-title>
|
||||
<media-alert-dialog-description class="media-error__description"></media-alert-dialog-description>
|
||||
</div>
|
||||
<div class="media-error__actions">
|
||||
<media-alert-dialog-close class="media-button media-button--primary">OK</media-alert-dialog-close>
|
||||
</div>
|
||||
</div>
|
||||
</media-error-dialog>
|
||||
|
||||
<media-controls class="media-surface media-controls">
|
||||
<media-tooltip-group>
|
||||
<div class="media-button-group">
|
||||
<media-play-button commandfor="play-tooltip" class="media-button media-button--subtle media-button--icon media-button--play">
|
||||
${renderIcon('restart', { class: 'media-icon media-icon--restart' })}
|
||||
${renderIcon('play', { class: 'media-icon media-icon--play' })}
|
||||
${renderIcon('pause', { class: 'media-icon media-icon--pause' })}
|
||||
</media-play-button>
|
||||
<media-tooltip id="play-tooltip" side="top" class="media-surface media-tooltip"></media-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="media-time-controls" aria-hidden="true"></div>
|
||||
|
||||
<div class="media-button-group">
|
||||
<media-mute-button commandfor="live-video-volume-popover" class="media-button media-button--subtle media-button--icon media-button--mute">
|
||||
${renderIcon('volume-off', { class: 'media-icon media-icon--volume-off' })}
|
||||
${renderIcon('volume-low', { class: 'media-icon media-icon--volume-low' })}
|
||||
${renderIcon('volume-high', { class: 'media-icon media-icon--volume-high' })}
|
||||
</media-mute-button>
|
||||
|
||||
<media-popover id="live-video-volume-popover" open-on-hover delay="200" close-delay="100" side="top" class="media-surface media-popover media-popover--volume">
|
||||
<media-volume-slider class="media-slider" orientation="vertical" thumb-alignment="edge">
|
||||
<media-slider-track class="media-slider__track">
|
||||
<media-slider-fill class="media-slider__fill"></media-slider-fill>
|
||||
</media-slider-track>
|
||||
<media-slider-thumb class="media-slider__thumb media-slider__thumb--persistent"></media-slider-thumb>
|
||||
</media-volume-slider>
|
||||
</media-popover>
|
||||
|
||||
<media-captions-button commandfor="captions-tooltip" class="media-button media-button--subtle media-button--icon media-button--captions">
|
||||
${renderIcon('captions-off', { class: 'media-icon media-icon--captions-off' })}
|
||||
${renderIcon('captions-on', { class: 'media-icon media-icon--captions-on' })}
|
||||
</media-captions-button>
|
||||
<media-tooltip id="captions-tooltip" side="top" class="media-surface media-tooltip"></media-tooltip>
|
||||
|
||||
<media-cast-button commandfor="cast-tooltip" class="media-button media-button--subtle media-button--icon media-button--cast">
|
||||
${renderIcon('cast-enter', { class: 'media-icon media-icon--cast-enter' })}
|
||||
${renderIcon('cast-exit', { class: 'media-icon media-icon--cast-exit' })}
|
||||
</media-cast-button>
|
||||
<media-tooltip id="cast-tooltip" side="top" class="media-surface media-tooltip"></media-tooltip>
|
||||
|
||||
<media-pip-button commandfor="pip-tooltip" class="media-button media-button--subtle media-button--icon media-button--pip">
|
||||
${renderIcon('pip-enter', { class: 'media-icon media-icon--pip-enter' })}
|
||||
${renderIcon('pip-exit', { class: 'media-icon media-icon--pip-exit' })}
|
||||
</media-pip-button>
|
||||
<media-tooltip id="pip-tooltip" side="top" class="media-surface media-tooltip"></media-tooltip>
|
||||
|
||||
<media-fullscreen-button commandfor="fullscreen-tooltip" class="media-button media-button--subtle media-button--icon media-button--fullscreen">
|
||||
${renderIcon('fullscreen-enter', { class: 'media-icon media-icon--fullscreen-enter' })}
|
||||
${renderIcon('fullscreen-exit', { class: 'media-icon media-icon--fullscreen-exit' })}
|
||||
</media-fullscreen-button>
|
||||
<media-tooltip id="fullscreen-tooltip" side="top" class="media-surface media-tooltip"></media-tooltip>
|
||||
</div>
|
||||
</media-tooltip-group>
|
||||
</media-controls>
|
||||
|
||||
<div class="media-overlay"></div>
|
||||
|
||||
<!-- Hotkeys -->
|
||||
<media-hotkey keys="Space" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="k" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="m" action="toggleMuted"></media-hotkey>
|
||||
<media-hotkey keys="f" action="toggleFullscreen"></media-hotkey>
|
||||
<media-hotkey keys="c" action="toggleSubtitles"></media-hotkey>
|
||||
<media-hotkey keys="i" action="togglePictureInPicture"></media-hotkey>
|
||||
<media-hotkey keys="ArrowUp" action="volumeStep" value="0.05"></media-hotkey>
|
||||
<media-hotkey keys="ArrowDown" action="volumeStep" value="-0.05"></media-hotkey>
|
||||
|
||||
<!-- Gestures -->
|
||||
<media-gesture type="tap" action="togglePaused" pointer="mouse" region="center"></media-gesture>
|
||||
<media-gesture type="tap" action="toggleControls" pointer="touch"></media-gesture>
|
||||
<media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
export class LiveVideoSkinElement extends SkinElement {
|
||||
static readonly tagName = 'live-video-skin';
|
||||
static styles = createShadowStyle(styles);
|
||||
static template = createTemplate(getTemplateHTML());
|
||||
}
|
||||
|
||||
safeDefine(LiveVideoSkinElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[LiveVideoSkinElement.tagName]: LiveVideoSkinElement;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user