refactor: 격자 시스템을 10px 단위로 단순화
- 복잡한 컬럼 시스템 제거 - 웹타입별 고정 픽셀 너비 사용 (10px 단위) - 격자 설정 패널 단순화 (컬럼 수 설정 제거) - 간격/여백 조정을 10px 단위로 변경 - 더 직관적이고 예측 가능한 레이아웃 시스템
This commit is contained in:
parent
7ab3781372
commit
c4290f2d0e
|
|
@ -2338,45 +2338,43 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
|||
snapToGrid: layout.gridSettings?.snapToGrid,
|
||||
});
|
||||
|
||||
// 웹타입별 기본 그리드 컬럼 수 계산
|
||||
const getDefaultGridColumns = (widgetType: string): number => {
|
||||
// 웹타입별 기본 너비 계산 (10px 단위 고정)
|
||||
const getDefaultWidth = (widgetType: string): number => {
|
||||
const widthMap: Record<string, number> = {
|
||||
// 텍스트 입력 계열 (넓게)
|
||||
text: 4, // 1/3 (33%)
|
||||
email: 4, // 1/3 (33%)
|
||||
tel: 3, // 1/4 (25%)
|
||||
url: 4, // 1/3 (33%)
|
||||
textarea: 6, // 절반 (50%)
|
||||
// 텍스트 입력 계열
|
||||
text: 200,
|
||||
email: 200,
|
||||
tel: 150,
|
||||
url: 250,
|
||||
textarea: 300,
|
||||
|
||||
// 숫자/날짜 입력 (중간)
|
||||
number: 2, // 2/12 (16.67%)
|
||||
decimal: 2, // 2/12 (16.67%)
|
||||
date: 3, // 1/4 (25%)
|
||||
datetime: 3, // 1/4 (25%)
|
||||
time: 2, // 2/12 (16.67%)
|
||||
// 숫자/날짜 입력
|
||||
number: 120,
|
||||
decimal: 120,
|
||||
date: 150,
|
||||
datetime: 180,
|
||||
time: 120,
|
||||
|
||||
// 선택 입력 (중간)
|
||||
select: 3, // 1/4 (25%)
|
||||
radio: 3, // 1/4 (25%)
|
||||
checkbox: 2, // 2/12 (16.67%)
|
||||
boolean: 2, // 2/12 (16.67%)
|
||||
// 선택 입력
|
||||
select: 180,
|
||||
radio: 180,
|
||||
checkbox: 120,
|
||||
boolean: 120,
|
||||
|
||||
// 코드/참조 (넓게)
|
||||
code: 3, // 1/4 (25%)
|
||||
entity: 4, // 1/3 (33%)
|
||||
// 코드/참조
|
||||
code: 180,
|
||||
entity: 200,
|
||||
|
||||
// 파일/이미지 (넓게)
|
||||
file: 4, // 1/3 (33%)
|
||||
image: 3, // 1/4 (25%)
|
||||
// 파일/이미지
|
||||
file: 250,
|
||||
image: 200,
|
||||
|
||||
// 기타
|
||||
button: 2, // 2/12 (16.67%)
|
||||
label: 2, // 2/12 (16.67%)
|
||||
button: 100,
|
||||
label: 100,
|
||||
};
|
||||
|
||||
const defaultColumns = widthMap[widgetType] || 3; // 기본값 3 (1/4, 25%)
|
||||
console.log("🎯 [ScreenDesigner] getDefaultGridColumns:", { widgetType, defaultColumns });
|
||||
return defaultColumns;
|
||||
return widthMap[widgetType] || 200; // 기본값 200px
|
||||
};
|
||||
|
||||
// 웹타입별 기본 높이 계산
|
||||
|
|
@ -2544,24 +2542,12 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
|||
const componentId = getComponentIdFromWebType(column.widgetType);
|
||||
// console.log(`🔄 폼 컨테이너 드롭: ${column.widgetType} → ${componentId}`);
|
||||
|
||||
// 웹타입별 적절한 gridColumns 계산
|
||||
const calculatedGridColumns = getDefaultGridColumns(column.widgetType);
|
||||
|
||||
// gridColumns에 맞는 실제 너비 계산
|
||||
const componentWidth =
|
||||
currentGridInfo && layout.gridSettings?.snapToGrid
|
||||
? calculateWidthFromColumns(
|
||||
calculatedGridColumns,
|
||||
currentGridInfo,
|
||||
layout.gridSettings as GridUtilSettings,
|
||||
)
|
||||
: defaultWidth;
|
||||
// 웹타입별 기본 너비 계산 (10px 단위 고정)
|
||||
const componentWidth = getDefaultWidth(column.widgetType);
|
||||
|
||||
console.log("🎯 폼 컨테이너 컴포넌트 생성:", {
|
||||
widgetType: column.widgetType,
|
||||
calculatedGridColumns,
|
||||
componentWidth,
|
||||
defaultWidth,
|
||||
});
|
||||
|
||||
newComponent = {
|
||||
|
|
@ -2576,7 +2562,6 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
|||
componentType: componentId, // DynamicComponentRenderer용 컴포넌트 타입
|
||||
position: { x: relativeX, y: relativeY, z: 1 } as Position,
|
||||
size: { width: componentWidth, height: getDefaultHeight(column.widgetType) },
|
||||
gridColumns: calculatedGridColumns,
|
||||
// 코드 타입인 경우 코드 카테고리 정보 추가
|
||||
...(column.widgetType === "code" &&
|
||||
column.codeCategory && {
|
||||
|
|
@ -2588,7 +2573,6 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
|||
labelColor: "#212121",
|
||||
labelFontWeight: "500",
|
||||
labelMarginBottom: "6px",
|
||||
width: `${(calculatedGridColumns / (layout.gridSettings?.columns || 12)) * 100}%`, // 퍼센트 너비
|
||||
},
|
||||
componentConfig: {
|
||||
type: componentId, // text-input, number-input 등
|
||||
|
|
@ -2611,36 +2595,14 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
|||
const componentId = getComponentIdFromWebType(column.widgetType);
|
||||
// console.log(`🔄 캔버스 드롭: ${column.widgetType} → ${componentId}`);
|
||||
|
||||
// 웹타입별 적절한 gridColumns 계산
|
||||
const calculatedGridColumns = getDefaultGridColumns(column.widgetType);
|
||||
|
||||
// gridColumns에 맞는 실제 너비 계산
|
||||
const componentWidth =
|
||||
currentGridInfo && layout.gridSettings?.snapToGrid
|
||||
? calculateWidthFromColumns(
|
||||
calculatedGridColumns,
|
||||
currentGridInfo,
|
||||
layout.gridSettings as GridUtilSettings,
|
||||
)
|
||||
: defaultWidth;
|
||||
// 웹타입별 기본 너비 계산 (10px 단위 고정)
|
||||
const componentWidth = getDefaultWidth(column.widgetType);
|
||||
|
||||
console.log("🎯 캔버스 컴포넌트 생성:", {
|
||||
widgetType: column.widgetType,
|
||||
calculatedGridColumns,
|
||||
componentWidth,
|
||||
defaultWidth,
|
||||
});
|
||||
|
||||
// 🔍 이미지 타입 드래그앤드롭 디버깅
|
||||
// if (column.widgetType === "image") {
|
||||
// console.log("🖼️ 이미지 컬럼 드래그앤드롭:", {
|
||||
// columnName: column.columnName,
|
||||
// widgetType: column.widgetType,
|
||||
// componentId,
|
||||
// column,
|
||||
// });
|
||||
// }
|
||||
|
||||
newComponent = {
|
||||
id: generateComponentId(),
|
||||
type: "component", // ✅ 새로운 컴포넌트 시스템 사용
|
||||
|
|
@ -2652,7 +2614,6 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
|||
componentType: componentId, // DynamicComponentRenderer용 컴포넌트 타입
|
||||
position: { x, y, z: 1 } as Position,
|
||||
size: { width: componentWidth, height: getDefaultHeight(column.widgetType) },
|
||||
gridColumns: calculatedGridColumns,
|
||||
// 코드 타입인 경우 코드 카테고리 정보 추가
|
||||
...(column.widgetType === "code" &&
|
||||
column.codeCategory && {
|
||||
|
|
@ -2664,7 +2625,6 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
|||
labelColor: "#000000", // 순수한 검정
|
||||
labelFontWeight: "500",
|
||||
labelMarginBottom: "8px",
|
||||
width: `${(calculatedGridColumns / (layout.gridSettings?.columns || 12)) * 100}%`, // 퍼센트 너비
|
||||
},
|
||||
componentConfig: {
|
||||
type: componentId, // text-input, number-input 등
|
||||
|
|
|
|||
|
|
@ -128,49 +128,14 @@ export const GridPanel: React.FC<GridPanelProps> = ({
|
|||
|
||||
{/* 설정 영역 */}
|
||||
<div className="flex-1 space-y-4 overflow-y-auto p-4">
|
||||
{/* 격자 구조 */}
|
||||
{/* 격자 구조 - 10px 단위 */}
|
||||
<div className="space-y-3">
|
||||
<h4 className="text-xs font-semibold">격자 구조</h4>
|
||||
<h4 className="text-xs font-semibold">격자 크기 (10px 단위)</h4>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="columns" className="text-xs font-medium">
|
||||
컬럼 수
|
||||
</Label>
|
||||
<div className="flex items-center gap-2">
|
||||
<Input
|
||||
id="columns"
|
||||
type="number"
|
||||
min={1}
|
||||
max={safeMaxColumns}
|
||||
value={gridSettings.columns}
|
||||
onChange={(e) => {
|
||||
const value = parseInt(e.target.value, 10);
|
||||
if (!isNaN(value) && value >= 1 && value <= safeMaxColumns) {
|
||||
updateSetting("columns", value);
|
||||
}
|
||||
}}
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
<span className="text-muted-foreground text-xs">/ {safeMaxColumns}</span>
|
||||
</div>
|
||||
<Slider
|
||||
id="columns-slider"
|
||||
min={1}
|
||||
max={safeMaxColumns}
|
||||
step={1}
|
||||
value={[gridSettings.columns]}
|
||||
onValueChange={([value]) => updateSetting("columns", value)}
|
||||
className="w-full"
|
||||
/>
|
||||
<div className="text-muted-foreground flex justify-between text-xs">
|
||||
<span>1열</span>
|
||||
<span>{safeMaxColumns}열</span>
|
||||
</div>
|
||||
{isColumnsTooSmall && (
|
||||
<p className="text-xs text-amber-600">
|
||||
⚠️ 컬럼 너비가 너무 작습니다 (최소 {MIN_COLUMN_WIDTH}px 권장)
|
||||
</p>
|
||||
)}
|
||||
<div className="bg-muted/50 rounded-md p-3">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
모든 컴포넌트는 10px 단위로 배치되고 크기가 조정됩니다.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
|
@ -181,7 +146,7 @@ export const GridPanel: React.FC<GridPanelProps> = ({
|
|||
id="gap"
|
||||
min={0}
|
||||
max={40}
|
||||
step={2}
|
||||
step={10}
|
||||
value={[gridSettings.gap]}
|
||||
onValueChange={([value]) => updateSetting("gap", value)}
|
||||
className="w-full"
|
||||
|
|
@ -200,7 +165,7 @@ export const GridPanel: React.FC<GridPanelProps> = ({
|
|||
id="padding"
|
||||
min={0}
|
||||
max={60}
|
||||
step={4}
|
||||
step={10}
|
||||
value={[gridSettings.padding]}
|
||||
onValueChange={([value]) => updateSetting("padding", value)}
|
||||
className="w-full"
|
||||
|
|
@ -288,14 +253,14 @@ export const GridPanel: React.FC<GridPanelProps> = ({
|
|||
<div className="border-t border-gray-200 bg-gray-50 p-3">
|
||||
<div className="text-muted-foreground text-xs">💡 격자 설정은 실시간으로 캔버스에 반영됩니다 </div>
|
||||
|
||||
{/* 해상도 및 격자 정보 */}
|
||||
{screenResolution && actualGridInfo && (
|
||||
{/* 해상도 정보 */}
|
||||
{screenResolution && (
|
||||
<>
|
||||
<Separator />
|
||||
<div className="space-y-3">
|
||||
<h4 className="font-medium text-gray-900">격자 정보</h4>
|
||||
<div className="space-y-2">
|
||||
<h4 className="text-xs font-semibold">화면 정보</h4>
|
||||
|
||||
<div className="space-y-2 text-xs" style={{ fontSize: "12px" }}>
|
||||
<div className="space-y-2 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">해상도:</span>
|
||||
<span className="font-mono">
|
||||
|
|
@ -304,25 +269,9 @@ export const GridPanel: React.FC<GridPanelProps> = ({
|
|||
</div>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">컬럼 너비:</span>
|
||||
<span className={`font-mono ${isColumnsTooSmall ? "text-destructive" : "text-gray-900"}`}>
|
||||
{actualGridInfo.columnWidth.toFixed(1)}px
|
||||
{isColumnsTooSmall && " (너무 작음)"}
|
||||
</span>
|
||||
<span className="text-muted-foreground">격자 단위:</span>
|
||||
<span className="font-mono text-primary">10px</span>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">사용 가능 너비:</span>
|
||||
<span className="font-mono">
|
||||
{(screenResolution.width - gridSettings.padding * 2).toLocaleString()}px
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{isColumnsTooSmall && (
|
||||
<div className="rounded-md bg-yellow-50 p-2 text-xs text-yellow-800">
|
||||
💡 컬럼이 너무 작습니다. 컬럼 수를 줄이거나 간격을 줄여보세요.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
Loading…
Reference in New Issue