import { useState, useEffect } from "react"; interface ViewportSize { width: number; height: number; availableWidth: number; availableHeight: number; sidebarWidth: number; headerHeight: number; } /** * 뷰포트 크기와 레이아웃 요소들을 고려한 사용 가능한 공간을 계산하는 훅 */ export const useViewportSize = () => { const [viewportSize, setViewportSize] = useState({ width: 0, height: 0, availableWidth: 0, availableHeight: 0, sidebarWidth: 0, headerHeight: 0, }); useEffect(() => { const updateViewportSize = () => { const width = window.innerWidth; const height = window.innerHeight; // 레이아웃 요소 크기 계산 const isDesktop = width >= 1024; // lg 브레이크포인트 const sidebarWidth = isDesktop ? 256 : 0; // w-64 = 256px const headerHeight = 56; // 대략적인 헤더 높이 (h-14 = 56px) // 사용 가능한 컨텐츠 영역 계산 const availableWidth = width - sidebarWidth; const availableHeight = height - headerHeight; setViewportSize({ width, height, availableWidth: Math.max(availableWidth, 300), // 최소 300px availableHeight: Math.max(availableHeight, 200), // 최소 200px sidebarWidth, headerHeight, }); }; updateViewportSize(); window.addEventListener("resize", updateViewportSize); return () => window.removeEventListener("resize", updateViewportSize); }, []); return viewportSize; }; /** * 특정 컨테이너의 실제 사용 가능한 크기를 계산 */ export const useContainerSize = (containerRef: React.RefObject) => { const [containerSize, setContainerSize] = useState({ width: 0, height: 0 }); const viewportSize = useViewportSize(); useEffect(() => { const updateContainerSize = () => { if (containerRef.current) { const rect = containerRef.current.getBoundingClientRect(); // 컨테이너 내부 여백 고려 const padding = 32; // p-4 * 2 = 32px const controlBarHeight = 48; // 컨트롤 바 높이 const availableWidth = Math.max(rect.width - padding, 300); const availableHeight = Math.max(rect.height - controlBarHeight - padding, 200); setContainerSize({ width: availableWidth, height: availableHeight, }); } }; updateContainerSize(); window.addEventListener("resize", updateContainerSize); return () => window.removeEventListener("resize", updateContainerSize); }, [containerRef, viewportSize]); return containerSize; };