123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- import { KEYS } from "@excalidraw/common";
- import {
- actionAlignVerticallyCentered,
- actionAlignHorizontallyCentered,
- actionGroup,
- actionAlignTop,
- actionAlignBottom,
- actionAlignLeft,
- actionAlignRight,
- } from "@excalidraw/excalidraw/actions";
- import { defaultLang, setLanguage } from "@excalidraw/excalidraw/i18n";
- import { Excalidraw } from "@excalidraw/excalidraw";
- import { API } from "@excalidraw/excalidraw/tests/helpers/api";
- import { UI, Pointer, Keyboard } from "@excalidraw/excalidraw/tests/helpers/ui";
- import {
- act,
- unmountComponent,
- render,
- } from "@excalidraw/excalidraw/tests/test-utils";
- const mouse = new Pointer("mouse");
- const createAndSelectTwoRectangles = () => {
- UI.clickTool("rectangle");
- mouse.down();
- mouse.up(100, 100);
- UI.clickTool("rectangle");
- mouse.down(10, 10);
- mouse.up(100, 100);
- // Select the first element.
- // The second rectangle is already reselected because it was the last element created
- mouse.reset();
- Keyboard.withModifierKeys({ shift: true }, () => {
- mouse.click();
- });
- };
- const createAndSelectTwoRectanglesWithDifferentSizes = () => {
- UI.clickTool("rectangle");
- mouse.down();
- mouse.up(100, 100);
- UI.clickTool("rectangle");
- mouse.down(10, 10);
- mouse.up(110, 110);
- // Select the first element.
- // The second rectangle is already reselected because it was the last element created
- mouse.reset();
- Keyboard.withModifierKeys({ shift: true }, () => {
- mouse.click();
- });
- };
- describe("aligning", () => {
- beforeEach(async () => {
- unmountComponent();
- mouse.reset();
- await act(() => {
- return setLanguage(defaultLang);
- });
- await render(<Excalidraw handleKeyboardGlobally={true} />);
- });
- it("aligns two objects correctly to the top", () => {
- createAndSelectTwoRectangles();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(110);
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(110);
- Keyboard.withModifierKeys({ ctrl: true, shift: true }, () => {
- Keyboard.keyPress(KEYS.ARROW_UP);
- });
- // Check if x position did not change
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(110);
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(0);
- });
- it("aligns two objects correctly to the bottom", () => {
- createAndSelectTwoRectangles();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(110);
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(110);
- Keyboard.withModifierKeys({ ctrl: true, shift: true }, () => {
- Keyboard.keyPress(KEYS.ARROW_DOWN);
- });
- // Check if x position did not change
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(110);
- expect(API.getSelectedElements()[0].y).toEqual(110);
- expect(API.getSelectedElements()[1].y).toEqual(110);
- });
- it("aligns two objects correctly to the left", () => {
- createAndSelectTwoRectangles();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(110);
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(110);
- Keyboard.withModifierKeys({ ctrl: true, shift: true }, () => {
- Keyboard.keyPress(KEYS.ARROW_LEFT);
- });
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(0);
- // Check if y position did not change
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(110);
- });
- it("aligns two objects correctly to the right", () => {
- createAndSelectTwoRectangles();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(110);
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(110);
- Keyboard.withModifierKeys({ ctrl: true, shift: true }, () => {
- Keyboard.keyPress(KEYS.ARROW_RIGHT);
- });
- expect(API.getSelectedElements()[0].x).toEqual(110);
- expect(API.getSelectedElements()[1].x).toEqual(110);
- // Check if y position did not change
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(110);
- });
- it("centers two objects with different sizes correctly vertically", () => {
- createAndSelectTwoRectanglesWithDifferentSizes();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(110);
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(110);
- API.executeAction(actionAlignVerticallyCentered);
- // Check if x position did not change
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(110);
- expect(API.getSelectedElements()[0].y).toEqual(60);
- expect(API.getSelectedElements()[1].y).toEqual(55);
- });
- it("centers two objects with different sizes correctly horizontally", () => {
- createAndSelectTwoRectanglesWithDifferentSizes();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(110);
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(110);
- API.executeAction(actionAlignHorizontallyCentered);
- expect(API.getSelectedElements()[0].x).toEqual(60);
- expect(API.getSelectedElements()[1].x).toEqual(55);
- // Check if y position did not change
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(110);
- });
- const createAndSelectGroupAndRectangle = () => {
- UI.clickTool("rectangle");
- mouse.down();
- mouse.up(100, 100);
- UI.clickTool("rectangle");
- mouse.down(0, 0);
- mouse.up(100, 100);
- // Select the first element.
- // The second rectangle is already reselected because it was the last element created
- mouse.reset();
- Keyboard.withModifierKeys({ shift: true }, () => {
- mouse.click();
- });
- API.executeAction(actionGroup);
- mouse.reset();
- UI.clickTool("rectangle");
- mouse.down(200, 200);
- mouse.up(100, 100);
- // Add the created group to the current selection
- mouse.restorePosition(0, 0);
- Keyboard.withModifierKeys({ shift: true }, () => {
- mouse.click();
- });
- };
- it("aligns a group with another element correctly to the top", () => {
- createAndSelectGroupAndRectangle();
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- API.executeAction(actionAlignTop);
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(0);
- });
- it("aligns a group with another element correctly to the bottom", () => {
- createAndSelectGroupAndRectangle();
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- API.executeAction(actionAlignBottom);
- expect(API.getSelectedElements()[0].y).toEqual(100);
- expect(API.getSelectedElements()[1].y).toEqual(200);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- });
- it("aligns a group with another element correctly to the left", () => {
- createAndSelectGroupAndRectangle();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- API.executeAction(actionAlignLeft);
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(0);
- });
- it("aligns a group with another element correctly to the right", () => {
- createAndSelectGroupAndRectangle();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- API.executeAction(actionAlignRight);
- expect(API.getSelectedElements()[0].x).toEqual(100);
- expect(API.getSelectedElements()[1].x).toEqual(200);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- });
- it("centers a group with another element correctly vertically", () => {
- createAndSelectGroupAndRectangle();
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- API.executeAction(actionAlignVerticallyCentered);
- expect(API.getSelectedElements()[0].y).toEqual(50);
- expect(API.getSelectedElements()[1].y).toEqual(150);
- expect(API.getSelectedElements()[2].y).toEqual(100);
- });
- it("centers a group with another element correctly horizontally", () => {
- createAndSelectGroupAndRectangle();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- API.executeAction(actionAlignHorizontallyCentered);
- expect(API.getSelectedElements()[0].x).toEqual(50);
- expect(API.getSelectedElements()[1].x).toEqual(150);
- expect(API.getSelectedElements()[2].x).toEqual(100);
- });
- const createAndSelectTwoGroups = () => {
- UI.clickTool("rectangle");
- mouse.down();
- mouse.up(100, 100);
- UI.clickTool("rectangle");
- mouse.down(0, 0);
- mouse.up(100, 100);
- // Select the first element.
- // The second rectangle is already selected because it was the last element created
- mouse.reset();
- Keyboard.withModifierKeys({ shift: true }, () => {
- mouse.click();
- });
- API.executeAction(actionGroup);
- mouse.reset();
- UI.clickTool("rectangle");
- mouse.down(200, 200);
- mouse.up(100, 100);
- UI.clickTool("rectangle");
- mouse.down();
- mouse.up(100, 100);
- mouse.restorePosition(200, 200);
- Keyboard.withModifierKeys({ shift: true }, () => {
- mouse.click();
- });
- API.executeAction(actionGroup);
- // Select the first group.
- // The second group is already selected because it was the last group created
- mouse.reset();
- Keyboard.withModifierKeys({ shift: true }, () => {
- mouse.click();
- });
- };
- it("aligns two groups correctly to the top", () => {
- createAndSelectTwoGroups();
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- expect(API.getSelectedElements()[3].y).toEqual(300);
- API.executeAction(actionAlignTop);
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(0);
- expect(API.getSelectedElements()[3].y).toEqual(100);
- });
- it("aligns two groups correctly to the bottom", () => {
- createAndSelectTwoGroups();
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- expect(API.getSelectedElements()[3].y).toEqual(300);
- API.executeAction(actionAlignBottom);
- expect(API.getSelectedElements()[0].y).toEqual(200);
- expect(API.getSelectedElements()[1].y).toEqual(300);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- expect(API.getSelectedElements()[3].y).toEqual(300);
- });
- it("aligns two groups correctly to the left", () => {
- createAndSelectTwoGroups();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- expect(API.getSelectedElements()[3].x).toEqual(300);
- API.executeAction(actionAlignLeft);
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(0);
- expect(API.getSelectedElements()[3].x).toEqual(100);
- });
- it("aligns two groups correctly to the right", () => {
- createAndSelectTwoGroups();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- expect(API.getSelectedElements()[3].x).toEqual(300);
- API.executeAction(actionAlignRight);
- expect(API.getSelectedElements()[0].x).toEqual(200);
- expect(API.getSelectedElements()[1].x).toEqual(300);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- expect(API.getSelectedElements()[3].x).toEqual(300);
- });
- it("centers two groups correctly vertically", () => {
- createAndSelectTwoGroups();
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- expect(API.getSelectedElements()[3].y).toEqual(300);
- API.executeAction(actionAlignVerticallyCentered);
- expect(API.getSelectedElements()[0].y).toEqual(100);
- expect(API.getSelectedElements()[1].y).toEqual(200);
- expect(API.getSelectedElements()[2].y).toEqual(100);
- expect(API.getSelectedElements()[3].y).toEqual(200);
- });
- it("centers two groups correctly horizontally", () => {
- createAndSelectTwoGroups();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- expect(API.getSelectedElements()[3].x).toEqual(300);
- API.executeAction(actionAlignHorizontallyCentered);
- expect(API.getSelectedElements()[0].x).toEqual(100);
- expect(API.getSelectedElements()[1].x).toEqual(200);
- expect(API.getSelectedElements()[2].x).toEqual(100);
- expect(API.getSelectedElements()[3].x).toEqual(200);
- });
- const createAndSelectNestedGroupAndRectangle = () => {
- UI.clickTool("rectangle");
- mouse.down();
- mouse.up(100, 100);
- UI.clickTool("rectangle");
- mouse.down(0, 0);
- mouse.up(100, 100);
- // Select the first element.
- // The second rectangle is already reselected because it was the last element created
- mouse.reset();
- Keyboard.withModifierKeys({ shift: true }, () => {
- mouse.click();
- });
- // Create first group of rectangles
- API.executeAction(actionGroup);
- mouse.reset();
- UI.clickTool("rectangle");
- mouse.down(200, 200);
- mouse.up(100, 100);
- // Add group to current selection
- mouse.restorePosition(0, 0);
- Keyboard.withModifierKeys({ shift: true }, () => {
- mouse.click();
- });
- // Create the nested group
- API.executeAction(actionGroup);
- mouse.reset();
- UI.clickTool("rectangle");
- mouse.down(300, 300);
- mouse.up(100, 100);
- // Select the nested group, the rectangle is already selected
- mouse.reset();
- Keyboard.withModifierKeys({ shift: true }, () => {
- mouse.click();
- });
- };
- it("aligns nested group and other element correctly to the top", () => {
- createAndSelectNestedGroupAndRectangle();
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- expect(API.getSelectedElements()[3].y).toEqual(300);
- API.executeAction(actionAlignTop);
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- expect(API.getSelectedElements()[3].y).toEqual(0);
- });
- it("aligns nested group and other element correctly to the bottom", () => {
- createAndSelectNestedGroupAndRectangle();
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- expect(API.getSelectedElements()[3].y).toEqual(300);
- API.executeAction(actionAlignBottom);
- expect(API.getSelectedElements()[0].y).toEqual(100);
- expect(API.getSelectedElements()[1].y).toEqual(200);
- expect(API.getSelectedElements()[2].y).toEqual(300);
- expect(API.getSelectedElements()[3].y).toEqual(300);
- });
- it("aligns nested group and other element correctly to the left", () => {
- createAndSelectNestedGroupAndRectangle();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- expect(API.getSelectedElements()[3].x).toEqual(300);
- API.executeAction(actionAlignLeft);
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- expect(API.getSelectedElements()[3].x).toEqual(0);
- });
- it("aligns nested group and other element correctly to the right", () => {
- createAndSelectNestedGroupAndRectangle();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- expect(API.getSelectedElements()[3].x).toEqual(300);
- API.executeAction(actionAlignRight);
- expect(API.getSelectedElements()[0].x).toEqual(100);
- expect(API.getSelectedElements()[1].x).toEqual(200);
- expect(API.getSelectedElements()[2].x).toEqual(300);
- expect(API.getSelectedElements()[3].x).toEqual(300);
- });
- it("centers nested group and other element correctly vertically", () => {
- createAndSelectNestedGroupAndRectangle();
- expect(API.getSelectedElements()[0].y).toEqual(0);
- expect(API.getSelectedElements()[1].y).toEqual(100);
- expect(API.getSelectedElements()[2].y).toEqual(200);
- expect(API.getSelectedElements()[3].y).toEqual(300);
- API.executeAction(actionAlignVerticallyCentered);
- expect(API.getSelectedElements()[0].y).toEqual(50);
- expect(API.getSelectedElements()[1].y).toEqual(150);
- expect(API.getSelectedElements()[2].y).toEqual(250);
- expect(API.getSelectedElements()[3].y).toEqual(150);
- });
- it("centers nested group and other element correctly horizontally", () => {
- createAndSelectNestedGroupAndRectangle();
- expect(API.getSelectedElements()[0].x).toEqual(0);
- expect(API.getSelectedElements()[1].x).toEqual(100);
- expect(API.getSelectedElements()[2].x).toEqual(200);
- expect(API.getSelectedElements()[3].x).toEqual(300);
- API.executeAction(actionAlignHorizontallyCentered);
- expect(API.getSelectedElements()[0].x).toEqual(50);
- expect(API.getSelectedElements()[1].x).toEqual(150);
- expect(API.getSelectedElements()[2].x).toEqual(250);
- expect(API.getSelectedElements()[3].x).toEqual(150);
- });
- });
|