diff --git a/frontend/components/report/designer/CanvasComponent.tsx b/frontend/components/report/designer/CanvasComponent.tsx
index efb8107b..5f9b0aef 100644
--- a/frontend/components/report/designer/CanvasComponent.tsx
+++ b/frontend/components/report/designer/CanvasComponent.tsx
@@ -1,6 +1,6 @@
"use client";
-import { useRef, useState } from "react";
+import { useRef, useState, useEffect } from "react";
import { ComponentConfig } from "@/types/report";
import { useReportDesigner } from "@/contexts/ReportDesignerContext";
@@ -46,7 +46,7 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
};
// 마우스 이동 핸들러 (전역)
- useState(() => {
+ useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (isDragging) {
const newX = Math.max(0, e.clientX - dragStart.x);
@@ -74,7 +74,7 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
document.removeEventListener("mouseup", handleMouseUp);
};
}
- });
+ }, [isDragging, isResizing, dragStart, resizeStart, component.id, updateComponent]);
// 표시할 값 결정
const getDisplayValue = (): string => {
@@ -119,14 +119,17 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
텍스트 필드
{hasBinding && ● 연결됨}
- e.stopPropagation()}
- />
+
+ {displayValue}
+
);
@@ -137,7 +140,16 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
레이블
{hasBinding && ● 연결됨}
- {displayValue}
+
+ {displayValue}
+
);
@@ -218,15 +230,17 @@ export function CanvasComponent({ component }: CanvasComponentProps) {
return (
diff --git a/frontend/components/report/designer/ReportDesignerCanvas.tsx b/frontend/components/report/designer/ReportDesignerCanvas.tsx
index c56a298e..0cea297f 100644
--- a/frontend/components/report/designer/ReportDesignerCanvas.tsx
+++ b/frontend/components/report/designer/ReportDesignerCanvas.tsx
@@ -1,6 +1,6 @@
"use client";
-import { useRef } from "react";
+import { useRef, useEffect } from "react";
import { useDrop } from "react-dnd";
import { useReportDesigner } from "@/contexts/ReportDesignerContext";
import { ComponentConfig } from "@/types/report";
@@ -9,7 +9,8 @@ import { v4 as uuidv4 } from "uuid";
export function ReportDesignerCanvas() {
const canvasRef = useRef
(null);
- const { components, addComponent, canvasWidth, canvasHeight, selectComponent } = useReportDesigner();
+ const { components, addComponent, canvasWidth, canvasHeight, selectComponent, selectedComponentId, removeComponent } =
+ useReportDesigner();
const [{ isOver }, drop] = useDrop(() => ({
accept: "component",
@@ -60,6 +61,18 @@ export function ReportDesignerCanvas() {
}
};
+ // Delete 키 삭제 처리
+ useEffect(() => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (e.key === "Delete" && selectedComponentId) {
+ removeComponent(selectedComponentId);
+ }
+ };
+
+ window.addEventListener("keydown", handleKeyDown);
+ return () => window.removeEventListener("keydown", handleKeyDown);
+ }, [selectedComponentId, removeComponent]);
+
return (
{/* 작업 영역 제목 */}
diff --git a/frontend/components/report/designer/ReportDesignerRightPanel.tsx b/frontend/components/report/designer/ReportDesignerRightPanel.tsx
index ae3e4e66..5989e2d5 100644
--- a/frontend/components/report/designer/ReportDesignerRightPanel.tsx
+++ b/frontend/components/report/designer/ReportDesignerRightPanel.tsx
@@ -131,49 +131,173 @@ export function ReportDesignerRightPanel() {
- {/* 글꼴 크기 */}
-
-
-
- updateComponent(selectedComponent.id, {
- fontSize: parseInt(e.target.value) || 13,
- })
- }
- className="h-8"
- />
-
+ {/* 스타일링 섹션 */}
+
+
스타일
- {/* 글꼴 색상 */}
-
-
-
- updateComponent(selectedComponent.id, {
- fontColor: e.target.value,
- })
- }
- className="h-8"
- />
-
+ {/* 글꼴 크기 */}
+
+
+
+ updateComponent(selectedComponent.id, {
+ fontSize: parseInt(e.target.value) || 13,
+ })
+ }
+ className="h-8"
+ />
+
- {/* 배경 색상 */}
-
-
-
- updateComponent(selectedComponent.id, {
- backgroundColor: e.target.value,
- })
- }
- className="h-8"
- />
+ {/* 글꼴 색상 */}
+
+
+ {/* 텍스트 정렬 (텍스트/라벨만) */}
+ {(selectedComponent.type === "text" || selectedComponent.type === "label") && (
+
+
+
+
+ )}
+
+ {/* 글꼴 굵기 (텍스트/라벨만) */}
+ {(selectedComponent.type === "text" || selectedComponent.type === "label") && (
+
+
+
+
+ )}
+
+ {/* 배경 색상 */}
+
+
+ {/* 테두리 */}
+
{/* 데이터 바인딩 (텍스트/라벨/테이블 컴포넌트) */}
diff --git a/frontend/components/report/designer/ReportPreviewModal.tsx b/frontend/components/report/designer/ReportPreviewModal.tsx
index f64daaea..f271a003 100644
--- a/frontend/components/report/designer/ReportPreviewModal.tsx
+++ b/frontend/components/report/designer/ReportPreviewModal.tsx
@@ -104,6 +104,11 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
top: `${component.y}px`,
width: `${component.width}px`,
height: `${component.height}px`,
+ backgroundColor: component.backgroundColor,
+ border: component.borderWidth
+ ? `${component.borderWidth}px solid ${component.borderColor}`
+ : "none",
+ padding: "8px",
}}
>
{component.type === "text" && (
@@ -111,7 +116,8 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
style={{
fontSize: `${component.fontSize}px`,
color: component.fontColor,
- backgroundColor: component.backgroundColor,
+ fontWeight: component.fontWeight,
+ textAlign: component.textAlign as "left" | "center" | "right",
}}
>
{displayValue}
@@ -120,11 +126,11 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
{component.type === "label" && (
{displayValue}