UNPKG

@qazuor/react-hooks

Version:

A comprehensive collection of production-ready React hooks for modern web applications. Features type-safe implementations, extensive testing, and zero dependencies. Includes hooks for state management, browser APIs, user interactions, and development uti

79 lines (71 loc) 2.65 kB
import { useCallback, useEffect, useState } from 'react'; interface UseVisibilityChangeOptions { /** Callback when document becomes visible */ onVisible?: () => void; /** Callback when document becomes hidden */ onHidden?: () => void; /** Whether to start monitoring immediately */ startImmediately?: boolean; } interface UseVisibilityChangeReturn { /** Whether the document is currently visible */ isVisible: boolean; /** Start monitoring visibility changes */ start: () => void; /** Stop monitoring visibility changes */ stop: () => void; } /** * useVisibilityChange * * @description Tracks the visibility state of the current document (i.e., whether the tab is in the foreground). * Returns `true` if the document is visible, or `false` if it's hidden. * Provides methods to start and stop monitoring. * * @param {UseVisibilityChangeOptions} [options] - Optional configuration. * @returns {UseVisibilityChangeReturn} - An object containing the current visibility state and control methods. * * @example * ```ts * const { isVisible, start, stop } = useVisibilityChange({ startImmediately: true }); * * useEffect(() => { *   console.log(isVisible ? 'Tab is active' : 'Tab is hidden'); * }, [isVisible]); * * // To manually control monitoring: * // const { isVisible, start, stop } = useVisibilityChange({ startImmediately: false }); * // // ... later ... * // start(); * ``` */ export function useVisibilityChange({ onVisible, onHidden, startImmediately = true }: UseVisibilityChangeOptions = {}): UseVisibilityChangeReturn { const [isVisible, setIsVisible] = useState(!document.hidden); const [isMonitoring, setIsMonitoring] = useState(startImmediately); const handleVisibilityChange = useCallback(() => { const newVisibility = !document.hidden; setIsVisible(newVisibility); if (newVisibility) { onVisible?.(); } else { onHidden?.(); } }, [onVisible, onHidden, isMonitoring]); const start = useCallback(() => setIsMonitoring(true), []); const stop = useCallback(() => setIsMonitoring(false), []); useEffect(() => { if (isMonitoring) { document.addEventListener('visibilitychange', handleVisibilityChange); return () => { document.removeEventListener('visibilitychange', handleVisibilityChange); }; } else { document.removeEventListener('visibilitychange', handleVisibilityChange); } }, [isMonitoring, handleVisibilityChange]); return { isVisible, start, stop }; }