'use client'; import React, { useRef, useEffect, forwardRef, ComponentProps, } from 'react'; import { MuxBackgroundVideo as MuxBackgroundVideoCore } from './mux-background-video.js'; export type MuxBackgroundVideoProps = ComponentProps<'video'> & MuxBackgroundVideoCore['config']; export type MuxBackgroundVideoRef = Partial; export const MuxBackgroundVideo = forwardRef< MuxBackgroundVideoRef, MuxBackgroundVideoProps >( ( { className, style, children, src, audio, debug, maxResolution, preload, ...props }, ref ) => { const videoRef = useRef(null); const muxRef = useRef(null); useEffect(() => { if (!videoRef.current) return; muxRef.current ??= new MuxBackgroundVideoCore(); muxRef.current.display = videoRef.current; muxRef.current.config = { audio, debug, maxResolution, preload, }; muxRef.current.src = src ?? ''; return () => { if (muxRef.current) { muxRef.current = null; } }; }, [src, audio, debug, maxResolution, preload]); return (
{children}
); } ); MuxBackgroundVideo.displayName = 'MuxBackgroundVideo'; // useComposedRefs.ts type PossibleRef = React.Ref | undefined; /** * Set a given ref to a given value * This utility takes care of different types of refs: callback refs and RefObject(s) */ function setRef(ref: PossibleRef, value: T): (() => void) | void | undefined { if (typeof ref === 'function') { return ref(value); } else if (ref !== null && ref !== undefined) { (ref as React.MutableRefObject).current = value; } } /** * A utility to compose multiple refs together * Accepts callback refs and RefObject(s) */ function composeRefs(...refs: PossibleRef[]): React.RefCallback { return (node) => { let hasCleanup = false; const cleanups = refs.map((ref) => { const cleanup = setRef(ref, node); if (!hasCleanup && typeof cleanup == 'function') { hasCleanup = true; } return cleanup; }); // React <19 will log an error to the console if a callback ref returns a // value. We don't use ref cleanups internally so this will only happen if a // user's ref callback returns a value, which we only expect if they are // using the cleanup functionality added in React 19. if (hasCleanup) { return () => { for (let i = 0; i < cleanups.length; i++) { const cleanup = cleanups[i]; if (typeof cleanup == 'function') { cleanup(); } else { setRef(refs[i], null); } } }; } }; } /** * A custom hook that composes multiple refs * Accepts callback refs and RefObject(s) */ function useComposedRefs(...refs: PossibleRef[]): React.RefCallback { // eslint-disable-next-line react-hooks/exhaustive-deps return React.useCallback(composeRefs(...refs), refs); }