fix(editor): prevent crash when editing arrow with bound text (#11814)

This commit is contained in:
nihaarsirikonda
2026-08-04 16:31:37 +02:00
committed by GitHub
parent 792ea3a06c
commit ab0255f21e
2 changed files with 46 additions and 10 deletions
@@ -260,6 +260,46 @@ describe("Test Linear Elements", () => {
expect(h.state.selectedLinearElement?.elementId).toEqual(h.elements[0].id);
});
it("should allow editing an arrow from the context menu when its bound text appears earlier in the elements array", () => {
const arrow = createTwoPointerLinearElement("arrow");
const textElement = API.createElement({
type: "text",
x: 0,
y: 0,
text: "abc",
containerId: arrow.id,
width: 30,
height: 20,
});
const updatedArrow = {
...arrow,
boundElements: [{ type: "text" as const, id: textElement.id }],
};
// text element intentionally placed before its container in the array
API.setElements([textElement, updatedArrow]);
fireEvent.contextMenu(GlobalTestState.interactiveCanvas, {
button: 2,
clientX: midpoint[0],
clientY: midpoint[1],
});
const contextMenu = document.querySelector(".context-menu");
fireEvent.contextMenu(GlobalTestState.interactiveCanvas, {
button: 2,
clientX: midpoint[0],
clientY: midpoint[1],
});
expect(() =>
fireEvent.click(queryByText(contextMenu as HTMLElement, "Edit arrow")!),
).not.toThrow();
expect(h.state.selectedLinearElement?.isEditing).toBe(true);
expect(h.state.selectedLinearElement?.elementId).toEqual(updatedArrow.id);
});
it("should enter line editor via enter (line)", () => {
createTwoPointerLinearElement("line");
expect(h.state.selectedLinearElement?.isEditing).toBe(false);
@@ -53,20 +53,16 @@ export const actionToggleLinearEditor = register({
return false;
},
perform(elements, appState, _, app) {
const selectedElement = app.scene.getSelectedElements({
selectedElementIds: appState.selectedElementIds,
includeBoundTextElement: true,
})[0] as ExcalidrawLinearElement;
invariant(selectedElement, "No selected element found");
invariant(
appState.selectedLinearElement,
"No selected linear element found",
);
invariant(
selectedElement.id === appState.selectedLinearElement.elementId,
"Selected element ID and linear editor elementId does not match",
);
const selectedElement = app.scene.getElement(
appState.selectedLinearElement.elementId,
) as ExcalidrawLinearElement | null;
invariant(selectedElement, "No selected element found");
const selectedLinearElement = {
...appState.selectedLinearElement,