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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 28x 28x 25x 25x 28x 3x 28x 25x 25x 25x 3x 1x 1x 2x 25x 25x 25x 25x 28x 6x 6x | /**
* useWindowSize - Shared hook for responsive window dimensions
*
* @korean 윈도우크기훅 - 반응형 창 크기를 위한 공유 훅
*
* Eliminates duplication across screen components
*/
import { useCallback, useEffect, useState } from "react";
export interface WindowSize {
readonly width: number;
readonly height: number;
}
export interface UseWindowSizeOptions {
/**
* Initial width if window is not available (SSR)
* @default 1200
*/
readonly initialWidth?: number;
/**
* Initial height if window is not available (SSR)
* @default 800
*/
readonly initialHeight?: number;
/**
* Debounce delay in milliseconds
* @default 0
*/
readonly debounceMs?: number;
}
/**
* Hook to track window dimensions with optional debouncing
*
* @korean 윈도우 크기를 추적하는 훅 (선택적 디바운싱 지원)
*
* @param options - Configuration options
* @returns Current window dimensions
*
* @example
* ```tsx
* const { width, height } = useWindowSize();
* const isMobile = width < 768;
* ```
*/
export function useWindowSize(options: UseWindowSizeOptions = {}): WindowSize {
const { initialWidth = 1200, initialHeight = 800, debounceMs = 0 } = options;
const [size, setSize] = useState<WindowSize>(() => {
// Check if window is available (SSR safety)
Eif (typeof window !== "undefined") {
return {
width: window.innerWidth,
height: window.innerHeight,
};
}
return {
width: initialWidth,
height: initialHeight,
};
});
const handleResize = useCallback(() => {
setSize({
width: window.innerWidth,
height: window.innerHeight,
});
}, []);
useEffect(() => {
// Safety check for SSR
Iif (typeof window === "undefined") return;
let timeoutId: ReturnType<typeof setTimeout> | null = null;
const debouncedResize = () => {
if (debounceMs > 0) {
Iif (timeoutId) clearTimeout(timeoutId);
timeoutId = setTimeout(handleResize, debounceMs);
} else {
handleResize();
}
};
window.addEventListener("resize", debouncedResize);
return () => {
window.removeEventListener("resize", debouncedResize);
if (timeoutId) clearTimeout(timeoutId);
};
}, [handleResize, debounceMs]);
return size;
}
/**
* Hook to determine if current viewport is mobile-sized
*
* @korean 현재 뷰포트가 모바일 크기인지 확인하는 훅
*
* @param breakpoint - Width threshold for mobile (default: 768)
* @returns True if viewport width is less than breakpoint
*
* @example
* ```tsx
* const isMobile = useIsMobile();
* const isMobileCustom = useIsMobile(640);
* ```
*/
export function useIsMobile(breakpoint = 768): boolean {
const { width } = useWindowSize();
return width < breakpoint;
}
export default useWindowSize;
|