All files / hooks useBreakpoint.ts

100% Statements 21/21
87.5% Branches 7/8
100% Functions 5/5
100% Lines 19/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 781x                                                               1x 6x     1x   4x               4x   4x   4x   4x   4x       4x 4x 4x     4x 4x 1x 3x 1x     4x              
import { useState, useEffect } from 'react';
import { type Breakpoint, type BreakpointResult } from '../types/index';
 
/**
 * Custom hook to track and respond to viewport breakpoint changes.
 * Provides responsive design information based on window width.
 *
 * @returns {BreakpointResult} An object containing:
 *   - isMobile: boolean (width < 768px)
 *   - isTablet: boolean (768px <= width < 1024px)
 *   - isDesktop: boolean (width >= 1024px)
 *   - current: Breakpoint type ('mobile' | 'tablet' | 'desktop')
 *
 * @example
 * // Basic usage
 * const { isMobile, current } = useBreakpoint();
 * if (isMobile) {
 *   // Render mobile component
 * }
 *
 * @example
 * // Conditional rendering
 * const { current } = useBreakpoint();
 * return (
 *   <div>
 *     {current === 'mobile' ? <MobileView /> : <DesktopView />}
 *   </div>
 * );
 *
 * @see BreakpointResult for return type structure
 * @see Breakpoint for available breakpoint values
 */
export function getInitialWidth(): number {
	return typeof window !== 'undefined' ? window.innerWidth : 0;
}
 
export function useBreakpoint(): BreakpointResult {
	// Initialize state with current window width (or 0 for SSR)
	const [width, setWidth] = useState<number>(getInitialWidth());
 
	/**
	 * Effect to handle window resize events
	 * - Adds event listener on mount
	 * - Removes event listener on unmount
	 * - Initializes with current width
	 */
	useEffect(() => {
		// Only execute in browser environment
		const handleResize = () => setWidth(window.innerWidth);
		// Set initial width
		window.addEventListener('resize', handleResize);
		// Add resize listener
		handleResize();
		// Cleanup function
		return () => window.removeEventListener('resize', handleResize);
	}, []);
 
	// Breakpoint calculations
	const isMobile = width < 768;
	const isTablet = width >= 768 && width < 1024;
	const isDesktop = width >= 1024;
 
	// Determine current breakpoint
	let current: Breakpoint = 'desktop';
	if (isMobile) {
		current = 'mobile';
	} else if (isTablet) {
		current = 'tablet';
	}
 
	return {
		isMobile,
		isTablet,
		isDesktop,
		current,
	};
}