UNPKG

@supunlakmal/hooks

Version:

A collection of reusable React hooks

106 lines 4.64 kB
import { useState, useEffect, useCallback } from 'react'; /** * Custom hook to manage fullscreen state for a specific element. * * @param {RefObject<HTMLElement>} ref - Ref attached to the target element. * @returns {UseFullscreenResult} An object with fullscreen status and control functions. */ export const useFullscreen = (ref) => { // Get the initial state based on the standard API if possible const [isFullscreen, setIsFullscreen] = useState(() => !!(typeof document !== 'undefined' && document.fullscreenElement && document.fullscreenElement === ref.current)); // Check for API support using the standard property const isSupported = !!(typeof document !== 'undefined' && document.fullscreenEnabled); const getFullscreenElement = () => { if (typeof document === 'undefined') return null; const doc = document; // Prioritize standard, then fall back to prefixed versions return (doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement || null); }; const handleFullscreenChange = useCallback(() => { setIsFullscreen(!!getFullscreenElement() && getFullscreenElement() === ref.current); }, [ref]); useEffect(() => { if (!isSupported || typeof document === 'undefined') return; // Still need prefixed event names for listeners document.addEventListener('fullscreenchange', handleFullscreenChange); document.addEventListener('webkitfullscreenchange', handleFullscreenChange); document.addEventListener('mozfullscreenchange', handleFullscreenChange); document.addEventListener('msfullscreenchange', handleFullscreenChange); // Update state on mount handleFullscreenChange(); return () => { document.removeEventListener('fullscreenchange', handleFullscreenChange); document.removeEventListener('webkitfullscreenchange', handleFullscreenChange); document.removeEventListener('mozfullscreenchange', handleFullscreenChange); document.removeEventListener('msfullscreenchange', handleFullscreenChange); }; }, [isSupported, handleFullscreenChange]); const enterFullscreen = useCallback(async () => { if (!isSupported || !ref.current) return; const element = ref.current; try { // Attempt standard first, then fallbacks if (element.requestFullscreen) await element.requestFullscreen(); else if (element.webkitRequestFullscreen) await element.webkitRequestFullscreen(); else if (element.mozRequestFullScreen) await element.mozRequestFullScreen(); else if (element.msRequestFullscreen) await element.msRequestFullscreen(); else console.warn('Fullscreen API not fully supported on this element.'); } catch (error) { console.error('Failed to enter fullscreen:', error); setIsFullscreen(false); // Reset state on failure } }, [isSupported, ref]); const exitFullscreen = useCallback(async () => { if (!isSupported || !getFullscreenElement()) return; const doc = document; try { // Attempt standard first, then fallbacks if (doc.exitFullscreen) await doc.exitFullscreen(); else if (doc.webkitExitFullscreen) await doc.webkitExitFullscreen(); else if (doc.mozCancelFullScreen) await doc.mozCancelFullScreen(); else if (doc.msExitFullscreen) await doc.msExitFullscreen(); else console.warn('Exit Fullscreen API not fully supported on this document.'); } catch (error) { console.error('Failed to exit fullscreen:', error); } }, [isSupported]); const toggleFullscreen = useCallback(async () => { const currentFullscreenElement = getFullscreenElement(); if (currentFullscreenElement && currentFullscreenElement === ref.current) { await exitFullscreen(); } else { await enterFullscreen(); } }, [enterFullscreen, exitFullscreen, ref]); // Use getFullscreenElement within toggle return { isFullscreen, enterFullscreen, exitFullscreen, toggleFullscreen, isSupported, }; }; //# sourceMappingURL=useFullscreen.js.map