test: Add canvas keyboard shortcuts (undo/redo/delete/select-all/desele…

- "app/src/views/DesignCanvas.tsx"

GSD-Task: S02/T04
This commit is contained in:
jlightner 2026-03-26 05:41:41 +00:00
parent e38a7c5cf2
commit 0dcc96dee6

View file

@ -33,7 +33,7 @@ export default function DesignCanvas({
const { const {
state, state,
addObject, addObject,
removeObject: _removeObject, removeObject,
updateObject, updateObject,
selectObjects, selectObjects,
deselectAll, deselectAll,
@ -170,6 +170,59 @@ export default function DesignCanvas({
setZoomLevel(1); setZoomLevel(1);
}, []); }, []);
// -- Keyboard shortcuts ---------------------------------------------------
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
// Don't fire shortcuts when typing in an input/textarea
const tag = (document.activeElement?.tagName ?? '').toLowerCase();
if (tag === 'input' || tag === 'textarea' || tag === 'select') return;
const ctrl = e.ctrlKey || e.metaKey;
if (ctrl && e.shiftKey && e.key.toLowerCase() === 'z') {
e.preventDefault();
redo();
return;
}
if (ctrl && e.key.toLowerCase() === 'z') {
e.preventDefault();
undo();
return;
}
if (ctrl && e.key.toLowerCase() === 'y') {
e.preventDefault();
redo();
return;
}
if (ctrl && e.key.toLowerCase() === 'a') {
e.preventDefault();
selectObjects(state.objects.map((o) => o.id));
return;
}
if (e.key === 'Delete' || e.key === 'Backspace') {
e.preventDefault();
for (const id of state.selectedIds) {
removeObject(id);
}
return;
}
if (e.key === 'Escape') {
e.preventDefault();
deselectAll();
return;
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [undo, redo, removeObject, selectObjects, deselectAll, state.objects, state.selectedIds]);
// -- Selected object for properties panel --------------------------------- // -- Selected object for properties panel ---------------------------------
const selectedObject = useMemo(() => { const selectedObject = useMemo(() => {