키보드를 사용한 복제 및 삭제 구현
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import { useEffect, useCallback } from "react";
|
||||
|
||||
interface KeyboardShortcutsProps {
|
||||
selectedElementId: string | null;
|
||||
onDelete: () => void;
|
||||
onCopy: () => void;
|
||||
onPaste: () => void;
|
||||
onUndo?: () => void;
|
||||
onRedo?: () => void;
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 대시보드 키보드 단축키 훅
|
||||
*
|
||||
* 지원 단축키:
|
||||
* - Delete: 선택한 요소 삭제
|
||||
* - Ctrl+C: 요소 복사
|
||||
* - Ctrl+V: 요소 붙여넣기
|
||||
* - Ctrl+Z: 실행 취소 (구현 예정)
|
||||
* - Ctrl+Shift+Z: 재실행 (구현 예정)
|
||||
*/
|
||||
export function useKeyboardShortcuts({
|
||||
selectedElementId,
|
||||
onDelete,
|
||||
onCopy,
|
||||
onPaste,
|
||||
onUndo,
|
||||
onRedo,
|
||||
enabled = true,
|
||||
}: KeyboardShortcutsProps) {
|
||||
const handleKeyDown = useCallback(
|
||||
(e: KeyboardEvent) => {
|
||||
if (!enabled) return;
|
||||
|
||||
// 입력 필드에서는 단축키 비활성화
|
||||
const target = e.target as HTMLElement;
|
||||
if (
|
||||
target.tagName === "INPUT" ||
|
||||
target.tagName === "TEXTAREA" ||
|
||||
target.contentEditable === "true" ||
|
||||
target.closest('[role="dialog"]') ||
|
||||
target.closest('[role="alertdialog"]')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0;
|
||||
const ctrlKey = isMac ? e.metaKey : e.ctrlKey;
|
||||
|
||||
// Delete: 선택한 요소 삭제
|
||||
if (e.key === "Delete" || e.key === "Backspace") {
|
||||
if (selectedElementId) {
|
||||
e.preventDefault();
|
||||
onDelete();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+C: 복사
|
||||
if (ctrlKey && e.key === "c") {
|
||||
if (selectedElementId) {
|
||||
e.preventDefault();
|
||||
onCopy();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+V: 붙여넣기
|
||||
if (ctrlKey && e.key === "v") {
|
||||
e.preventDefault();
|
||||
onPaste();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+Z: 실행 취소
|
||||
if (ctrlKey && e.key === "z" && !e.shiftKey) {
|
||||
if (onUndo) {
|
||||
e.preventDefault();
|
||||
onUndo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+Shift+Z 또는 Ctrl+Y: 재실행
|
||||
if ((ctrlKey && e.shiftKey && e.key === "z") || (ctrlKey && e.key === "y")) {
|
||||
if (onRedo) {
|
||||
e.preventDefault();
|
||||
onRedo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
},
|
||||
[enabled, selectedElementId, onDelete, onCopy, onPaste, onUndo, onRedo],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
|
||||
document.addEventListener("keydown", handleKeyDown);
|
||||
return () => {
|
||||
document.removeEventListener("keydown", handleKeyDown);
|
||||
};
|
||||
}, [handleKeyDown, enabled]);
|
||||
}
|
||||
Reference in New Issue
Block a user