From a1466676152a56d011a912789ef18bc1f4f1b0a5 Mon Sep 17 00:00:00 2001 From: kjs Date: Thu, 8 Jan 2026 12:25:52 +0900 Subject: [PATCH] =?UTF-8?q?=EB=93=9C=EB=9E=98=EA=B7=B8=20=ED=95=B8?= =?UTF-8?q?=EB=93=A4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/EditableSpreadsheet.tsx | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/frontend/components/common/EditableSpreadsheet.tsx b/frontend/components/common/EditableSpreadsheet.tsx index cf05bbe2..0d4ad3d3 100644 --- a/frontend/components/common/EditableSpreadsheet.tsx +++ b/frontend/components/common/EditableSpreadsheet.tsx @@ -532,6 +532,24 @@ export const EditableSpreadsheet: React.FC = ({ } else if (e.key === "Escape") { // Esc로 복사 범위 표시 취소 setCopiedRange(null); + } else if (e.key === "F2") { + // F2로 편집 모드 진입 (기존 값 유지) + const norm = normalizeRange(selection); + if (norm.startRow >= 0 && norm.startRow === norm.endRow && norm.startCol === norm.endCol) { + e.preventDefault(); + const colName = columns[norm.startCol]; + setEditingCell({ row: norm.startRow, col: norm.startCol }); + setEditValue(String(data[norm.startRow]?.[colName] ?? "")); + } + } else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) { + // 일반 문자 키 입력 시 편집 모드 진입 (엑셀처럼) + const norm = normalizeRange(selection); + if (norm.startRow >= 0 && norm.startRow === norm.endRow && norm.startCol === norm.endCol) { + // 단일 셀 선택 시에만 + e.preventDefault(); + setEditingCell({ row: norm.startRow, col: norm.startCol }); + setEditValue(e.key); // 입력한 문자로 시작 + } } }; @@ -659,6 +677,32 @@ export const EditableSpreadsheet: React.FC = ({ e.preventDefault(); e.stopPropagation(); + // 편집 중이면 먼저 현재 편집 값을 저장 + if (editingCell) { + const { row, col } = editingCell; + if (row === -1) { + // 헤더 변경 + const newColumns = [...columns]; + const oldColName = newColumns[col]; + const newColName = editValue.trim() || `Column${col + 1}`; + if (oldColName !== newColName) { + newColumns[col] = newColName; + onColumnsChange(newColumns); + } + } else { + // 데이터 셀 변경 + const colName = columns[col]; + const newData = [...data]; + if (!newData[row]) { + newData[row] = {}; + } + newData[row] = { ...newData[row], [colName]: editValue }; + onDataChange(newData); + } + setEditingCell(null); + setEditValue(""); + } + if (!selection) return; const norm = normalizeRange(selection); if (norm.startRow < 0) return; // 헤더는 제외 @@ -955,8 +999,8 @@ export const EditableSpreadsheet: React.FC = ({ )} - {/* 자동 채우기 핸들 - 선택 범위의 우하단에서만 표시 */} - {isSelectionEnd && !isEditing && selection && normalizeRange(selection).startRow >= 0 && ( + {/* 자동 채우기 핸들 - 선택 범위의 우하단에서만 표시 (편집 중에도 표시) */} + {isSelectionEnd && selection && normalizeRange(selection).startRow >= 0 && (