Compare commits

..

2 Commits

Author SHA1 Message Date
kjs a146667615 드래그 핸들 수정 2026-01-08 12:25:52 +09:00
kjs f33d989202 복사된 셀 표시 2026-01-08 12:23:00 +09:00
1 changed files with 49 additions and 5 deletions

View File

@ -104,9 +104,6 @@ export const EditableSpreadsheet: React.FC<EditableSpreadsheetProps> = ({
});
setIsDraggingSelection(true);
// 복사 범위 초기화 (새로운 선택 시작하면 이전 복사 표시 제거)
setCopiedRange(null);
// 테이블에 포커스 (키보드 이벤트 수신용)
tableRef.current?.focus();
}, [editingCell]);
@ -532,6 +529,27 @@ export const EditableSpreadsheet: React.FC<EditableSpreadsheetProps> = ({
if (isInputFocused) return;
e.preventDefault();
handleDelete();
} 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<EditableSpreadsheetProps> = ({
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<EditableSpreadsheetProps> = ({
</>
)}
{/* 자동 채우기 핸들 - 선택 범위의 우하단에서만 표시 */}
{isSelectionEnd && !isEditing && selection && normalizeRange(selection).startRow >= 0 && (
{/* 자동 채우기 핸들 - 선택 범위의 우하단에서만 표시 (편집 중에도 표시) */}
{isSelectionEnd && selection && normalizeRange(selection).startRow >= 0 && (
<div
className="absolute bottom-0 right-0 z-20 h-2.5 w-2.5 translate-x-1/2 translate-y-1/2 cursor-crosshair border border-white bg-primary"
onMouseDown={handleFillDragStart}