Files
flatrender/src/hooks/useCanvasKeyboard.ts
T

75 lines
2.0 KiB
TypeScript

"use client";
import { useEffect } from "react";
import { useStudioStore } from "@/lib/studio-store";
function isEditableTarget(target: EventTarget | null): boolean {
if (!(target instanceof HTMLElement)) return false;
const tag = target.tagName;
return tag === "INPUT" || tag === "TEXTAREA" || target.isContentEditable;
}
export function useCanvasKeyboard() {
const selectedLayerId = useStudioStore((state) => state.selectedLayerId);
const deleteLayer = useStudioStore((state) => state.deleteLayer);
const copyLayer = useStudioStore((state) => state.copyLayer);
const pasteLayer = useStudioStore((state) => state.pasteLayer);
const undo = useStudioStore((state) => state.undo);
const redo = useStudioStore((state) => state.redo);
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (isEditableTarget(event.target)) return;
if (event.key === "Delete" || event.key === "Backspace") {
if (!selectedLayerId) return;
event.preventDefault();
deleteLayer(selectedLayerId);
return;
}
const mod = event.ctrlKey || event.metaKey;
if (!mod) return;
if (event.key === "c" || event.key === "C") {
if (!selectedLayerId) return;
event.preventDefault();
copyLayer(selectedLayerId);
return;
}
if (event.key === "v" || event.key === "V") {
event.preventDefault();
pasteLayer();
return;
}
if (event.key === "z" || event.key === "Z") {
event.preventDefault();
if (event.shiftKey) {
redo();
} else {
undo();
}
return;
}
if (event.key === "y" || event.key === "Y") {
event.preventDefault();
redo();
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [
selectedLayerId,
deleteLayer,
copyLayer,
pasteLayer,
undo,
redo,
]);
}