diff --git a/dotcom-rendering/src/components/SelfHostedVideo.island.tsx b/dotcom-rendering/src/components/SelfHostedVideo.island.tsx index af71dcb0d8c..115a5b6e49c 100644 --- a/dotcom-rendering/src/components/SelfHostedVideo.island.tsx +++ b/dotcom-rendering/src/components/SelfHostedVideo.island.tsx @@ -370,6 +370,7 @@ export const SelfHostedVideo = ({ const adapted = useShouldAdapt(); const { renderingTarget } = useConfig(); const vidRef = useRef(null); + const playerContainerRef = useRef(null); const [isPlayable, setIsPlayable] = useState(false); const [isMuted, setIsMuted] = useState(true); const [showPosterImage, setShowPosterImage] = useState(false); @@ -808,8 +809,9 @@ export const SelfHostedVideo = ({ if (document.fullscreenElement) { void document.exitFullscreen(); + } else if (playerContainerRef.current) { + void playerContainerRef.current.requestFullscreen(); } - void video.requestFullscreen(); }; /** @@ -1013,6 +1015,7 @@ export const SelfHostedVideo = ({ FallbackImageComponent={FallbackImageComponent} currentTime={currentTime} ref={vidRef} + playerContainerRef={playerContainerRef} isMuted={isMuted} handleLoadedMetadata={handleLoadedMetadata} handleLoadedData={handleLoadedData} diff --git a/dotcom-rendering/src/components/SelfHostedVideoPlayer.tsx b/dotcom-rendering/src/components/SelfHostedVideoPlayer.tsx index 55bb1f8497d..eacc4c52d0e 100644 --- a/dotcom-rendering/src/components/SelfHostedVideoPlayer.tsx +++ b/dotcom-rendering/src/components/SelfHostedVideoPlayer.tsx @@ -36,6 +36,28 @@ const videoStyles = (aspectRatio: number) => css` aspect-ratio: ${aspectRatio}; `; +const playerContainerStyles = css` + &:fullscreen { + display: flex; + align-items: center; + justify-content: center; + background-color: ${palette('--video-fullscreen-background')}; + width: 100vw; + height: 100vh; + + /* Override the fixed aspect-ratio + width:100% on the video so it + fits within the screen while preserving its aspect ratio. */ + video { + width: 100%; + height: 100%; + max-width: 100vw; + max-height: 100vh; + aspect-ratio: auto; + object-fit: contain; + } + } +`; + const videoControlsStyles = css` height: 100%; width: 100%; @@ -143,6 +165,7 @@ export type Props = { isInteractive: boolean; iconsPosition: ControlsPosition; subtitlesPosition: SubtitlesPosition; + playerContainerRef: React.RefObject; }; /** @@ -196,6 +219,7 @@ export const SelfHostedVideoPlayer = forwardRef( isInteractive, iconsPosition, subtitlesPosition, + playerContainerRef, }: Props, ref: React.ForwardedRef, ) => { @@ -212,7 +236,7 @@ export const SelfHostedVideoPlayer = forwardRef( }-${atomId}`; return ( - <> +
{/* eslint-disable-next-line jsx-a11y/media-has-caption -- Not all videos require captions. */}
- + ); }, ); diff --git a/dotcom-rendering/src/paletteDeclarations.ts b/dotcom-rendering/src/paletteDeclarations.ts index cfc4e678b63..b5766738944 100644 --- a/dotcom-rendering/src/paletteDeclarations.ts +++ b/dotcom-rendering/src/paletteDeclarations.ts @@ -8433,6 +8433,10 @@ const paletteColours = { light: () => sourcePalette.neutral[93], dark: () => sourcePalette.neutral[93], }, + '--video-fullscreen-background': { + light: () => sourcePalette.neutral[0], + dark: () => sourcePalette.neutral[0], + }, '--video-icon': { light: () => sourcePalette.neutral[100], dark: () => sourcePalette.neutral[100],