import cn from 'classnames'; import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState, } from 'react'; import { useLazyReady } from '@anton.bobrov/react-hooks'; import { ILazyVideoProps } from './types'; import { BaseVideo } from '../BaseVideo'; import { prefixedClasNames } from '../../utils/prefixedClassNames'; /** * LazyVideo component for rendering videos with lazy loading functionality. * * This component optimizes video loading by only loading videos when they enter * the viewport, improving performance and reducing bandwidth usage. * * @link See examples https://antonbobrov.github.io/react-kit/?path=/docs/video-lazyvideo--docs * * @requires Requires styles: `@import '~@anton.bobrov/react-components/lib/styles/components/LazyVideo';` */ export const LazyVideo = forwardRef( ( { className, style, position = 'cover', onLoadedMetadata, loading = 'lazy', hasAlpha = true, ...videoProps }, ref, ) => { const [videoRef, setVideoRef] = useState(null); useImperativeHandle(ref, () => videoRef!); const wrapperRef = useRef(null); const [canLoad, setCanLoad] = useState(false); const [isLoaded, setIsLoaded] = useState(false); const isLazy = loading === 'lazy'; useLazyReady({ ref: wrapperRef, onIn: () => setCanLoad(true), isDisabled: !isLazy, }); useEffect(() => { if (!isLazy) { setCanLoad(true); } }, [isLazy]); const classNames = prefixedClasNames( 'lazy-video', position, hasAlpha && 'has-alpha', isLoaded && 'is-loaded', ); return (
{canLoad && ( { onLoadedMetadata?.(event); setIsLoaded(true); }} /> )}
); }, ); LazyVideo.displayName = 'LazyVideo';