"use client"; import type { CSSProperties, ReactNode } from "react"; import { DndContext, DragOverlay, type DragEndEvent, type DragStartEvent, } from "@dnd-kit/core"; import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable"; import { rectIntersection } from "@dnd-kit/core"; import type { Block, ButtonBlockProps, ImageBlockProps, ProjectConfig, TextBlockProps } from "@/features/editor/state/editorStore"; interface EditorCanvasProps { blocks: Block[]; rootBlocks: Block[]; selectedBlockId: string | null; editingBlockId: string | null; editingText: string; activeDragId: string | null; sensors: any; onCanvasEmptyClick: () => void; renderBlocks: (targetBlocks: Block[]) => ReactNode; handleDragStart: (event: DragStartEvent) => void; handleDragEnd: (event: DragEndEvent) => void; handleDragCancel: () => void; projectConfig: ProjectConfig; } export function EditorCanvas(props: EditorCanvasProps) { const { blocks, rootBlocks, activeDragId, sensors, onCanvasEmptyClick, renderBlocks, handleDragStart, handleDragEnd, handleDragCancel, projectConfig, } = props; const canvasInnerStyle: CSSProperties = {}; const preset = projectConfig.canvasPreset ?? "full"; const widthPx = typeof projectConfig.canvasWidthPx === "number" && projectConfig.canvasWidthPx > 0 ? projectConfig.canvasWidthPx : null; if (widthPx != null) { canvasInnerStyle.maxWidth = `${widthPx}px`; } else if (preset === "mobile") { canvasInnerStyle.maxWidth = "390px"; } else if (preset === "tablet") { canvasInnerStyle.maxWidth = "768px"; } else if (preset === "desktop") { canvasInnerStyle.maxWidth = "1200px"; } if (projectConfig.canvasBgColorHex && projectConfig.canvasBgColorHex.trim()) { canvasInnerStyle.backgroundColor = projectConfig.canvasBgColorHex; } return (
{ if (event.target === event.currentTarget) { onCanvasEmptyClick(); } }} >
{blocks.length === 0 ? (
왼쪽에서 "텍스트 블록 추가" 버튼을 눌러 블록을 추가해 보세요.
) : ( b.id)} strategy={verticalListSortingStrategy} > {renderBlocks(rootBlocks)} {activeDragId && ( b.id === activeDragId) ?? null} /> )} )}
); } interface DragPreviewProps { block: Block | null; } function DragPreview({ block }: DragPreviewProps) { if (!block) return null; return (
{block.type === "text" ? "Text" : block.type === "button" ? "Button" : block.type === "image" ? "Image" : block.type === "divider" ? "Divider" : block.type === "list" ? "List" : "Section"}
{block.type === "text" ? (block.props as TextBlockProps).text || "텍스트 블록" : block.type === "button" ? (block.props as ButtonBlockProps).label || "버튼 블록" : block.type === "image" ? (block.props as ImageBlockProps).alt || "이미지 블록" : block.type === "list" ? "리스트 블록" : block.type === "divider" ? "구분선 블록" : "섹션 블록"}
); }