/** * 반응형 스마트 기본값 생성 유틸리티 */ import { ComponentData } from "@/types/screen-management"; import { ResponsiveComponentConfig, BREAKPOINTS } from "@/types/responsive"; /** * 컴포넌트 크기에 따른 스마트 기본값 생성 * * 로직: * - 작은 컴포넌트 (너비 25% 이하): 모바일에서도 같은 너비 유지 * - 중간 컴포넌트 (너비 25-50%): 모바일에서 전체 너비로 확장 * - 큰 컴포넌트 (너비 50% 이상): 모든 디바이스에서 전체 너비 */ export function generateSmartDefaults( component: ComponentData, screenWidth: number = 1920, rowComponentCount: number = 1, // 같은 행에 있는 컴포넌트 개수 ): ResponsiveComponentConfig["responsive"] { // 특정 컴포넌트는 항상 전체 너비 (datatable, table-list 등) const fullWidthComponents = ["datatable", "data-table", "table-list", "repeater-field-group"]; const componentId = (component as any).componentId || (component as any).id; const componentType = (component as any).componentType || component.type; if (fullWidthComponents.includes(componentId) || fullWidthComponents.includes(componentType)) { return { desktop: { gridColumns: 12, // 전체 너비 order: 1, hide: false, }, tablet: { gridColumns: 8, // 전체 너비 order: 1, hide: false, }, mobile: { gridColumns: 4, // 전체 너비 order: 1, hide: false, }, }; } const componentWidthPercent = (component.size.width / screenWidth) * 100; // 같은 행에 여러 컴포넌트가 있으면 컬럼을 나눔 if (rowComponentCount > 1) { const desktopColumns = Math.round(12 / rowComponentCount); const tabletColumns = Math.round(8 / rowComponentCount); const mobileColumns = 4; // 모바일에서는 항상 전체 너비 return { desktop: { gridColumns: desktopColumns, order: 1, hide: false, }, tablet: { gridColumns: tabletColumns, order: 1, hide: false, }, mobile: { gridColumns: mobileColumns, order: 1, hide: false, }, }; } // 매우 작은 컴포넌트 (10% 이하, 예: 버튼) else if (componentWidthPercent <= 10) { return { desktop: { gridColumns: 1, // 12컬럼 중 1개 (~8%) order: 1, hide: false, }, tablet: { gridColumns: 1, // 8컬럼 중 1개 (~12.5%) order: 1, hide: false, }, mobile: { gridColumns: 1, // 4컬럼 중 1개 (25%) order: 1, hide: false, }, }; } // 작은 컴포넌트 (10-25%) else if (componentWidthPercent <= 25) { return { desktop: { gridColumns: 3, // 12컬럼 중 3개 (25%) order: 1, hide: false, }, tablet: { gridColumns: 2, // 8컬럼 중 2개 (25%) order: 1, hide: false, }, mobile: { gridColumns: 1, // 4컬럼 중 1개 (25%) order: 1, hide: false, }, }; } // 중간 컴포넌트 (25-50%) else if (componentWidthPercent <= 50) { return { desktop: { gridColumns: 6, // 12컬럼 중 6개 (50%) order: 1, hide: false, }, tablet: { gridColumns: 4, // 8컬럼 중 4개 (50%) order: 1, hide: false, }, mobile: { gridColumns: 4, // 4컬럼 전체 (100%) order: 1, hide: false, }, }; } // 큰 컴포넌트 (50% 이상) else { return { desktop: { gridColumns: 12, // 전체 너비 order: 1, hide: false, }, tablet: { gridColumns: 8, // 전체 너비 order: 1, hide: false, }, mobile: { gridColumns: 4, // 전체 너비 order: 1, hide: false, }, }; } } /** * 컴포넌트에 반응형 설정이 없을 경우 자동 생성 */ export function ensureResponsiveConfig(component: ComponentData, screenWidth?: number): ComponentData { if (component.responsiveConfig) { return component; } return { ...component, responsiveConfig: { designerPosition: { x: component.position.x, y: component.position.y, width: component.size.width, height: component.size.height, }, useSmartDefaults: true, responsive: generateSmartDefaults(component, screenWidth), }, }; }