Fix keypress rebinding (#2102)
Co-authored-by: Anton <anton.matrenin@introduct.tech>
This commit is contained in:
parent
84c49ebaa1
commit
1828a93ba7
@ -135,7 +135,7 @@ import {
|
|||||||
import LayerUI from "./LayerUI";
|
import LayerUI from "./LayerUI";
|
||||||
import { ScrollBars, SceneState } from "../scene/types";
|
import { ScrollBars, SceneState } from "../scene/types";
|
||||||
import { generateCollaborationLink, getCollaborationLinkData } from "../data";
|
import { generateCollaborationLink, getCollaborationLinkData } from "../data";
|
||||||
import { mutateElement, newElementWith } from "../element/mutateElement";
|
import { mutateElement } from "../element/mutateElement";
|
||||||
import { invalidateShapeForElement } from "../renderer/renderElement";
|
import { invalidateShapeForElement } from "../renderer/renderElement";
|
||||||
import { unstable_batchedUpdates } from "react-dom";
|
import { unstable_batchedUpdates } from "react-dom";
|
||||||
import {
|
import {
|
||||||
@ -173,6 +173,7 @@ import {
|
|||||||
fixBindingsAfterDeletion,
|
fixBindingsAfterDeletion,
|
||||||
isLinearElementSimpleAndAlreadyBound,
|
isLinearElementSimpleAndAlreadyBound,
|
||||||
isBindingEnabled,
|
isBindingEnabled,
|
||||||
|
updateBoundElements,
|
||||||
} from "../element/binding";
|
} from "../element/binding";
|
||||||
import { MaybeTransformHandleType } from "../element/transformHandles";
|
import { MaybeTransformHandleType } from "../element/transformHandles";
|
||||||
|
|
||||||
@ -608,7 +609,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
this.setState({});
|
this.setState({});
|
||||||
});
|
});
|
||||||
|
|
||||||
private onHashChange = (event: HashChangeEvent) => {
|
private onHashChange = (_: HashChangeEvent) => {
|
||||||
if (window.location.hash.length > 1) {
|
if (window.location.hash.length > 1) {
|
||||||
this.initializeScene();
|
this.initializeScene();
|
||||||
}
|
}
|
||||||
@ -1486,24 +1487,35 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||||||
(event.shiftKey
|
(event.shiftKey
|
||||||
? ELEMENT_SHIFT_TRANSLATE_AMOUNT
|
? ELEMENT_SHIFT_TRANSLATE_AMOUNT
|
||||||
: ELEMENT_TRANSLATE_AMOUNT);
|
: ELEMENT_TRANSLATE_AMOUNT);
|
||||||
this.scene.replaceAllElements(
|
|
||||||
this.scene.getElementsIncludingDeleted().map((el) => {
|
const selectedElements = this.scene
|
||||||
if (this.state.selectedElementIds[el.id]) {
|
.getElements()
|
||||||
const update: { x?: number; y?: number } = {};
|
.filter((element) => this.state.selectedElementIds[element.id]);
|
||||||
if (event.key === KEYS.ARROW_LEFT) {
|
|
||||||
update.x = el.x - step;
|
let offsetX = 0;
|
||||||
} else if (event.key === KEYS.ARROW_RIGHT) {
|
let offsetY = 0;
|
||||||
update.x = el.x + step;
|
|
||||||
} else if (event.key === KEYS.ARROW_UP) {
|
if (event.key === KEYS.ARROW_LEFT) {
|
||||||
update.y = el.y - step;
|
offsetX = -step;
|
||||||
} else if (event.key === KEYS.ARROW_DOWN) {
|
} else if (event.key === KEYS.ARROW_RIGHT) {
|
||||||
update.y = el.y + step;
|
offsetX = step;
|
||||||
}
|
} else if (event.key === KEYS.ARROW_UP) {
|
||||||
return newElementWith(el, update);
|
offsetY = -step;
|
||||||
}
|
} else if (event.key === KEYS.ARROW_DOWN) {
|
||||||
return el;
|
offsetY = step;
|
||||||
}),
|
}
|
||||||
);
|
|
||||||
|
selectedElements.forEach((element) => {
|
||||||
|
mutateElement(element, {
|
||||||
|
x: element.x + offsetX,
|
||||||
|
y: element.y + offsetY,
|
||||||
|
});
|
||||||
|
|
||||||
|
updateBoundElements(element, {
|
||||||
|
simultaneouslyUpdated: selectedElements,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
} else if (event.key === KEYS.ENTER) {
|
} else if (event.key === KEYS.ENTER) {
|
||||||
const selectedElements = getSelectedElements(
|
const selectedElements = getSelectedElements(
|
||||||
|
@ -77,3 +77,106 @@ Object {
|
|||||||
"y": 40,
|
"y": 40,
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`move element rectangles with binding arrow 1`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"boundElementIds": Array [
|
||||||
|
"id2",
|
||||||
|
],
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"groupIds": Array [],
|
||||||
|
"height": 100,
|
||||||
|
"id": "id0",
|
||||||
|
"isDeleted": false,
|
||||||
|
"opacity": 100,
|
||||||
|
"roughness": 1,
|
||||||
|
"seed": 337897,
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"strokeSharpness": "sharp",
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"type": "rectangle",
|
||||||
|
"version": 3,
|
||||||
|
"versionNonce": 1014066025,
|
||||||
|
"width": 100,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`move element rectangles with binding arrow 2`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"boundElementIds": Array [
|
||||||
|
"id2",
|
||||||
|
],
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"groupIds": Array [],
|
||||||
|
"height": 300,
|
||||||
|
"id": "id1",
|
||||||
|
"isDeleted": false,
|
||||||
|
"opacity": 100,
|
||||||
|
"roughness": 1,
|
||||||
|
"seed": 449462985,
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"strokeSharpness": "sharp",
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"type": "rectangle",
|
||||||
|
"version": 6,
|
||||||
|
"versionNonce": 1723083209,
|
||||||
|
"width": 300,
|
||||||
|
"x": 201,
|
||||||
|
"y": 2,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`move element rectangles with binding arrow 3`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"boundElementIds": null,
|
||||||
|
"endBinding": Object {
|
||||||
|
"elementId": "id1",
|
||||||
|
"focus": -0.46666666666666673,
|
||||||
|
"gap": 10,
|
||||||
|
},
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"groupIds": Array [],
|
||||||
|
"height": 81.48231043525051,
|
||||||
|
"id": "id2",
|
||||||
|
"isDeleted": false,
|
||||||
|
"lastCommittedPoint": null,
|
||||||
|
"opacity": 100,
|
||||||
|
"points": Array [
|
||||||
|
Array [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
81,
|
||||||
|
81.48231043525051,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"roughness": 1,
|
||||||
|
"seed": 401146281,
|
||||||
|
"startBinding": Object {
|
||||||
|
"elementId": "id0",
|
||||||
|
"focus": -0.6000000000000001,
|
||||||
|
"gap": 10,
|
||||||
|
},
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"strokeSharpness": "round",
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"type": "line",
|
||||||
|
"version": 11,
|
||||||
|
"versionNonce": 1006504105,
|
||||||
|
"width": 81,
|
||||||
|
"x": 110,
|
||||||
|
"y": 49.981789081137734,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
@ -4,6 +4,13 @@ import { render, fireEvent } from "./test-utils";
|
|||||||
import App from "../components/App";
|
import App from "../components/App";
|
||||||
import * as Renderer from "../renderer/renderScene";
|
import * as Renderer from "../renderer/renderScene";
|
||||||
import { reseed } from "../random";
|
import { reseed } from "../random";
|
||||||
|
import { bindOrUnbindLinearElement } from "../element/binding";
|
||||||
|
import {
|
||||||
|
ExcalidrawLinearElement,
|
||||||
|
NonDeleted,
|
||||||
|
ExcalidrawRectangleElement,
|
||||||
|
} from "../element/types";
|
||||||
|
import { UI, Pointer, Keyboard } from "./helpers/ui";
|
||||||
|
|
||||||
// Unmount ReactDOM from root
|
// Unmount ReactDOM from root
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
||||||
@ -50,6 +57,53 @@ describe("move element", () => {
|
|||||||
|
|
||||||
h.elements.forEach((element) => expect(element).toMatchSnapshot());
|
h.elements.forEach((element) => expect(element).toMatchSnapshot());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("rectangles with binding arrow", () => {
|
||||||
|
render(<App />);
|
||||||
|
|
||||||
|
// create elements
|
||||||
|
const rectA = UI.createElement("rectangle", { size: 100 });
|
||||||
|
const rectB = UI.createElement("rectangle", { x: 200, y: 0, size: 300 });
|
||||||
|
const line = UI.createElement("line", { x: 110, y: 50, size: 80 });
|
||||||
|
|
||||||
|
// bind line to two rectangles
|
||||||
|
bindOrUnbindLinearElement(
|
||||||
|
line as NonDeleted<ExcalidrawLinearElement>,
|
||||||
|
rectA as ExcalidrawRectangleElement,
|
||||||
|
rectB as ExcalidrawRectangleElement,
|
||||||
|
);
|
||||||
|
|
||||||
|
// select the second rectangles
|
||||||
|
new Pointer("mouse").clickOn(rectB);
|
||||||
|
|
||||||
|
expect(renderScene).toHaveBeenCalledTimes(19);
|
||||||
|
expect(h.state.selectionElement).toBeNull();
|
||||||
|
expect(h.elements.length).toEqual(3);
|
||||||
|
expect(h.state.selectedElementIds[rectB.id]).toBeTruthy();
|
||||||
|
expect([rectA.x, rectA.y]).toEqual([0, 0]);
|
||||||
|
expect([rectB.x, rectB.y]).toEqual([200, 0]);
|
||||||
|
expect([line.x, line.y]).toEqual([110, 50]);
|
||||||
|
expect([line.width, line.height]).toEqual([80, 80]);
|
||||||
|
|
||||||
|
renderScene.mockClear();
|
||||||
|
|
||||||
|
// Move selected rectangle
|
||||||
|
Keyboard.keyDown("ArrowRight");
|
||||||
|
Keyboard.keyDown("ArrowDown");
|
||||||
|
Keyboard.keyDown("ArrowDown");
|
||||||
|
|
||||||
|
// Check that the arrow size has been changed according to moving the rectangle
|
||||||
|
expect(renderScene).toHaveBeenCalledTimes(3);
|
||||||
|
expect(h.state.selectionElement).toBeNull();
|
||||||
|
expect(h.elements.length).toEqual(3);
|
||||||
|
expect(h.state.selectedElementIds[rectB.id]).toBeTruthy();
|
||||||
|
expect([rectA.x, rectA.y]).toEqual([0, 0]);
|
||||||
|
expect([rectB.x, rectB.y]).toEqual([201, 2]);
|
||||||
|
expect([Math.round(line.x), Math.round(line.y)]).toEqual([110, 50]);
|
||||||
|
expect([Math.round(line.width), Math.round(line.height)]).toEqual([81, 81]);
|
||||||
|
|
||||||
|
h.elements.forEach((element) => expect(element).toMatchSnapshot());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("duplicate element on move when ALT is clicked", () => {
|
describe("duplicate element on move when ALT is clicked", () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user