From 935c24f887d27ec1e75565bd10ecff7e40a09fdf Mon Sep 17 00:00:00 2001 From: Jawahar Date: Mon, 3 Oct 2022 19:29:05 +0530 Subject: [PATCH 1/7] Remove all active selections on pressing ESC key --- packages/excalidraw/components/App.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index 97ce14662..270c5b53d 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -3747,6 +3747,17 @@ class App extends React.Component { }, 100); } + // remove selections on escape press + if (event.key === "Escape") { + this.setState({ + selectedElementIds: {}, + selectedGroupIds: {}, + editingGroupId: null, + }); + event.preventDefault(); + return; + } + // prevent browser zoom in input fields if (event[KEYS.CTRL_OR_CMD] && isWritableElement(event.target)) { if (event.code === CODES.MINUS || event.code === CODES.EQUAL) { From ac46b431b2179b6d3757cb26a433ac9918fad9de Mon Sep 17 00:00:00 2001 From: Jawahar S Date: Fri, 28 Oct 2022 15:30:46 +0530 Subject: [PATCH 2/7] Use KEYS.ESCAPE instead of "Escape" Co-authored-by: DanielJGeiger <1852529+DanielJGeiger@users.noreply.github.com> --- packages/excalidraw/components/App.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index 270c5b53d..884cf17d8 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -3748,7 +3748,11 @@ class App extends React.Component { } // remove selections on escape press - if (event.key === "Escape") { + if (event.key === KEYS.ESCAPE) { + // Don't deselect text right after editing it + if (isWritableElement(event.target)) { + return; + } this.setState({ selectedElementIds: {}, selectedGroupIds: {}, From 898036d202ba4077269622add13a95b13f235fa2 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Sat, 16 Mar 2024 17:01:18 -0700 Subject: [PATCH 3/7] fix: update expected render call counts in selection tests --- packages/excalidraw/tests/selection.test.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/excalidraw/tests/selection.test.tsx b/packages/excalidraw/tests/selection.test.tsx index 18e0dfe2a..6d55cc373 100644 --- a/packages/excalidraw/tests/selection.test.tsx +++ b/packages/excalidraw/tests/selection.test.tsx @@ -314,7 +314,7 @@ describe("select single element on the scene", () => { fireEvent.pointerUp(canvas); expect(renderInteractiveScene).toHaveBeenCalledTimes(9); - expect(renderStaticScene).toHaveBeenCalledTimes(7); + expect(renderStaticScene).toHaveBeenCalledTimes(8); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); @@ -346,7 +346,7 @@ describe("select single element on the scene", () => { fireEvent.pointerUp(canvas); expect(renderInteractiveScene).toHaveBeenCalledTimes(9); - expect(renderStaticScene).toHaveBeenCalledTimes(7); + expect(renderStaticScene).toHaveBeenCalledTimes(8); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); @@ -378,7 +378,7 @@ describe("select single element on the scene", () => { fireEvent.pointerUp(canvas); expect(renderInteractiveScene).toHaveBeenCalledTimes(9); - expect(renderStaticScene).toHaveBeenCalledTimes(7); + expect(renderStaticScene).toHaveBeenCalledTimes(8); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); @@ -422,8 +422,8 @@ describe("select single element on the scene", () => { fireEvent.pointerDown(canvas, { clientX: 40, clientY: 40 }); fireEvent.pointerUp(canvas); - expect(renderInteractiveScene).toHaveBeenCalledTimes(9); - expect(renderStaticScene).toHaveBeenCalledTimes(7); + expect(renderInteractiveScene).toHaveBeenCalledTimes(10); + expect(renderStaticScene).toHaveBeenCalledTimes(8); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); @@ -466,8 +466,8 @@ describe("select single element on the scene", () => { fireEvent.pointerDown(canvas, { clientX: 40, clientY: 40 }); fireEvent.pointerUp(canvas); - expect(renderInteractiveScene).toHaveBeenCalledTimes(9); - expect(renderStaticScene).toHaveBeenCalledTimes(7); + expect(renderInteractiveScene).toHaveBeenCalledTimes(10); + expect(renderStaticScene).toHaveBeenCalledTimes(8); expect(h.state.selectionElement).toBeNull(); expect(h.elements.length).toEqual(1); expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy(); From db9aca37b678154c4c13e6c937da4969f5a743d7 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Sat, 16 Mar 2024 21:44:09 -0700 Subject: [PATCH 4/7] test: add tests for deselecting when pressing escape --- packages/excalidraw/tests/selection.test.tsx | 98 ++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/packages/excalidraw/tests/selection.test.tsx b/packages/excalidraw/tests/selection.test.tsx index 6d55cc373..e40251fea 100644 --- a/packages/excalidraw/tests/selection.test.tsx +++ b/packages/excalidraw/tests/selection.test.tsx @@ -104,6 +104,104 @@ describe("box-selection", () => { }); }); +describe("deselect when pressing escape", () => { + beforeEach(async () => { + await render(); + }); + + it("deselects elements", async () => { + const rect1 = API.createElement({ + type: "rectangle", + x: 0, + y: 0, + width: 50, + height: 50, + }); + const rect2 = API.createElement({ + type: "rectangle", + x: 100, + y: 0, + width: 50, + height: 50, + }); + + h.elements = [rect1, rect2]; + + mouse.clickAt(0, 0); + + assertSelectedElements([rect1.id]); + + Keyboard.keyDown(KEYS.ESCAPE); + + assertSelectedElements([]); + + mouse.downAt(-10, -10); + mouse.moveTo(160, 60); + mouse.up(); + + assertSelectedElements([rect1.id, rect2.id]); + + Keyboard.keyDown(KEYS.ESCAPE); + + assertSelectedElements([]); + }); + + it("deselects groups", async () => { + const rect1 = API.createElement({ + type: "rectangle", + x: 0, + y: 0, + width: 50, + height: 50, + }); + const rect2 = API.createElement({ + type: "rectangle", + x: 100, + y: 0, + width: 50, + height: 50, + }); + const rect3 = API.createElement({ + type: "rectangle", + x: 200, + y: 0, + width: 50, + height: 50, + }); + + h.elements = [rect1, rect2, rect3]; + + mouse.downAt(-10, -10); + mouse.moveTo(160, 60); + mouse.up(); + + Keyboard.withModifierKeys({ ctrl: true }, () => { + Keyboard.keyDown(KEYS.G); + }); + + expect(Object.keys(h.state.selectedGroupIds).length).toBe(1); + assertSelectedElements([rect1.id, rect2.id]); + + Keyboard.keyDown(KEYS.ESCAPE); + + expect(Object.keys(h.state.selectedGroupIds).length).toBe(0); + assertSelectedElements([]); + + mouse.clickAt(100, 0); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.clickAt(200, 0); + }); + + expect(Object.keys(h.state.selectedGroupIds).length).toBe(1); + assertSelectedElements([rect1.id, rect2.id, rect3.id]); + + Keyboard.keyDown(KEYS.ESCAPE); + + expect(Object.keys(h.state.selectedGroupIds).length).toBe(0); + assertSelectedElements([]); + }); +}); + describe("inner box-selection", () => { beforeEach(async () => { await render(); From 63e748f147fb8d8af16072d931d47f58ed0ee343 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Wed, 3 Apr 2024 16:06:23 -0700 Subject: [PATCH 5/7] fix: deselect on escape only if neither dragging nor finalizing an action --- packages/excalidraw/components/App.tsx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index 884cf17d8..23f5c6987 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -3748,11 +3748,16 @@ class App extends React.Component { } // remove selections on escape press - if (event.key === KEYS.ESCAPE) { - // Don't deselect text right after editing it - if (isWritableElement(event.target)) { - return; - } + if ( + event.key === KEYS.ESCAPE && + // unless we're dragging or finalizing an action + !( + this.state.draggingElement || + isWritableElement(event.target) || + this.state.editingElement || + ["freedraw", "eraser"].includes(this.state.activeTool.type) + ) + ) { this.setState({ selectedElementIds: {}, selectedGroupIds: {}, From ace478a0ebf5c14505c744cf26c46d33a6afb253 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Fri, 20 Sep 2024 13:22:44 -0700 Subject: [PATCH 6/7] fix renamed variable names from #8294 and #8340 --- packages/excalidraw/components/App.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index aa31a283e..18c469150 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -4071,9 +4071,10 @@ class App extends React.Component { event.key === KEYS.ESCAPE && // unless we're dragging or finalizing an action !( - this.state.draggingElement || + this.state.newElement || isWritableElement(event.target) || - this.state.editingElement || + this.state.editingTextElement || + this.state.editingLinearElement || ["freedraw", "eraser"].includes(this.state.activeTool.type) ) ) { From 4f1664cc906bbdcdbea1fff71cc37be961bae6c1 Mon Sep 17 00:00:00 2001 From: Andrew Aquino Date: Fri, 20 Sep 2024 13:38:43 -0700 Subject: [PATCH 7/7] update deselection tests to use act() helper, per #8322 --- packages/excalidraw/tests/selection.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/excalidraw/tests/selection.test.tsx b/packages/excalidraw/tests/selection.test.tsx index ce6eede4e..2150b669f 100644 --- a/packages/excalidraw/tests/selection.test.tsx +++ b/packages/excalidraw/tests/selection.test.tsx @@ -126,7 +126,7 @@ describe("deselect when pressing escape", () => { height: 50, }); - h.elements = [rect1, rect2]; + API.setElements([rect1, rect2]); mouse.clickAt(0, 0); @@ -170,7 +170,7 @@ describe("deselect when pressing escape", () => { height: 50, }); - h.elements = [rect1, rect2, rect3]; + API.setElements([rect1, rect2, rect3]); mouse.downAt(-10, -10); mouse.moveTo(160, 60);