diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index 08ad13fa5..925035c4b 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -190,6 +190,7 @@ import type { import { getCenter, getDistance } from "../gesture"; import { editGroupForSelectedElement, + elementsAreInSameGroup, getElementsInGroup, getSelectedGroupIdForElement, getSelectedGroupIds, @@ -4210,6 +4211,7 @@ class App extends React.Component { event.preventDefault(); } else if (event.key === KEYS.ENTER) { const selectedElements = this.scene.getSelectedElements(this.state); + const selectedGroupIds = getSelectedGroupIds(this.state); if (selectedElements.length === 1) { const selectedElement = selectedElements[0]; if (event[KEYS.CTRL_OR_CMD]) { @@ -4256,6 +4258,13 @@ class App extends React.Component { editingFrame: selectedElement.id, }); } + } else if ( + selectedGroupIds.length === 1 && + elementsAreInSameGroup(selectedElements) + ) { + this.setState({ + editingGroupId: selectedGroupIds[0], + }); } } else if ( !event.ctrlKey && diff --git a/packages/excalidraw/tests/selection.test.tsx b/packages/excalidraw/tests/selection.test.tsx index bffe375bf..c0beea9c1 100644 --- a/packages/excalidraw/tests/selection.test.tsx +++ b/packages/excalidraw/tests/selection.test.tsx @@ -16,6 +16,7 @@ import { API } from "./helpers/api"; import { Keyboard, Pointer, UI } from "./helpers/ui"; import { SHAPES } from "../shapes"; import { vi } from "vitest"; +import type { ExcalidrawElement } from "../element/types"; // Unmount ReactDOM from root ReactDOM.unmountComponentAtNode(document.getElementById("root")!); @@ -535,3 +536,58 @@ describe("selectedElementIds stability", () => { expect(h.state.selectedElementIds).toBe(selectedElementIds_2); }); }); + +describe("edit-group selection", () => { + let rect1: ExcalidrawElement; + let rect2: ExcalidrawElement; + let rect3: ExcalidrawElement; + + beforeEach(async () => { + await render(); + + rect1 = API.createElement({ + type: "rectangle", + x: 0, + y: 0, + width: 20, + height: 20, + groupIds: ["A"], + }); + rect2 = API.createElement({ + type: "rectangle", + x: 50, + y: 50, + width: 20, + height: 20, + groupIds: ["A"], + }); + rect3 = API.createElement({ + type: "rectangle", + x: 100, + y: 100, + width: 20, + height: 20, + }); + API.setElements([rect1, rect2, rect3]); + }); + + it("edits group on Enter", () => { + mouse.select(rect1); + assertSelectedElements([rect1.id, rect2.id]); + expect(h.state.selectedGroupIds).toEqual({ A: true }); + + Keyboard.keyDown(KEYS.ENTER); + expect(h.state.editingGroupId).toBe("A"); + assertSelectedElements([rect1.id, rect2.id]); + }); + + it("doesn't edit group if selected elements aren't part of the same group", () => { + mouse.downAt(130, 130); + mouse.moveTo(40, 40); + mouse.up(); + assertSelectedElements([rect1.id, rect2.id, rect3.id]); + + Keyboard.keyDown(KEYS.ENTER); + expect(h.state.editingGroupId).toBe(null); + }); +});