키보드 화살표 이동 구현

This commit is contained in:
dohyeons 2025-10-01 16:09:34 +09:00
parent 43cdacb194
commit 722a413916
1 changed files with 58 additions and 2 deletions

View File

@ -12,6 +12,7 @@ export function ReportDesignerCanvas() {
const {
components,
addComponent,
updateComponent,
canvasWidth,
canvasHeight,
selectComponent,
@ -77,7 +78,7 @@ export function ReportDesignerCanvas() {
}
};
// 키보드 단축키 (Delete, Ctrl+C, Ctrl+V)
// 키보드 단축키 (Delete, Ctrl+C, Ctrl+V, 화살표 이동)
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
// 입력 필드에서는 단축키 무시
@ -86,6 +87,51 @@ export function ReportDesignerCanvas() {
return;
}
// 화살표 키: 선택된 컴포넌트 이동
if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(e.key)) {
e.preventDefault();
// 선택된 컴포넌트가 없으면 무시
if (!selectedComponentId && selectedComponentIds.length === 0) {
return;
}
// 이동 거리 (Shift 키를 누르면 10px, 아니면 1px)
const moveDistance = e.shiftKey ? 10 : 1;
// 이동할 컴포넌트 ID 목록
const idsToMove =
selectedComponentIds.length > 0 ? selectedComponentIds : ([selectedComponentId].filter(Boolean) as string[]);
// 각 컴포넌트 이동
idsToMove.forEach((id) => {
const component = components.find((c) => c.id === id);
if (!component) return;
let newX = component.x;
let newY = component.y;
switch (e.key) {
case "ArrowLeft":
newX = Math.max(0, component.x - moveDistance);
break;
case "ArrowRight":
newX = component.x + moveDistance;
break;
case "ArrowUp":
newY = Math.max(0, component.y - moveDistance);
break;
case "ArrowDown":
newY = component.y + moveDistance;
break;
}
updateComponent(id, { x: newX, y: newY });
});
return;
}
// Delete 키: 삭제
if (e.key === "Delete") {
if (selectedComponentIds.length > 0) {
@ -128,7 +174,17 @@ export function ReportDesignerCanvas() {
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [selectedComponentId, selectedComponentIds, removeComponent, copyComponents, pasteComponents, undo, redo]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
selectedComponentId,
selectedComponentIds,
components,
removeComponent,
copyComponents,
pasteComponents,
undo,
redo,
]);
return (
<div className="flex flex-1 flex-col overflow-hidden bg-gray-100">