import { useState, useCallback, useEffect, type RefObject } from 'react'; interface UseFullscreenReturn { /** Whether the element is currently fullscreen */ isFullscreen: boolean; /** Enter fullscreen mode */ enterFullscreen: () => Promise; /** Exit fullscreen mode */ exitFullscreen: () => Promise; /** Toggle fullscreen mode */ toggleFullscreen: () => void; } /** * Hook to manage fullscreen mode for a container element. * Uses the Fullscreen API with fallback styling. * * @param containerRef - Ref to the element to make fullscreen * @returns Object with fullscreen state and control functions * * @example * ```tsx * const containerRef = useRef(null); * const { isFullscreen, toggleFullscreen } = useFullscreen(containerRef); * * return ( *
* *
Content here
*
* ); * ``` */ export function useFullscreen(containerRef: RefObject): UseFullscreenReturn { const [isFullscreen, setIsFullscreen] = useState(false); const enterFullscreen = useCallback(async () => { const container = containerRef.current; if (!container) return; try { if (container.requestFullscreen) { await container.requestFullscreen(); } else if ((container as any).webkitRequestFullscreen) { await (container as any).webkitRequestFullscreen(); } else if ((container as any).msRequestFullscreen) { await (container as any).msRequestFullscreen(); } } catch (err) { console.warn('Fullscreen API not available, using CSS fallback'); // CSS fallback handled by isFullscreen state setIsFullscreen(true); } }, [containerRef]); const exitFullscreen = useCallback(async () => { try { if (document.exitFullscreen) { await document.exitFullscreen(); } else if ((document as any).webkitExitFullscreen) { await (document as any).webkitExitFullscreen(); } else if ((document as any).msExitFullscreen) { await (document as any).msExitFullscreen(); } } catch (err) { // CSS fallback setIsFullscreen(false); } }, []); const toggleFullscreen = useCallback(() => { if (isFullscreen) { exitFullscreen(); } else { enterFullscreen(); } }, [isFullscreen, enterFullscreen, exitFullscreen]); // Listen for fullscreen change events useEffect(() => { const handleFullscreenChange = () => { const isCurrentlyFullscreen = !!( document.fullscreenElement || (document as any).webkitFullscreenElement || (document as any).msFullscreenElement ); setIsFullscreen(isCurrentlyFullscreen); }; document.addEventListener('fullscreenchange', handleFullscreenChange); document.addEventListener('webkitfullscreenchange', handleFullscreenChange); document.addEventListener('MSFullscreenChange', handleFullscreenChange); return () => { document.removeEventListener('fullscreenchange', handleFullscreenChange); document.removeEventListener('webkitfullscreenchange', handleFullscreenChange); document.removeEventListener('MSFullscreenChange', handleFullscreenChange); }; }, []); // Handle Escape key for CSS fallback mode useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape' && isFullscreen && !document.fullscreenElement) { setIsFullscreen(false); } }; document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown); }, [isFullscreen]); return { isFullscreen, enterFullscreen, exitFullscreen, toggleFullscreen, }; } export default useFullscreen;