From 627f1dd03647811da6b4f837014daa964bfe439e Mon Sep 17 00:00:00 2001 From: Likilee Date: Mon, 31 Mar 2025 18:56:05 +0900 Subject: [PATCH] feat: add keyboardEvent codes for shape selection Add new keyboard shortcuts for shape selection by introducing `codes` for each shape in the `SHAPES` array. Update the shape finding logic to include a new function, `findShapeByCode`, which allows shape selection using both key and code events. This enhances user experience by providing more flexible input options for shape selection. --- packages/excalidraw/components/App.tsx | 4 ++-- packages/excalidraw/components/shapes.tsx | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index d5fb55e1d..25fac15a4 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -480,7 +480,7 @@ import { import { MagicIcon, copyIcon, fullscreenIcon } from "./icons"; import { Toast } from "./Toast"; -import { findShapeByKey } from "./shapes"; +import { findShapeByCode, findShapeByKey } from "./shapes"; import type { RenderInteractiveSceneCallback, @@ -4500,7 +4500,7 @@ class App extends React.Component { !this.state.selectionElement && !this.state.selectedElementsAreBeingDragged ) { - const shape = findShapeByKey(event.key); + const shape = findShapeByKey(event.key) || findShapeByCode(event.code); if (shape) { if (this.state.activeTool.type !== shape) { trackEvent( diff --git a/packages/excalidraw/components/shapes.tsx b/packages/excalidraw/components/shapes.tsx index 7411a9e25..318544028 100644 --- a/packages/excalidraw/components/shapes.tsx +++ b/packages/excalidraw/components/shapes.tsx @@ -18,6 +18,7 @@ export const SHAPES = [ icon: SelectionIcon, value: "selection", key: KEYS.V, + codes: ["KeyV", "Digit1"], numericKey: KEYS["1"], fillable: true, }, @@ -25,6 +26,7 @@ export const SHAPES = [ icon: RectangleIcon, value: "rectangle", key: KEYS.R, + codes: ["KeyR", "Digit2"], numericKey: KEYS["2"], fillable: true, }, @@ -32,6 +34,7 @@ export const SHAPES = [ icon: DiamondIcon, value: "diamond", key: KEYS.D, + codes: ["KeyD", "Digit3"], numericKey: KEYS["3"], fillable: true, }, @@ -39,6 +42,7 @@ export const SHAPES = [ icon: EllipseIcon, value: "ellipse", key: KEYS.O, + codes: ["KeyO", "Digit4"], numericKey: KEYS["4"], fillable: true, }, @@ -46,6 +50,7 @@ export const SHAPES = [ icon: ArrowIcon, value: "arrow", key: KEYS.A, + codes: ["KeyA", "Digit5"], numericKey: KEYS["5"], fillable: true, }, @@ -53,6 +58,7 @@ export const SHAPES = [ icon: LineIcon, value: "line", key: KEYS.L, + codes: ["KeyL", "Digit6"], numericKey: KEYS["6"], fillable: true, }, @@ -60,6 +66,7 @@ export const SHAPES = [ icon: FreedrawIcon, value: "freedraw", key: [KEYS.P, KEYS.X], + codes: ["KeyP", "KeyX", "Digit7"], numericKey: KEYS["7"], fillable: false, }, @@ -67,6 +74,7 @@ export const SHAPES = [ icon: TextIcon, value: "text", key: KEYS.T, + codes: ["KeyT", "Digit8"], numericKey: KEYS["8"], fillable: false, }, @@ -74,6 +82,7 @@ export const SHAPES = [ icon: ImageIcon, value: "image", key: null, + codes: ["Digit9"], numericKey: KEYS["9"], fillable: false, }, @@ -81,6 +90,7 @@ export const SHAPES = [ icon: EraserIcon, value: "eraser", key: KEYS.E, + codes: ["KeyE", "Digit0"], numericKey: KEYS["0"], fillable: false, }, @@ -98,3 +108,10 @@ export const findShapeByKey = (key: string) => { }); return shape?.value || null; }; + +export const findShapeByCode = (code: string) => { + const shape = SHAPES.find((shape) => + (shape.codes as readonly string[]).includes(code), + ); + return shape?.value || null; +};