feat(packages): add poster component to video skins (#994)

This commit is contained in:
Sam Potts
2026-03-18 17:57:10 +11:00
committed by GitHub
parent b9bada9567
commit 59bbf6c209
45 changed files with 445 additions and 171 deletions
@@ -17,30 +17,6 @@
border-radius: inherit;
}
/* ==========================================================================
Poster Image
========================================================================== */
.media-default-skin > img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: var(--media-object-fit, contain);
object-position: var(--media-object-position, center);
transition: opacity 0.25s;
pointer-events: none;
border-radius: inherit;
&:not([data-visible]) {
opacity: 0;
}
}
/* ==========================================================================
Fullscreen
========================================================================== */
.media-default-skin:fullscreen ::slotted(video),
.media-default-skin:fullscreen video {
object-fit: contain;
@@ -0,0 +1,34 @@
/* ==========================================================================
Poster Image
========================================================================== */
.media-default-skin media-poster,
.media-default-skin > img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
transition: opacity 0.25s;
pointer-events: none;
}
.media-default-skin media-poster:not([data-visible]),
.media-default-skin > img:not([data-visible]) {
opacity: 0;
}
.media-default-skin media-poster ::slotted(img) {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: var(--media-object-fit, contain);
object-position: var(--media-object-position, center);
border-radius: var(--media-video-border-radius);
}
.media-default-skin > img {
border-radius: inherit;
}
.media-default-skin:fullscreen media-poster ::slotted(img),
.media-default-skin:fullscreen > img {
object-fit: contain;
}
+2
View File
@@ -11,6 +11,7 @@
@import "./components/time.css";
@import "./components/buttons.css";
@import "./components/icons.css";
@import "./components/poster.css";
@import "./components/preview.css";
@import "./components/slider.css";
@import "./components/popup.css";
@@ -136,6 +137,7 @@
filter: blur(8px);
transition-property: scale, opacity, filter;
transition-duration: 150ms;
transition-timing-function: ease-out;
transform-origin: bottom;
pointer-events: none;
@@ -0,0 +1,21 @@
import { cn } from '@videojs/utils/style';
export const poster = (isShadowDOM: boolean) =>
cn(
'absolute inset-0 w-full h-full pointer-events-none',
// Fade in/out with the `data-visible` attribute
'transition-opacity duration-250',
'not-data-visible:opacity-0',
// In the shadow DOM, the class applies to the parent so we have to set styles on the slotted img.
isShadowDOM
? [
'[&_::slotted(img)]:absolute',
'[&_::slotted(img)]:inset-0',
'[&_::slotted(img)]:w-full',
'[&_::slotted(img)]:h-full',
'[&_::slotted(img)]:[object-fit:var(--media-object-fit,contain)]',
'[&_::slotted(img)]:[object-position:var(--media-object-position,center)]',
'[&_::slotted(img)]:rounded-(--media-video-border-radius)',
]
: 'rounded-[inherit] [object-fit:var(--media-object-fit,contain)] [object-position:var(--media-object-position,center)]'
);
@@ -33,11 +33,6 @@ export const root = (isShadowDOM: boolean) =>
'[@media(pointer:fine)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:300ms]',
'[@media(pointer:coarse)]:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:150ms]',
'motion-reduce:has-[[data-controls]:not([data-visible])]:[--media-controls-transition-duration:100ms]',
// Poster image
'[&>img]:absolute [&>img]:inset-0 [&>img]:w-full [&>img]:h-full [&>img]:rounded-[inherit]',
'[&>img]:[object-fit:var(--media-object-fit,contain)] [&>img]:[object-position:var(--media-object-position,center)] [&>img]:pointer-events-none',
'[&>img]:transition-opacity [&>img]:duration-250',
'[&>img:not([data-visible])]:opacity-0',
// Caption track CSS variables (consumed by the native caption bridge in light DOM)
'[--media-caption-track-y:-0.5rem]',
'[--media-caption-track-delay:calc(var(--media-controls-transition-delay)_+_25ms)]',
@@ -171,5 +166,6 @@ export { button } from './components/button';
export { icon, iconContainer, iconFlipped, iconHidden } from './components/icon';
export { overlay } from './components/overlay';
export { playbackRate } from './components/playback-rate';
export { poster } from './components/poster';
export { seek } from './components/seek';
export { time } from './components/time';