Browse Source

feat: Calculate `width/height` of canvas based on container dimensions (".excalidraw" selector) & remove props width & height (#3379)

* Remove width/height from the ".excalidraw" container so it will sized automatically.
* updated all ref calculation to ".excalidraw" instead of parent since now ".excalidraw" will get resized
* Remove props width/height as its not needed anymore.
* Resize handler is also not needed anymore.
* Position absolute canvas due to #3379 (comment)

* move css to style and remove one extra rerendering

* factor out mock logic for test

* set height, width so as to avoid unnecessary updates of regression snap

* better mock

* better type checking and omit width,height from getDefaultAppState and also restore

* revert

* default to window dimensions in constructor

* update docs

* update

* update

* tweaks
vanilla_orig
Aakansha Doshi 4 years ago
parent
commit
c54a099010
No account linked to committer's email address

+ 3
- 0
public/index.html View File

147
         color: var(--popup-text-color);
147
         color: var(--popup-text-color);
148
         font-size: 1.3em;
148
         font-size: 1.3em;
149
       }
149
       }
150
+      #root {
151
+        height: 100%;
152
+      }
150
     </style>
153
     </style>
151
   </head>
154
   </head>
152
 
155
 

+ 4
- 1
src/actions/types.ts View File

6
 export type ActionResult =
6
 export type ActionResult =
7
   | {
7
   | {
8
       elements?: readonly ExcalidrawElement[] | null;
8
       elements?: readonly ExcalidrawElement[] | null;
9
-      appState?: MarkOptional<AppState, "offsetTop" | "offsetLeft"> | null;
9
+      appState?: MarkOptional<
10
+        AppState,
11
+        "offsetTop" | "offsetLeft" | "width" | "height"
12
+      > | null;
10
       commitToHistory: boolean;
13
       commitToHistory: boolean;
11
       syncHistory?: boolean;
14
       syncHistory?: boolean;
12
     }
15
     }

+ 1
- 3
src/appState.ts View File

10
 
10
 
11
 export const getDefaultAppState = (): Omit<
11
 export const getDefaultAppState = (): Omit<
12
   AppState,
12
   AppState,
13
-  "offsetTop" | "offsetLeft"
13
+  "offsetTop" | "offsetLeft" | "width" | "height"
14
 > => {
14
 > => {
15
   return {
15
   return {
16
     theme: "light",
16
     theme: "light",
43
     exportWithDarkMode: false,
43
     exportWithDarkMode: false,
44
     fileHandle: null,
44
     fileHandle: null,
45
     gridSize: null,
45
     gridSize: null,
46
-    height: window.innerHeight,
47
     isBindingEnabled: true,
46
     isBindingEnabled: true,
48
     isLibraryOpen: false,
47
     isLibraryOpen: false,
49
     isLoading: false,
48
     isLoading: false,
70
     suggestedBindings: [],
69
     suggestedBindings: [],
71
     toastMessage: null,
70
     toastMessage: null,
72
     viewBackgroundColor: oc.white,
71
     viewBackgroundColor: oc.white,
73
-    width: window.innerWidth,
74
     zenModeEnabled: false,
72
     zenModeEnabled: false,
75
     zoom: { value: 1 as NormalizedZoomValue, translation: { x: 0, y: 0 } },
73
     zoom: { value: 1 as NormalizedZoomValue, translation: { x: 0, y: 0 } },
76
     viewModeEnabled: false,
74
     viewModeEnabled: false,

+ 53
- 45
src/components/App.tsx View File

293
   actionManager: ActionManager;
293
   actionManager: ActionManager;
294
   private excalidrawContainerRef = React.createRef<HTMLDivElement>();
294
   private excalidrawContainerRef = React.createRef<HTMLDivElement>();
295
 
295
 
296
-  public static defaultProps: Partial<ExcalidrawProps> = {
297
-    width: window.innerWidth,
298
-    height: window.innerHeight,
299
-  };
300
   private scene: Scene;
296
   private scene: Scene;
301
   private resizeObserver: ResizeObserver | undefined;
297
   private resizeObserver: ResizeObserver | undefined;
302
   constructor(props: ExcalidrawProps) {
298
   constructor(props: ExcalidrawProps) {
303
     super(props);
299
     super(props);
304
     const defaultAppState = getDefaultAppState();
300
     const defaultAppState = getDefaultAppState();
305
-
306
     const {
301
     const {
307
-      width = window.innerWidth,
308
-      height = window.innerHeight,
309
       excalidrawRef,
302
       excalidrawRef,
310
       viewModeEnabled = false,
303
       viewModeEnabled = false,
311
       zenModeEnabled = false,
304
       zenModeEnabled = false,
317
       ...defaultAppState,
310
       ...defaultAppState,
318
       theme,
311
       theme,
319
       isLoading: true,
312
       isLoading: true,
320
-      width,
321
-      height,
322
       ...this.getCanvasOffsets(),
313
       ...this.getCanvasOffsets(),
323
       viewModeEnabled,
314
       viewModeEnabled,
324
       zenModeEnabled,
315
       zenModeEnabled,
325
       gridSize: gridModeEnabled ? GRID_SIZE : null,
316
       gridSize: gridModeEnabled ? GRID_SIZE : null,
326
       name,
317
       name,
318
+      width: window.innerWidth,
319
+      height: window.innerHeight,
327
     };
320
     };
328
     if (excalidrawRef) {
321
     if (excalidrawRef) {
329
       const readyPromise =
322
       const readyPromise =
447
           "excalidraw--view-mode": viewModeEnabled,
440
           "excalidraw--view-mode": viewModeEnabled,
448
         })}
441
         })}
449
         ref={this.excalidrawContainerRef}
442
         ref={this.excalidrawContainerRef}
450
-        style={{
451
-          width: canvasDOMWidth,
452
-          height: canvasDOMHeight,
453
-        }}
454
       >
443
       >
455
         <LayerUI
444
         <LayerUI
456
           canvas={this.canvas}
445
           canvas={this.canvas}
561
         if (typeof this.props.name !== "undefined") {
550
         if (typeof this.props.name !== "undefined") {
562
           name = this.props.name;
551
           name = this.props.name;
563
         }
552
         }
564
-
565
         this.setState(
553
         this.setState(
566
           (state) => {
554
           (state) => {
567
             // using Object.assign instead of spread to fool TS 4.2.2+ into
555
             // using Object.assign instead of spread to fool TS 4.2.2+ into
570
             return Object.assign(actionResult.appState || {}, {
558
             return Object.assign(actionResult.appState || {}, {
571
               editingElement:
559
               editingElement:
572
                 editingElement || actionResult.appState?.editingElement || null,
560
                 editingElement || actionResult.appState?.editingElement || null,
573
-              width: state.width,
574
-              height: state.height,
575
-              offsetTop: state.offsetTop,
576
-              offsetLeft: state.offsetLeft,
577
               viewModeEnabled,
561
               viewModeEnabled,
578
               zenModeEnabled,
562
               zenModeEnabled,
579
               gridSize,
563
               gridSize,
706
     if (!this.state.isLoading) {
690
     if (!this.state.isLoading) {
707
       this.setState({ isLoading: true });
691
       this.setState({ isLoading: true });
708
     }
692
     }
709
-
710
     let initialData = null;
693
     let initialData = null;
711
     try {
694
     try {
712
       initialData = (await this.props.initialData) || null;
695
       initialData = (await this.props.initialData) || null;
715
     }
698
     }
716
 
699
 
717
     const scene = restore(initialData, null);
700
     const scene = restore(initialData, null);
718
-
719
     scene.appState = {
701
     scene.appState = {
720
       ...scene.appState,
702
       ...scene.appState,
721
       isLoading: false,
703
       isLoading: false,
787
     this.scene.addCallback(this.onSceneUpdated);
769
     this.scene.addCallback(this.onSceneUpdated);
788
     this.addEventListeners();
770
     this.addEventListeners();
789
 
771
 
790
-    if (
791
-      "ResizeObserver" in window &&
792
-      this.excalidrawContainerRef?.current?.parentElement
793
-    ) {
794
-      this.resizeObserver = new ResizeObserver(() => this.setCanvasOffsets());
795
-      this.resizeObserver?.observe(
796
-        this.excalidrawContainerRef.current.parentElement,
797
-      );
772
+    if ("ResizeObserver" in window && this.excalidrawContainerRef?.current) {
773
+      this.resizeObserver = new ResizeObserver(() => {
774
+        this.updateDOMRect();
775
+      });
776
+      this.resizeObserver?.observe(this.excalidrawContainerRef.current);
798
     }
777
     }
799
     const searchParams = new URLSearchParams(window.location.search.slice(1));
778
     const searchParams = new URLSearchParams(window.location.search.slice(1));
800
 
779
 
802
       // Obtain a file that was shared via the Web Share Target API.
781
       // Obtain a file that was shared via the Web Share Target API.
803
       this.restoreFileFromShare();
782
       this.restoreFileFromShare();
804
     } else {
783
     } else {
805
-      this.setState(this.getCanvasOffsets(), () => {
806
-        this.initializeScene();
807
-      });
784
+      this.updateDOMRect(this.initializeScene);
808
     }
785
     }
809
   }
786
   }
810
 
787
 
906
       this.updateLanguage();
883
       this.updateLanguage();
907
     }
884
     }
908
 
885
 
909
-    if (
910
-      prevProps.width !== this.props.width ||
911
-      prevProps.height !== this.props.height
912
-    ) {
913
-      this.setState({
914
-        width: this.props.width ?? window.innerWidth,
915
-        height: this.props.height ?? window.innerHeight,
916
-        ...this.getCanvasOffsets(),
917
-      });
918
-    }
919
-
920
     if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {
886
     if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {
921
       this.setState(
887
       this.setState(
922
         { viewModeEnabled: !!this.props.viewModeEnabled },
888
         { viewModeEnabled: !!this.props.viewModeEnabled },
4093
     }
4059
     }
4094
   }, 300);
4060
   }, 300);
4095
 
4061
 
4062
+  private updateDOMRect = (cb?: () => void) => {
4063
+    if (this.excalidrawContainerRef?.current) {
4064
+      const excalidrawContainer = this.excalidrawContainerRef.current;
4065
+      const {
4066
+        width,
4067
+        height,
4068
+        left: offsetLeft,
4069
+        top: offsetTop,
4070
+      } = excalidrawContainer.getBoundingClientRect();
4071
+      const {
4072
+        width: currentWidth,
4073
+        height: currentHeight,
4074
+        offsetTop: currentOffsetTop,
4075
+        offsetLeft: currentOffsetLeft,
4076
+      } = this.state;
4077
+
4078
+      if (
4079
+        width === currentWidth &&
4080
+        height === currentHeight &&
4081
+        offsetLeft === currentOffsetLeft &&
4082
+        offsetTop === currentOffsetTop
4083
+      ) {
4084
+        if (cb) {
4085
+          cb();
4086
+        }
4087
+        return;
4088
+      }
4089
+
4090
+      this.setState(
4091
+        {
4092
+          width,
4093
+          height,
4094
+          offsetLeft,
4095
+          offsetTop,
4096
+        },
4097
+        () => {
4098
+          cb && cb();
4099
+        },
4100
+      );
4101
+    }
4102
+  };
4103
+
4096
   public setCanvasOffsets = () => {
4104
   public setCanvasOffsets = () => {
4097
     this.setState({ ...this.getCanvasOffsets() });
4105
     this.setState({ ...this.getCanvasOffsets() });
4098
   };
4106
   };
4099
 
4107
 
4100
   private getCanvasOffsets(): Pick<AppState, "offsetTop" | "offsetLeft"> {
4108
   private getCanvasOffsets(): Pick<AppState, "offsetTop" | "offsetLeft"> {
4101
-    if (this.excalidrawContainerRef?.current?.parentElement) {
4102
-      const parentElement = this.excalidrawContainerRef.current.parentElement;
4103
-      const { left, top } = parentElement.getBoundingClientRect();
4109
+    if (this.excalidrawContainerRef?.current) {
4110
+      const excalidrawContainer = this.excalidrawContainerRef.current;
4111
+      const { left, top } = excalidrawContainer.getBoundingClientRect();
4104
       return {
4112
       return {
4105
         offsetLeft: left,
4113
         offsetLeft: left,
4106
         offsetTop: top,
4114
         offsetTop: top,

+ 6
- 0
src/css/styles.scss View File

16
   bottom: 0;
16
   bottom: 0;
17
   left: 0;
17
   left: 0;
18
   right: 0;
18
   right: 0;
19
+  height: 100%;
20
+  width: 100%;
19
 
21
 
20
   // serves 2 purposes:
22
   // serves 2 purposes:
21
   // 1. prevent selecting text outside the component when double-clicking or
23
   // 1. prevent selecting text outside the component when double-clicking or
45
     image-rendering: -moz-crisp-edges; // FF
47
     image-rendering: -moz-crisp-edges; // FF
46
 
48
 
47
     z-index: var(--zIndex-canvas);
49
     z-index: var(--zIndex-canvas);
50
+
51
+    // Remove canvas from document flow to avoid resizeObserver feedback loop
52
+    // (see https://github.com/excalidraw/excalidraw/pull/3379)
53
+    position: absolute;
48
   }
54
   }
49
 
55
 
50
   &.theme--dark {
56
   &.theme--dark {

+ 1
- 3
src/data/restore.ts View File

144
 export const restoreAppState = (
144
 export const restoreAppState = (
145
   appState: ImportedDataState["appState"],
145
   appState: ImportedDataState["appState"],
146
   localAppState: Partial<AppState> | null,
146
   localAppState: Partial<AppState> | null,
147
-): AppState => {
147
+): DataState["appState"] => {
148
   appState = appState || {};
148
   appState = appState || {};
149
 
149
 
150
   const defaultAppState = getDefaultAppState();
150
   const defaultAppState = getDefaultAppState();
166
 
166
 
167
   return {
167
   return {
168
     ...nextAppState,
168
     ...nextAppState,
169
-    offsetLeft: appState.offsetLeft || 0,
170
-    offsetTop: appState.offsetTop || 0,
171
     // Migrates from previous version where appState.zoom was a number
169
     // Migrates from previous version where appState.zoom was a number
172
     zoom:
170
     zoom:
173
       typeof appState.zoom === "number"
171
       typeof appState.zoom === "number"

+ 1
- 1
src/data/types.ts View File

6
   version?: string;
6
   version?: string;
7
   source?: string;
7
   source?: string;
8
   elements: readonly ExcalidrawElement[];
8
   elements: readonly ExcalidrawElement[];
9
-  appState: MarkOptional<AppState, "offsetTop" | "offsetLeft">;
9
+  appState: Omit<AppState, "offsetTop" | "offsetLeft" | "width" | "height">;
10
 }
10
 }
11
 
11
 
12
 export interface ImportedDataState {
12
 export interface ImportedDataState {

+ 0
- 23
src/excalidraw-app/index.tsx View File

3
   useCallback,
3
   useCallback,
4
   useContext,
4
   useContext,
5
   useEffect,
5
   useEffect,
6
-  useLayoutEffect,
7
   useRef,
6
   useRef,
8
   useState,
7
   useState,
9
 } from "react";
8
 } from "react";
163
 };
162
 };
164
 
163
 
165
 const ExcalidrawWrapper = () => {
164
 const ExcalidrawWrapper = () => {
166
-  // dimensions
167
-  // ---------------------------------------------------------------------------
168
-
169
-  const [dimensions, setDimensions] = useState({
170
-    width: window.innerWidth,
171
-    height: window.innerHeight,
172
-  });
173
   const [errorMessage, setErrorMessage] = useState("");
165
   const [errorMessage, setErrorMessage] = useState("");
174
   const currentLangCode = languageDetector.detect() || defaultLang.code;
166
   const currentLangCode = languageDetector.detect() || defaultLang.code;
175
   const [langCode, setLangCode] = useState(currentLangCode);
167
   const [langCode, setLangCode] = useState(currentLangCode);
176
 
168
 
177
-  useLayoutEffect(() => {
178
-    const onResize = () => {
179
-      setDimensions({
180
-        width: window.innerWidth,
181
-        height: window.innerHeight,
182
-      });
183
-    };
184
-
185
-    window.addEventListener("resize", onResize);
186
-
187
-    return () => window.removeEventListener("resize", onResize);
188
-  }, []);
189
-
190
   // initial state
169
   // initial state
191
   // ---------------------------------------------------------------------------
170
   // ---------------------------------------------------------------------------
192
 
171
 
337
       <Excalidraw
316
       <Excalidraw
338
         ref={excalidrawRefCallback}
317
         ref={excalidrawRefCallback}
339
         onChange={onChange}
318
         onChange={onChange}
340
-        width={dimensions.width}
341
-        height={dimensions.height}
342
         initialData={initialStatePromiseRef.current.promise}
319
         initialData={initialStatePromiseRef.current.promise}
343
         onCollabButtonClick={collabAPI?.onCollabButtonClick}
320
         onCollabButtonClick={collabAPI?.onCollabButtonClick}
344
         isCollaborating={collabAPI?.isCollaborating()}
321
         isCollaborating={collabAPI?.isCollaborating()}

+ 2
- 0
src/index-node.ts View File

63
     ...getDefaultAppState(),
63
     ...getDefaultAppState(),
64
     offsetTop: 0,
64
     offsetTop: 0,
65
     offsetLeft: 0,
65
     offsetLeft: 0,
66
+    width: 0,
67
+    height: 0,
66
   },
68
   },
67
   {
69
   {
68
     exportBackground: true,
70
     exportBackground: true,

+ 3
- 0
src/packages/excalidraw/CHANGELOG.md View File

18
 
18
 
19
 ### Features
19
 ### Features
20
 
20
 
21
+- Calculate `width/height` of canvas based on excalidraw component (".excalidraw" selector) & also resize and update offsets whenever the dimensions of excalidraw component gets updated [#3379](https://github.com/excalidraw/excalidraw/pull/3379). You also don't need to add a resize handler anymore for excalidraw as its handled now in excalidraw itself.
22
+  #### BREAKING CHANGE
23
+  - `width/height` props have been removed. Instead now it takes `100%` of `width` and `height` of the container so you need to make sure the container in which you are rendering Excalidraw has non zero dimensions (It should have non zero width and height so Excalidraw can match the dimensions of containing block)
21
 - Calculate offsets when excalidraw container resizes using resize observer api [#3374](https://github.com/excalidraw/excalidraw/pull/3374).
24
 - Calculate offsets when excalidraw container resizes using resize observer api [#3374](https://github.com/excalidraw/excalidraw/pull/3374).
22
 - Export types for the package so now it can be used with typescript [#3337](https://github.com/excalidraw/excalidraw/pull/3337). The types are available at `@excalidraw/excalirdraw/types`.
25
 - Export types for the package so now it can be used with typescript [#3337](https://github.com/excalidraw/excalidraw/pull/3337). The types are available at `@excalidraw/excalirdraw/types`.
23
 - Add `renderCustomStats` prop to render extra stats on host, and expose `setToastMessage` API via refs which can be used to show toast with custom message [#3360](https://github.com/excalidraw/excalidraw/pull/3360).
26
 - Add `renderCustomStats` prop to render extra stats on host, and expose `setToastMessage` API via refs which can be used to show toast with custom message [#3360](https://github.com/excalidraw/excalidraw/pull/3360).

+ 4
- 58
src/packages/excalidraw/README_NEXT.md View File

45
 
45
 
46
 export default function App() {
46
 export default function App() {
47
   const excalidrawRef = useRef(null);
47
   const excalidrawRef = useRef(null);
48
-  const excalidrawWrapperRef = useRef(null);
49
-  const [dimensions, setDimensions] = useState({
50
-    width: undefined,
51
-    height: undefined,
52
-  });
53
 
48
 
54
   const [viewModeEnabled, setViewModeEnabled] = useState(false);
49
   const [viewModeEnabled, setViewModeEnabled] = useState(false);
55
   const [zenModeEnabled, setZenModeEnabled] = useState(false);
50
   const [zenModeEnabled, setZenModeEnabled] = useState(false);
56
   const [gridModeEnabled, setGridModeEnabled] = useState(false);
51
   const [gridModeEnabled, setGridModeEnabled] = useState(false);
57
 
52
 
58
-  useEffect(() => {
59
-    setDimensions({
60
-      width: excalidrawWrapperRef.current.getBoundingClientRect().width,
61
-      height: excalidrawWrapperRef.current.getBoundingClientRect().height,
62
-    });
63
-    const onResize = () => {
64
-      setDimensions({
65
-        width: excalidrawWrapperRef.current.getBoundingClientRect().width,
66
-        height: excalidrawWrapperRef.current.getBoundingClientRect().height,
67
-      });
68
-    };
69
-
70
-    window.addEventListener("resize", onResize);
71
-
72
-    return () => window.removeEventListener("resize", onResize);
73
-  }, [excalidrawWrapperRef]);
74
 
53
 
75
   const updateScene = () => {
54
   const updateScene = () => {
76
     const sceneData = {
55
     const sceneData = {
144
           Grid mode
123
           Grid mode
145
         </label>
124
         </label>
146
       </div>
125
       </div>
147
-      <div className="excalidraw-wrapper" ref={excalidrawWrapperRef}>
126
+      <div className="excalidraw-wrapper">
148
         <Excalidraw
127
         <Excalidraw
149
           ref={excalidrawRef}
128
           ref={excalidrawRef}
150
-          width={dimensions.width}
151
-          height={dimensions.height}
152
           initialData={InitialData}
129
           initialData={InitialData}
153
-          onChange={(elements, state) =>
130
+          onChange={(elements, state) => {
154
             console.log("Elements :", elements, "State : ", state)
131
             console.log("Elements :", elements, "State : ", state)
155
           }
132
           }
156
           onPointerUpdate={(payload) => console.log(payload)}
133
           onPointerUpdate={(payload) => console.log(payload)}
246
 
223
 
247
 const App = () => {
224
 const App = () => {
248
   const excalidrawRef = React.useRef(null);
225
   const excalidrawRef = React.useRef(null);
249
-  const excalidrawWrapperRef = React.useRef(null);
250
-  const [dimensions, setDimensions] = React.useState({
251
-    width: undefined,
252
-    height: undefined,
253
-  });
254
 
226
 
255
   const [viewModeEnabled, setViewModeEnabled] = React.useState(false);
227
   const [viewModeEnabled, setViewModeEnabled] = React.useState(false);
256
   const [zenModeEnabled, setZenModeEnabled] = React.useState(false);
228
   const [zenModeEnabled, setZenModeEnabled] = React.useState(false);
257
   const [gridModeEnabled, setGridModeEnabled] = React.useState(false);
229
   const [gridModeEnabled, setGridModeEnabled] = React.useState(false);
258
 
230
 
259
-  React.useEffect(() => {
260
-    setDimensions({
261
-      width: excalidrawWrapperRef.current.getBoundingClientRect().width,
262
-      height: excalidrawWrapperRef.current.getBoundingClientRect().height,
263
-    });
264
-    const onResize = () => {
265
-      setDimensions({
266
-        width: excalidrawWrapperRef.current.getBoundingClientRect().width,
267
-        height: excalidrawWrapperRef.current.getBoundingClientRect().height,
268
-      });
269
-    };
270
-
271
-    window.addEventListener("resize", onResize);
272
-
273
-    return () => window.removeEventListener("resize", onResize);
274
-  }, [excalidrawWrapperRef]);
275
-
276
   const updateScene = () => {
231
   const updateScene = () => {
277
     const sceneData = {
232
     const sceneData = {
278
       elements: [
233
       elements: [
365
         ref: excalidrawWrapperRef,
320
         ref: excalidrawWrapperRef,
366
       },
321
       },
367
       React.createElement(Excalidraw.default, {
322
       React.createElement(Excalidraw.default, {
368
-        ref: excalidrawRef,
369
-        width: dimensions.width,
370
-        height: dimensions.height,
371
         initialData: InitialData,
323
         initialData: InitialData,
372
         onChange: (elements, state) =>
324
         onChange: (elements, state) =>
373
           console.log("Elements :", elements, "State : ", state),
325
           console.log("Elements :", elements, "State : ", state),
396
 
348
 
397
 | Name | Type | Default | Description |
349
 | Name | Type | Default | Description |
398
 | --- | --- | --- | --- |
350
 | --- | --- | --- | --- |
399
-| [`width`](#width) | Number | `window.innerWidth` | The width of Excalidraw component |
400
-| [`height`](#height) | Number | `window.innerHeight` | The height of Excalidraw component |
401
 | [`onChange`](#onChange) | Function |  | This callback is triggered whenever the component updates due to any change. This callback will receive the excalidraw elements and the current app state. |
351
 | [`onChange`](#onChange) | Function |  | This callback is triggered whenever the component updates due to any change. This callback will receive the excalidraw elements and the current app state. |
402
 | [`initialData`](#initialData) | <pre>{elements?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>, appState?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L37">AppState<a> } </pre> | null | The initial data with which app loads. |
352
 | [`initialData`](#initialData) | <pre>{elements?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>, appState?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L37">AppState<a> } </pre> | null | The initial data with which app loads. |
403
 | [`ref`](#ref) | [`createRef`](https://reactjs.org/docs/refs-and-the-dom.html#creating-refs) or [`callbackRef`](https://reactjs.org/docs/refs-and-the-dom.html#callback-refs) or <pre>{ current: { readyPromise: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/utils.ts#L317">resolvablePromise</a> } }</pre> |  | Ref to be passed to Excalidraw |
353
 | [`ref`](#ref) | [`createRef`](https://reactjs.org/docs/refs-and-the-dom.html#creating-refs) or [`callbackRef`](https://reactjs.org/docs/refs-and-the-dom.html#callback-refs) or <pre>{ current: { readyPromise: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/utils.ts#L317">resolvablePromise</a> } }</pre> |  | Ref to be passed to Excalidraw |
415
 | [`theme`](#theme) | `light` or `dark` |  | The theme of the Excalidraw component |
365
 | [`theme`](#theme) | `light` or `dark` |  | The theme of the Excalidraw component |
416
 | [`name`](#name) | string |  | Name of the drawing |
366
 | [`name`](#name) | string |  | Name of the drawing |
417
 
367
 
418
-#### `width`
419
-
420
-This props defines the `width` of the Excalidraw component. Defaults to `window.innerWidth` if not passed.
421
-
422
-#### `height`
368
+### Dimensions of Excalidraw
423
 
369
 
424
-This props defines the `height` of the Excalidraw component. Defaults to `window.innerHeight` if not passed.
370
+Excalidraw takes `100%` of `width` and `height` of the containing block so you need to make sure the container in which you are rendering Excalidraw has non zero dimensions (It should have non zero width and height so Excalidraw can match the dimensions of the containing block). This is to make sure you don't have to worry about updating the offsets of dimensions when resizing Excalidraw.
425
 
371
 
426
 #### `onChange`
372
 #### `onChange`
427
 
373
 

+ 0
- 4
src/packages/excalidraw/index.tsx View File

13
 
13
 
14
 const Excalidraw = (props: ExcalidrawProps) => {
14
 const Excalidraw = (props: ExcalidrawProps) => {
15
   const {
15
   const {
16
-    width,
17
-    height,
18
     onChange,
16
     onChange,
19
     initialData,
17
     initialData,
20
     excalidrawRef,
18
     excalidrawRef,
55
     <InitializeApp langCode={langCode}>
53
     <InitializeApp langCode={langCode}>
56
       <IsMobileProvider>
54
       <IsMobileProvider>
57
         <App
55
         <App
58
-          width={width}
59
-          height={height}
60
           onChange={onChange}
56
           onChange={onChange}
61
           initialData={initialData}
57
           initialData={initialData}
62
           excalidrawRef={excalidrawRef}
58
           excalidrawRef={excalidrawRef}

+ 1
- 1
src/packages/utils.ts View File

33
   } = restoredAppState;
33
   } = restoredAppState;
34
   return _exportToCanvas(
34
   return _exportToCanvas(
35
     getNonDeletedElements(restoredElements),
35
     getNonDeletedElements(restoredElements),
36
-    { ...restoredAppState, offsetTop: 0, offsetLeft: 0 },
36
+    { ...restoredAppState, offsetTop: 0, offsetLeft: 0, width: 0, height: 0 },
37
     { exportBackground, viewBackgroundColor, shouldAddWatermark },
37
     { exportBackground, viewBackgroundColor, shouldAddWatermark },
38
     (width: number, height: number) => {
38
     (width: number, height: number) => {
39
       const canvas = document.createElement("canvas");
39
       const canvas = document.createElement("canvas");

+ 67
- 67
src/tests/__snapshots__/regressionTests.test.tsx.snap View File

459
 
459
 
460
 exports[`given element A and group of elements B and given both are selected when user clicks on B, on pointer up only elements from B should be selected: [end of test] number of elements 1`] = `3`;
460
 exports[`given element A and group of elements B and given both are selected when user clicks on B, on pointer up only elements from B should be selected: [end of test] number of elements 1`] = `3`;
461
 
461
 
462
-exports[`given element A and group of elements B and given both are selected when user clicks on B, on pointer up only elements from B should be selected: [end of test] number of renders 1`] = `26`;
462
+exports[`given element A and group of elements B and given both are selected when user clicks on B, on pointer up only elements from B should be selected: [end of test] number of renders 1`] = `27`;
463
 
463
 
464
 exports[`given element A and group of elements B and given both are selected when user shift-clicks on B, on pointer up only element A should be selected: [end of test] appState 1`] = `
464
 exports[`given element A and group of elements B and given both are selected when user shift-clicks on B, on pointer up only element A should be selected: [end of test] appState 1`] = `
465
 Object {
465
 Object {
926
 
926
 
927
 exports[`given element A and group of elements B and given both are selected when user shift-clicks on B, on pointer up only element A should be selected: [end of test] number of elements 1`] = `3`;
927
 exports[`given element A and group of elements B and given both are selected when user shift-clicks on B, on pointer up only element A should be selected: [end of test] number of elements 1`] = `3`;
928
 
928
 
929
-exports[`given element A and group of elements B and given both are selected when user shift-clicks on B, on pointer up only element A should be selected: [end of test] number of renders 1`] = `22`;
929
+exports[`given element A and group of elements B and given both are selected when user shift-clicks on B, on pointer up only element A should be selected: [end of test] number of renders 1`] = `23`;
930
 
930
 
931
 exports[`regression tests Cmd/Ctrl-click exclusively select element under pointer: [end of test] appState 1`] = `
931
 exports[`regression tests Cmd/Ctrl-click exclusively select element under pointer: [end of test] appState 1`] = `
932
 Object {
932
 Object {
1702
 
1702
 
1703
 exports[`regression tests Cmd/Ctrl-click exclusively select element under pointer: [end of test] number of elements 1`] = `3`;
1703
 exports[`regression tests Cmd/Ctrl-click exclusively select element under pointer: [end of test] number of elements 1`] = `3`;
1704
 
1704
 
1705
-exports[`regression tests Cmd/Ctrl-click exclusively select element under pointer: [end of test] number of renders 1`] = `41`;
1705
+exports[`regression tests Cmd/Ctrl-click exclusively select element under pointer: [end of test] number of renders 1`] = `42`;
1706
 
1706
 
1707
 exports[`regression tests Drags selected element when hitting only bounding box and keeps element selected: [end of test] appState 1`] = `
1707
 exports[`regression tests Drags selected element when hitting only bounding box and keeps element selected: [end of test] appState 1`] = `
1708
 Object {
1708
 Object {
1906
 
1906
 
1907
 exports[`regression tests Drags selected element when hitting only bounding box and keeps element selected: [end of test] number of elements 1`] = `1`;
1907
 exports[`regression tests Drags selected element when hitting only bounding box and keeps element selected: [end of test] number of elements 1`] = `1`;
1908
 
1908
 
1909
-exports[`regression tests Drags selected element when hitting only bounding box and keeps element selected: [end of test] number of renders 1`] = `10`;
1909
+exports[`regression tests Drags selected element when hitting only bounding box and keeps element selected: [end of test] number of renders 1`] = `11`;
1910
 
1910
 
1911
 exports[`regression tests adjusts z order when grouping: [end of test] appState 1`] = `
1911
 exports[`regression tests adjusts z order when grouping: [end of test] appState 1`] = `
1912
 Object {
1912
 Object {
2364
 
2364
 
2365
 exports[`regression tests adjusts z order when grouping: [end of test] number of elements 1`] = `3`;
2365
 exports[`regression tests adjusts z order when grouping: [end of test] number of elements 1`] = `3`;
2366
 
2366
 
2367
-exports[`regression tests adjusts z order when grouping: [end of test] number of renders 1`] = `20`;
2367
+exports[`regression tests adjusts z order when grouping: [end of test] number of renders 1`] = `21`;
2368
 
2368
 
2369
 exports[`regression tests alt-drag duplicates an element: [end of test] appState 1`] = `
2369
 exports[`regression tests alt-drag duplicates an element: [end of test] appState 1`] = `
2370
 Object {
2370
 Object {
2617
 
2617
 
2618
 exports[`regression tests alt-drag duplicates an element: [end of test] number of elements 1`] = `2`;
2618
 exports[`regression tests alt-drag duplicates an element: [end of test] number of elements 1`] = `2`;
2619
 
2619
 
2620
-exports[`regression tests alt-drag duplicates an element: [end of test] number of renders 1`] = `10`;
2620
+exports[`regression tests alt-drag duplicates an element: [end of test] number of renders 1`] = `11`;
2621
 
2621
 
2622
 exports[`regression tests arrow keys: [end of test] appState 1`] = `
2622
 exports[`regression tests arrow keys: [end of test] appState 1`] = `
2623
 Object {
2623
 Object {
2781
 
2781
 
2782
 exports[`regression tests arrow keys: [end of test] number of elements 1`] = `1`;
2782
 exports[`regression tests arrow keys: [end of test] number of elements 1`] = `1`;
2783
 
2783
 
2784
-exports[`regression tests arrow keys: [end of test] number of renders 1`] = `19`;
2784
+exports[`regression tests arrow keys: [end of test] number of renders 1`] = `20`;
2785
 
2785
 
2786
 exports[`regression tests can drag element that covers another element, while another elem is selected: [end of test] appState 1`] = `
2786
 exports[`regression tests can drag element that covers another element, while another elem is selected: [end of test] appState 1`] = `
2787
 Object {
2787
 Object {
3258
 
3258
 
3259
 exports[`regression tests can drag element that covers another element, while another elem is selected: [end of test] number of elements 1`] = `3`;
3259
 exports[`regression tests can drag element that covers another element, while another elem is selected: [end of test] number of elements 1`] = `3`;
3260
 
3260
 
3261
-exports[`regression tests can drag element that covers another element, while another elem is selected: [end of test] number of renders 1`] = `18`;
3261
+exports[`regression tests can drag element that covers another element, while another elem is selected: [end of test] number of renders 1`] = `19`;
3262
 
3262
 
3263
 exports[`regression tests change the properties of a shape: [end of test] appState 1`] = `
3263
 exports[`regression tests change the properties of a shape: [end of test] appState 1`] = `
3264
 Object {
3264
 Object {
3494
 
3494
 
3495
 exports[`regression tests change the properties of a shape: [end of test] number of elements 1`] = `1`;
3495
 exports[`regression tests change the properties of a shape: [end of test] number of elements 1`] = `1`;
3496
 
3496
 
3497
-exports[`regression tests change the properties of a shape: [end of test] number of renders 1`] = `11`;
3497
+exports[`regression tests change the properties of a shape: [end of test] number of renders 1`] = `12`;
3498
 
3498
 
3499
 exports[`regression tests click on an element and drag it: [dragged] appState 1`] = `
3499
 exports[`regression tests click on an element and drag it: [dragged] appState 1`] = `
3500
 Object {
3500
 Object {
3698
 
3698
 
3699
 exports[`regression tests click on an element and drag it: [dragged] number of elements 1`] = `1`;
3699
 exports[`regression tests click on an element and drag it: [dragged] number of elements 1`] = `1`;
3700
 
3700
 
3701
-exports[`regression tests click on an element and drag it: [dragged] number of renders 1`] = `10`;
3701
+exports[`regression tests click on an element and drag it: [dragged] number of renders 1`] = `11`;
3702
 
3702
 
3703
 exports[`regression tests click on an element and drag it: [end of test] appState 1`] = `
3703
 exports[`regression tests click on an element and drag it: [end of test] appState 1`] = `
3704
 Object {
3704
 Object {
3942
 
3942
 
3943
 exports[`regression tests click on an element and drag it: [end of test] number of elements 1`] = `1`;
3943
 exports[`regression tests click on an element and drag it: [end of test] number of elements 1`] = `1`;
3944
 
3944
 
3945
-exports[`regression tests click on an element and drag it: [end of test] number of renders 1`] = `13`;
3945
+exports[`regression tests click on an element and drag it: [end of test] number of renders 1`] = `14`;
3946
 
3946
 
3947
 exports[`regression tests click to select a shape: [end of test] appState 1`] = `
3947
 exports[`regression tests click to select a shape: [end of test] appState 1`] = `
3948
 Object {
3948
 Object {
4194
 
4194
 
4195
 exports[`regression tests click to select a shape: [end of test] number of elements 1`] = `2`;
4195
 exports[`regression tests click to select a shape: [end of test] number of elements 1`] = `2`;
4196
 
4196
 
4197
-exports[`regression tests click to select a shape: [end of test] number of renders 1`] = `13`;
4197
+exports[`regression tests click to select a shape: [end of test] number of renders 1`] = `14`;
4198
 
4198
 
4199
 exports[`regression tests click-drag to select a group: [end of test] appState 1`] = `
4199
 exports[`regression tests click-drag to select a group: [end of test] appState 1`] = `
4200
 Object {
4200
 Object {
4555
 
4555
 
4556
 exports[`regression tests click-drag to select a group: [end of test] number of elements 1`] = `3`;
4556
 exports[`regression tests click-drag to select a group: [end of test] number of elements 1`] = `3`;
4557
 
4557
 
4558
-exports[`regression tests click-drag to select a group: [end of test] number of renders 1`] = `19`;
4558
+exports[`regression tests click-drag to select a group: [end of test] number of renders 1`] = `20`;
4559
 
4559
 
4560
 exports[`regression tests deselects group of selected elements on pointer down when pointer doesn't hit any element: [end of test] appState 1`] = `
4560
 exports[`regression tests deselects group of selected elements on pointer down when pointer doesn't hit any element: [end of test] appState 1`] = `
4561
 Object {
4561
 Object {
4850
 
4850
 
4851
 exports[`regression tests deselects group of selected elements on pointer down when pointer doesn't hit any element: [end of test] number of elements 1`] = `2`;
4851
 exports[`regression tests deselects group of selected elements on pointer down when pointer doesn't hit any element: [end of test] number of elements 1`] = `2`;
4852
 
4852
 
4853
-exports[`regression tests deselects group of selected elements on pointer down when pointer doesn't hit any element: [end of test] number of renders 1`] = `14`;
4853
+exports[`regression tests deselects group of selected elements on pointer down when pointer doesn't hit any element: [end of test] number of renders 1`] = `15`;
4854
 
4854
 
4855
 exports[`regression tests deselects group of selected elements on pointer up when pointer hits common bounding box without hitting any element: [end of test] appState 1`] = `
4855
 exports[`regression tests deselects group of selected elements on pointer up when pointer hits common bounding box without hitting any element: [end of test] appState 1`] = `
4856
 Object {
4856
 Object {
5157
 
5157
 
5158
 exports[`regression tests deselects group of selected elements on pointer up when pointer hits common bounding box without hitting any element: [end of test] number of elements 1`] = `2`;
5158
 exports[`regression tests deselects group of selected elements on pointer up when pointer hits common bounding box without hitting any element: [end of test] number of elements 1`] = `2`;
5159
 
5159
 
5160
-exports[`regression tests deselects group of selected elements on pointer up when pointer hits common bounding box without hitting any element: [end of test] number of renders 1`] = `15`;
5160
+exports[`regression tests deselects group of selected elements on pointer up when pointer hits common bounding box without hitting any element: [end of test] number of renders 1`] = `16`;
5161
 
5161
 
5162
 exports[`regression tests deselects selected element on pointer down when pointer doesn't hit any element: [end of test] appState 1`] = `
5162
 exports[`regression tests deselects selected element on pointer down when pointer doesn't hit any element: [end of test] appState 1`] = `
5163
 Object {
5163
 Object {
5365
 
5365
 
5366
 exports[`regression tests deselects selected element on pointer down when pointer doesn't hit any element: [end of test] number of elements 1`] = `1`;
5366
 exports[`regression tests deselects selected element on pointer down when pointer doesn't hit any element: [end of test] number of elements 1`] = `1`;
5367
 
5367
 
5368
-exports[`regression tests deselects selected element on pointer down when pointer doesn't hit any element: [end of test] number of renders 1`] = `8`;
5368
+exports[`regression tests deselects selected element on pointer down when pointer doesn't hit any element: [end of test] number of renders 1`] = `9`;
5369
 
5369
 
5370
 exports[`regression tests deselects selected element, on pointer up, when click hits element bounding box but doesn't hit the element: [end of test] appState 1`] = `
5370
 exports[`regression tests deselects selected element, on pointer up, when click hits element bounding box but doesn't hit the element: [end of test] appState 1`] = `
5371
 Object {
5371
 Object {
5551
 
5551
 
5552
 exports[`regression tests deselects selected element, on pointer up, when click hits element bounding box but doesn't hit the element: [end of test] number of elements 1`] = `1`;
5552
 exports[`regression tests deselects selected element, on pointer up, when click hits element bounding box but doesn't hit the element: [end of test] number of elements 1`] = `1`;
5553
 
5553
 
5554
-exports[`regression tests deselects selected element, on pointer up, when click hits element bounding box but doesn't hit the element: [end of test] number of renders 1`] = `9`;
5554
+exports[`regression tests deselects selected element, on pointer up, when click hits element bounding box but doesn't hit the element: [end of test] number of renders 1`] = `10`;
5555
 
5555
 
5556
 exports[`regression tests double click to edit a group: [end of test] appState 1`] = `
5556
 exports[`regression tests double click to edit a group: [end of test] appState 1`] = `
5557
 Object {
5557
 Object {
6004
 
6004
 
6005
 exports[`regression tests double click to edit a group: [end of test] number of elements 1`] = `3`;
6005
 exports[`regression tests double click to edit a group: [end of test] number of elements 1`] = `3`;
6006
 
6006
 
6007
-exports[`regression tests double click to edit a group: [end of test] number of renders 1`] = `18`;
6007
+exports[`regression tests double click to edit a group: [end of test] number of renders 1`] = `19`;
6008
 
6008
 
6009
 exports[`regression tests drags selected elements from point inside common bounding box that doesn't hit any element and keeps elements selected after dragging: [end of test] appState 1`] = `
6009
 exports[`regression tests drags selected elements from point inside common bounding box that doesn't hit any element and keeps elements selected after dragging: [end of test] appState 1`] = `
6010
 Object {
6010
 Object {
6322
 
6322
 
6323
 exports[`regression tests drags selected elements from point inside common bounding box that doesn't hit any element and keeps elements selected after dragging: [end of test] number of elements 1`] = `2`;
6323
 exports[`regression tests drags selected elements from point inside common bounding box that doesn't hit any element and keeps elements selected after dragging: [end of test] number of elements 1`] = `2`;
6324
 
6324
 
6325
-exports[`regression tests drags selected elements from point inside common bounding box that doesn't hit any element and keeps elements selected after dragging: [end of test] number of renders 1`] = `16`;
6325
+exports[`regression tests drags selected elements from point inside common bounding box that doesn't hit any element and keeps elements selected after dragging: [end of test] number of renders 1`] = `17`;
6326
 
6326
 
6327
 exports[`regression tests draw every type of shape: [end of test] appState 1`] = `
6327
 exports[`regression tests draw every type of shape: [end of test] appState 1`] = `
6328
 Object {
6328
 Object {
8356
 
8356
 
8357
 exports[`regression tests draw every type of shape: [end of test] number of elements 1`] = `8`;
8357
 exports[`regression tests draw every type of shape: [end of test] number of elements 1`] = `8`;
8358
 
8358
 
8359
-exports[`regression tests draw every type of shape: [end of test] number of renders 1`] = `51`;
8359
+exports[`regression tests draw every type of shape: [end of test] number of renders 1`] = `52`;
8360
 
8360
 
8361
 exports[`regression tests given a group of selected elements with an element that is not selected inside the group common bounding box when element that is not selected is clicked should switch selection to not selected element on pointer up: [end of test] appState 1`] = `
8361
 exports[`regression tests given a group of selected elements with an element that is not selected inside the group common bounding box when element that is not selected is clicked should switch selection to not selected element on pointer up: [end of test] appState 1`] = `
8362
 Object {
8362
 Object {
8718
 
8718
 
8719
 exports[`regression tests given a group of selected elements with an element that is not selected inside the group common bounding box when element that is not selected is clicked should switch selection to not selected element on pointer up: [end of test] number of elements 1`] = `3`;
8719
 exports[`regression tests given a group of selected elements with an element that is not selected inside the group common bounding box when element that is not selected is clicked should switch selection to not selected element on pointer up: [end of test] number of elements 1`] = `3`;
8720
 
8720
 
8721
-exports[`regression tests given a group of selected elements with an element that is not selected inside the group common bounding box when element that is not selected is clicked should switch selection to not selected element on pointer up: [end of test] number of renders 1`] = `19`;
8721
+exports[`regression tests given a group of selected elements with an element that is not selected inside the group common bounding box when element that is not selected is clicked should switch selection to not selected element on pointer up: [end of test] number of renders 1`] = `20`;
8722
 
8722
 
8723
 exports[`regression tests given a selected element A and a not selected element B with higher z-index than A and given B partialy overlaps A when there's a shift-click on the overlapped section B is added to the selection: [end of test] appState 1`] = `
8723
 exports[`regression tests given a selected element A and a not selected element B with higher z-index than A and given B partialy overlaps A when there's a shift-click on the overlapped section B is added to the selection: [end of test] appState 1`] = `
8724
 Object {
8724
 Object {
8973
 
8973
 
8974
 exports[`regression tests given a selected element A and a not selected element B with higher z-index than A and given B partialy overlaps A when there's a shift-click on the overlapped section B is added to the selection: [end of test] number of elements 1`] = `2`;
8974
 exports[`regression tests given a selected element A and a not selected element B with higher z-index than A and given B partialy overlaps A when there's a shift-click on the overlapped section B is added to the selection: [end of test] number of elements 1`] = `2`;
8975
 
8975
 
8976
-exports[`regression tests given a selected element A and a not selected element B with higher z-index than A and given B partialy overlaps A when there's a shift-click on the overlapped section B is added to the selection: [end of test] number of renders 1`] = `17`;
8976
+exports[`regression tests given a selected element A and a not selected element B with higher z-index than A and given B partialy overlaps A when there's a shift-click on the overlapped section B is added to the selection: [end of test] number of renders 1`] = `18`;
8977
 
8977
 
8978
 exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when clicking intersection between A and B B should be selected on pointer up: [end of test] appState 1`] = `
8978
 exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when clicking intersection between A and B B should be selected on pointer up: [end of test] appState 1`] = `
8979
 Object {
8979
 Object {
9226
 
9226
 
9227
 exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when clicking intersection between A and B B should be selected on pointer up: [end of test] number of elements 1`] = `2`;
9227
 exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when clicking intersection between A and B B should be selected on pointer up: [end of test] number of elements 1`] = `2`;
9228
 
9228
 
9229
-exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when clicking intersection between A and B B should be selected on pointer up: [end of test] number of renders 1`] = `17`;
9229
+exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when clicking intersection between A and B B should be selected on pointer up: [end of test] number of renders 1`] = `18`;
9230
 
9230
 
9231
 exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when dragging on intersection between A and B A should be dragged and keep being selected: [end of test] appState 1`] = `
9231
 exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when dragging on intersection between A and B A should be dragged and keep being selected: [end of test] appState 1`] = `
9232
 Object {
9232
 Object {
9541
 
9541
 
9542
 exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when dragging on intersection between A and B A should be dragged and keep being selected: [end of test] number of elements 1`] = `2`;
9542
 exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when dragging on intersection between A and B A should be dragged and keep being selected: [end of test] number of elements 1`] = `2`;
9543
 
9543
 
9544
-exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when dragging on intersection between A and B A should be dragged and keep being selected: [end of test] number of renders 1`] = `18`;
9544
+exports[`regression tests given selected element A with lower z-index than unselected element B and given B is partially over A when dragging on intersection between A and B A should be dragged and keep being selected: [end of test] number of renders 1`] = `19`;
9545
 
9545
 
9546
 exports[`regression tests key 2 selects rectangle tool: [end of test] appState 1`] = `
9546
 exports[`regression tests key 2 selects rectangle tool: [end of test] appState 1`] = `
9547
 Object {
9547
 Object {
9705
 
9705
 
9706
 exports[`regression tests key 2 selects rectangle tool: [end of test] number of elements 1`] = `1`;
9706
 exports[`regression tests key 2 selects rectangle tool: [end of test] number of elements 1`] = `1`;
9707
 
9707
 
9708
-exports[`regression tests key 2 selects rectangle tool: [end of test] number of renders 1`] = `7`;
9708
+exports[`regression tests key 2 selects rectangle tool: [end of test] number of renders 1`] = `8`;
9709
 
9709
 
9710
 exports[`regression tests key 3 selects diamond tool: [end of test] appState 1`] = `
9710
 exports[`regression tests key 3 selects diamond tool: [end of test] appState 1`] = `
9711
 Object {
9711
 Object {
9869
 
9869
 
9870
 exports[`regression tests key 3 selects diamond tool: [end of test] number of elements 1`] = `1`;
9870
 exports[`regression tests key 3 selects diamond tool: [end of test] number of elements 1`] = `1`;
9871
 
9871
 
9872
-exports[`regression tests key 3 selects diamond tool: [end of test] number of renders 1`] = `7`;
9872
+exports[`regression tests key 3 selects diamond tool: [end of test] number of renders 1`] = `8`;
9873
 
9873
 
9874
 exports[`regression tests key 4 selects ellipse tool: [end of test] appState 1`] = `
9874
 exports[`regression tests key 4 selects ellipse tool: [end of test] appState 1`] = `
9875
 Object {
9875
 Object {
10033
 
10033
 
10034
 exports[`regression tests key 4 selects ellipse tool: [end of test] number of elements 1`] = `1`;
10034
 exports[`regression tests key 4 selects ellipse tool: [end of test] number of elements 1`] = `1`;
10035
 
10035
 
10036
-exports[`regression tests key 4 selects ellipse tool: [end of test] number of renders 1`] = `7`;
10036
+exports[`regression tests key 4 selects ellipse tool: [end of test] number of renders 1`] = `8`;
10037
 
10037
 
10038
 exports[`regression tests key 5 selects arrow tool: [end of test] appState 1`] = `
10038
 exports[`regression tests key 5 selects arrow tool: [end of test] appState 1`] = `
10039
 Object {
10039
 Object {
10227
 
10227
 
10228
 exports[`regression tests key 5 selects arrow tool: [end of test] number of elements 1`] = `1`;
10228
 exports[`regression tests key 5 selects arrow tool: [end of test] number of elements 1`] = `1`;
10229
 
10229
 
10230
-exports[`regression tests key 5 selects arrow tool: [end of test] number of renders 1`] = `8`;
10230
+exports[`regression tests key 5 selects arrow tool: [end of test] number of renders 1`] = `9`;
10231
 
10231
 
10232
 exports[`regression tests key 6 selects line tool: [end of test] appState 1`] = `
10232
 exports[`regression tests key 6 selects line tool: [end of test] appState 1`] = `
10233
 Object {
10233
 Object {
10421
 
10421
 
10422
 exports[`regression tests key 6 selects line tool: [end of test] number of elements 1`] = `1`;
10422
 exports[`regression tests key 6 selects line tool: [end of test] number of elements 1`] = `1`;
10423
 
10423
 
10424
-exports[`regression tests key 6 selects line tool: [end of test] number of renders 1`] = `7`;
10424
+exports[`regression tests key 6 selects line tool: [end of test] number of renders 1`] = `8`;
10425
 
10425
 
10426
 exports[`regression tests key 7 selects draw tool: [end of test] appState 1`] = `
10426
 exports[`regression tests key 7 selects draw tool: [end of test] appState 1`] = `
10427
 Object {
10427
 Object {
10615
 
10615
 
10616
 exports[`regression tests key 7 selects draw tool: [end of test] number of elements 1`] = `1`;
10616
 exports[`regression tests key 7 selects draw tool: [end of test] number of elements 1`] = `1`;
10617
 
10617
 
10618
-exports[`regression tests key 7 selects draw tool: [end of test] number of renders 1`] = `7`;
10618
+exports[`regression tests key 7 selects draw tool: [end of test] number of renders 1`] = `8`;
10619
 
10619
 
10620
 exports[`regression tests key a selects arrow tool: [end of test] appState 1`] = `
10620
 exports[`regression tests key a selects arrow tool: [end of test] appState 1`] = `
10621
 Object {
10621
 Object {
10809
 
10809
 
10810
 exports[`regression tests key a selects arrow tool: [end of test] number of elements 1`] = `1`;
10810
 exports[`regression tests key a selects arrow tool: [end of test] number of elements 1`] = `1`;
10811
 
10811
 
10812
-exports[`regression tests key a selects arrow tool: [end of test] number of renders 1`] = `8`;
10812
+exports[`regression tests key a selects arrow tool: [end of test] number of renders 1`] = `9`;
10813
 
10813
 
10814
 exports[`regression tests key d selects diamond tool: [end of test] appState 1`] = `
10814
 exports[`regression tests key d selects diamond tool: [end of test] appState 1`] = `
10815
 Object {
10815
 Object {
10973
 
10973
 
10974
 exports[`regression tests key d selects diamond tool: [end of test] number of elements 1`] = `1`;
10974
 exports[`regression tests key d selects diamond tool: [end of test] number of elements 1`] = `1`;
10975
 
10975
 
10976
-exports[`regression tests key d selects diamond tool: [end of test] number of renders 1`] = `7`;
10976
+exports[`regression tests key d selects diamond tool: [end of test] number of renders 1`] = `8`;
10977
 
10977
 
10978
 exports[`regression tests key e selects ellipse tool: [end of test] appState 1`] = `
10978
 exports[`regression tests key e selects ellipse tool: [end of test] appState 1`] = `
10979
 Object {
10979
 Object {
11137
 
11137
 
11138
 exports[`regression tests key e selects ellipse tool: [end of test] number of elements 1`] = `1`;
11138
 exports[`regression tests key e selects ellipse tool: [end of test] number of elements 1`] = `1`;
11139
 
11139
 
11140
-exports[`regression tests key e selects ellipse tool: [end of test] number of renders 1`] = `7`;
11140
+exports[`regression tests key e selects ellipse tool: [end of test] number of renders 1`] = `8`;
11141
 
11141
 
11142
 exports[`regression tests key l selects line tool: [end of test] appState 1`] = `
11142
 exports[`regression tests key l selects line tool: [end of test] appState 1`] = `
11143
 Object {
11143
 Object {
11331
 
11331
 
11332
 exports[`regression tests key l selects line tool: [end of test] number of elements 1`] = `1`;
11332
 exports[`regression tests key l selects line tool: [end of test] number of elements 1`] = `1`;
11333
 
11333
 
11334
-exports[`regression tests key l selects line tool: [end of test] number of renders 1`] = `7`;
11334
+exports[`regression tests key l selects line tool: [end of test] number of renders 1`] = `8`;
11335
 
11335
 
11336
 exports[`regression tests key r selects rectangle tool: [end of test] appState 1`] = `
11336
 exports[`regression tests key r selects rectangle tool: [end of test] appState 1`] = `
11337
 Object {
11337
 Object {
11495
 
11495
 
11496
 exports[`regression tests key r selects rectangle tool: [end of test] number of elements 1`] = `1`;
11496
 exports[`regression tests key r selects rectangle tool: [end of test] number of elements 1`] = `1`;
11497
 
11497
 
11498
-exports[`regression tests key r selects rectangle tool: [end of test] number of renders 1`] = `7`;
11498
+exports[`regression tests key r selects rectangle tool: [end of test] number of renders 1`] = `8`;
11499
 
11499
 
11500
 exports[`regression tests key x selects draw tool: [end of test] appState 1`] = `
11500
 exports[`regression tests key x selects draw tool: [end of test] appState 1`] = `
11501
 Object {
11501
 Object {
11689
 
11689
 
11690
 exports[`regression tests key x selects draw tool: [end of test] number of elements 1`] = `1`;
11690
 exports[`regression tests key x selects draw tool: [end of test] number of elements 1`] = `1`;
11691
 
11691
 
11692
-exports[`regression tests key x selects draw tool: [end of test] number of renders 1`] = `7`;
11692
+exports[`regression tests key x selects draw tool: [end of test] number of renders 1`] = `8`;
11693
 
11693
 
11694
 exports[`regression tests make a group and duplicate it: [end of test] appState 1`] = `
11694
 exports[`regression tests make a group and duplicate it: [end of test] appState 1`] = `
11695
 Object {
11695
 Object {
12405
 
12405
 
12406
 exports[`regression tests make a group and duplicate it: [end of test] number of elements 1`] = `6`;
12406
 exports[`regression tests make a group and duplicate it: [end of test] number of elements 1`] = `6`;
12407
 
12407
 
12408
-exports[`regression tests make a group and duplicate it: [end of test] number of renders 1`] = `22`;
12408
+exports[`regression tests make a group and duplicate it: [end of test] number of renders 1`] = `23`;
12409
 
12409
 
12410
 exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] appState 1`] = `
12410
 exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] appState 1`] = `
12411
 Object {
12411
 Object {
12658
 
12658
 
12659
 exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] number of elements 1`] = `2`;
12659
 exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] number of elements 1`] = `2`;
12660
 
12660
 
12661
-exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] number of renders 1`] = `19`;
12661
+exports[`regression tests noop interaction after undo shouldn't create history entry: [end of test] number of renders 1`] = `20`;
12662
 
12662
 
12663
 exports[`regression tests pinch-to-zoom works: [end of test] appState 1`] = `
12663
 exports[`regression tests pinch-to-zoom works: [end of test] appState 1`] = `
12664
 Object {
12664
 Object {
12760
 
12760
 
12761
 exports[`regression tests pinch-to-zoom works: [end of test] number of elements 1`] = `0`;
12761
 exports[`regression tests pinch-to-zoom works: [end of test] number of elements 1`] = `0`;
12762
 
12762
 
12763
-exports[`regression tests pinch-to-zoom works: [end of test] number of renders 1`] = `9`;
12763
+exports[`regression tests pinch-to-zoom works: [end of test] number of renders 1`] = `10`;
12764
 
12764
 
12765
 exports[`regression tests rerenders UI on language change: [end of test] appState 1`] = `
12765
 exports[`regression tests rerenders UI on language change: [end of test] appState 1`] = `
12766
 Object {
12766
 Object {
12860
 
12860
 
12861
 exports[`regression tests rerenders UI on language change: [end of test] number of elements 1`] = `0`;
12861
 exports[`regression tests rerenders UI on language change: [end of test] number of elements 1`] = `0`;
12862
 
12862
 
12863
-exports[`regression tests rerenders UI on language change: [end of test] number of renders 1`] = `8`;
12863
+exports[`regression tests rerenders UI on language change: [end of test] number of renders 1`] = `9`;
12864
 
12864
 
12865
 exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] appState 1`] = `
12865
 exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] appState 1`] = `
12866
 Object {
12866
 Object {
13024
 
13024
 
13025
 exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] number of elements 1`] = `1`;
13025
 exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] number of elements 1`] = `1`;
13026
 
13026
 
13027
-exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] number of renders 1`] = `7`;
13027
+exports[`regression tests selecting 'Add to library' in context menu adds element to library: [end of test] number of renders 1`] = `8`;
13028
 
13028
 
13029
 exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] appState 1`] = `
13029
 exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] appState 1`] = `
13030
 Object {
13030
 Object {
13332
 
13332
 
13333
 exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] number of elements 1`] = `2`;
13333
 exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] number of elements 1`] = `2`;
13334
 
13334
 
13335
-exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] number of renders 1`] = `13`;
13335
+exports[`regression tests selecting 'Bring forward' in context menu brings element forward: [end of test] number of renders 1`] = `14`;
13336
 
13336
 
13337
 exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] appState 1`] = `
13337
 exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] appState 1`] = `
13338
 Object {
13338
 Object {
13640
 
13640
 
13641
 exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] number of elements 1`] = `2`;
13641
 exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] number of elements 1`] = `2`;
13642
 
13642
 
13643
-exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] number of renders 1`] = `13`;
13643
+exports[`regression tests selecting 'Bring to front' in context menu brings element to front: [end of test] number of renders 1`] = `14`;
13644
 
13644
 
13645
 exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] appState 1`] = `
13645
 exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] appState 1`] = `
13646
 Object {
13646
 Object {
13804
 
13804
 
13805
 exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] number of elements 1`] = `1`;
13805
 exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] number of elements 1`] = `1`;
13806
 
13806
 
13807
-exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] number of renders 1`] = `8`;
13807
+exports[`regression tests selecting 'Copy styles' in context menu copies styles: [end of test] number of renders 1`] = `9`;
13808
 
13808
 
13809
 exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] appState 1`] = `
13809
 exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] appState 1`] = `
13810
 Object {
13810
 Object {
14000
 
14000
 
14001
 exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] number of elements 1`] = `1`;
14001
 exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] number of elements 1`] = `1`;
14002
 
14002
 
14003
-exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] number of renders 1`] = `8`;
14003
+exports[`regression tests selecting 'Delete' in context menu deletes element: [end of test] number of renders 1`] = `9`;
14004
 
14004
 
14005
 exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] appState 1`] = `
14005
 exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] appState 1`] = `
14006
 Object {
14006
 Object {
14249
 
14249
 
14250
 exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] number of elements 1`] = `2`;
14250
 exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] number of elements 1`] = `2`;
14251
 
14251
 
14252
-exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] number of renders 1`] = `8`;
14252
+exports[`regression tests selecting 'Duplicate' in context menu duplicates element: [end of test] number of renders 1`] = `9`;
14253
 
14253
 
14254
 exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] appState 1`] = `
14254
 exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] appState 1`] = `
14255
 Object {
14255
 Object {
14573
 
14573
 
14574
 exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] number of elements 1`] = `2`;
14574
 exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] number of elements 1`] = `2`;
14575
 
14575
 
14576
-exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] number of renders 1`] = `14`;
14576
+exports[`regression tests selecting 'Group selection' in context menu groups selected elements: [end of test] number of renders 1`] = `15`;
14577
 
14577
 
14578
 exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] appState 1`] = `
14578
 exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] appState 1`] = `
14579
 Object {
14579
 Object {
15294
 
15294
 
15295
 exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] number of elements 1`] = `2`;
15295
 exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] number of elements 1`] = `2`;
15296
 
15296
 
15297
-exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] number of renders 1`] = `23`;
15297
+exports[`regression tests selecting 'Paste styles' in context menu pastes styles: [end of test] number of renders 1`] = `24`;
15298
 
15298
 
15299
 exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] appState 1`] = `
15299
 exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] appState 1`] = `
15300
 Object {
15300
 Object {
15602
 
15602
 
15603
 exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] number of elements 1`] = `2`;
15603
 exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] number of elements 1`] = `2`;
15604
 
15604
 
15605
-exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] number of renders 1`] = `12`;
15605
+exports[`regression tests selecting 'Send backward' in context menu sends element backward: [end of test] number of renders 1`] = `13`;
15606
 
15606
 
15607
 exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] appState 1`] = `
15607
 exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] appState 1`] = `
15608
 Object {
15608
 Object {
15910
 
15910
 
15911
 exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] number of elements 1`] = `2`;
15911
 exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] number of elements 1`] = `2`;
15912
 
15912
 
15913
-exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] number of renders 1`] = `12`;
15913
+exports[`regression tests selecting 'Send to back' in context menu sends element to back: [end of test] number of renders 1`] = `13`;
15914
 
15914
 
15915
 exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] appState 1`] = `
15915
 exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] appState 1`] = `
15916
 Object {
15916
 Object {
16289
 
16289
 
16290
 exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] number of elements 1`] = `2`;
16290
 exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] number of elements 1`] = `2`;
16291
 
16291
 
16292
-exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] number of renders 1`] = `15`;
16292
+exports[`regression tests selecting 'Ungroup selection' in context menu ungroups selected group: [end of test] number of renders 1`] = `16`;
16293
 
16293
 
16294
 exports[`regression tests shift click on selected element should deselect it on pointer up: [end of test] appState 1`] = `
16294
 exports[`regression tests shift click on selected element should deselect it on pointer up: [end of test] appState 1`] = `
16295
 Object {
16295
 Object {
16456
 
16456
 
16457
 exports[`regression tests shift click on selected element should deselect it on pointer up: [end of test] number of elements 1`] = `1`;
16457
 exports[`regression tests shift click on selected element should deselect it on pointer up: [end of test] number of elements 1`] = `1`;
16458
 
16458
 
16459
-exports[`regression tests shift click on selected element should deselect it on pointer up: [end of test] number of renders 1`] = `9`;
16459
+exports[`regression tests shift click on selected element should deselect it on pointer up: [end of test] number of renders 1`] = `10`;
16460
 
16460
 
16461
 exports[`regression tests shift-click to multiselect, then drag: [end of test] appState 1`] = `
16461
 exports[`regression tests shift-click to multiselect, then drag: [end of test] appState 1`] = `
16462
 Object {
16462
 Object {
16777
 
16777
 
16778
 exports[`regression tests shift-click to multiselect, then drag: [end of test] number of elements 1`] = `2`;
16778
 exports[`regression tests shift-click to multiselect, then drag: [end of test] number of elements 1`] = `2`;
16779
 
16779
 
16780
-exports[`regression tests shift-click to multiselect, then drag: [end of test] number of renders 1`] = `18`;
16780
+exports[`regression tests shift-click to multiselect, then drag: [end of test] number of renders 1`] = `19`;
16781
 
16781
 
16782
 exports[`regression tests should show fill icons when element has non transparent background: [end of test] appState 1`] = `
16782
 exports[`regression tests should show fill icons when element has non transparent background: [end of test] appState 1`] = `
16783
 Object {
16783
 Object {
16980
 
16980
 
16981
 exports[`regression tests should show fill icons when element has non transparent background: [end of test] number of elements 1`] = `1`;
16981
 exports[`regression tests should show fill icons when element has non transparent background: [end of test] number of elements 1`] = `1`;
16982
 
16982
 
16983
-exports[`regression tests should show fill icons when element has non transparent background: [end of test] number of renders 1`] = `11`;
16983
+exports[`regression tests should show fill icons when element has non transparent background: [end of test] number of renders 1`] = `12`;
16984
 
16984
 
16985
 exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] appState 1`] = `
16985
 exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] appState 1`] = `
16986
 Object {
16986
 Object {
17235
 
17235
 
17236
 exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] number of elements 1`] = `2`;
17236
 exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] number of elements 1`] = `2`;
17237
 
17237
 
17238
-exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] number of renders 1`] = `15`;
17238
+exports[`regression tests shows 'Group selection' in context menu for multiple selected elements: [end of test] number of renders 1`] = `16`;
17239
 
17239
 
17240
 exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] appState 1`] = `
17240
 exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] appState 1`] = `
17241
 Object {
17241
 Object {
17562
 
17562
 
17563
 exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] number of elements 1`] = `2`;
17563
 exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] number of elements 1`] = `2`;
17564
 
17564
 
17565
-exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] number of renders 1`] = `16`;
17565
+exports[`regression tests shows 'Ungroup selection' in context menu for group inside selected elements: [end of test] number of renders 1`] = `17`;
17566
 
17566
 
17567
 exports[`regression tests shows context menu for canvas: [end of test] appState 1`] = `
17567
 exports[`regression tests shows context menu for canvas: [end of test] appState 1`] = `
17568
 Object {
17568
 Object {
17662
 
17662
 
17663
 exports[`regression tests shows context menu for canvas: [end of test] number of elements 1`] = `0`;
17663
 exports[`regression tests shows context menu for canvas: [end of test] number of elements 1`] = `0`;
17664
 
17664
 
17665
-exports[`regression tests shows context menu for canvas: [end of test] number of renders 1`] = `3`;
17665
+exports[`regression tests shows context menu for canvas: [end of test] number of renders 1`] = `4`;
17666
 
17666
 
17667
 exports[`regression tests shows context menu for element: [end of test] appState 1`] = `
17667
 exports[`regression tests shows context menu for element: [end of test] appState 1`] = `
17668
 Object {
17668
 Object {
17826
 
17826
 
17827
 exports[`regression tests shows context menu for element: [end of test] number of elements 1`] = `1`;
17827
 exports[`regression tests shows context menu for element: [end of test] number of elements 1`] = `1`;
17828
 
17828
 
17829
-exports[`regression tests shows context menu for element: [end of test] number of renders 1`] = `7`;
17829
+exports[`regression tests shows context menu for element: [end of test] number of renders 1`] = `8`;
17830
 
17830
 
17831
 exports[`regression tests single-clicking on a subgroup of a selected group should not alter selection: [end of test] appState 1`] = `
17831
 exports[`regression tests single-clicking on a subgroup of a selected group should not alter selection: [end of test] appState 1`] = `
17832
 Object {
17832
 Object {
18647
 
18647
 
18648
 exports[`regression tests single-clicking on a subgroup of a selected group should not alter selection: [end of test] number of elements 1`] = `4`;
18648
 exports[`regression tests single-clicking on a subgroup of a selected group should not alter selection: [end of test] number of elements 1`] = `4`;
18649
 
18649
 
18650
-exports[`regression tests single-clicking on a subgroup of a selected group should not alter selection: [end of test] number of renders 1`] = `37`;
18650
+exports[`regression tests single-clicking on a subgroup of a selected group should not alter selection: [end of test] number of renders 1`] = `38`;
18651
 
18651
 
18652
 exports[`regression tests spacebar + drag scrolls the canvas: [end of test] appState 1`] = `
18652
 exports[`regression tests spacebar + drag scrolls the canvas: [end of test] appState 1`] = `
18653
 Object {
18653
 Object {
18747
 
18747
 
18748
 exports[`regression tests spacebar + drag scrolls the canvas: [end of test] number of elements 1`] = `0`;
18748
 exports[`regression tests spacebar + drag scrolls the canvas: [end of test] number of elements 1`] = `0`;
18749
 
18749
 
18750
-exports[`regression tests spacebar + drag scrolls the canvas: [end of test] number of renders 1`] = `6`;
18750
+exports[`regression tests spacebar + drag scrolls the canvas: [end of test] number of renders 1`] = `7`;
18751
 
18751
 
18752
 exports[`regression tests supports nested groups: [end of test] appState 1`] = `
18752
 exports[`regression tests supports nested groups: [end of test] appState 1`] = `
18753
 Object {
18753
 Object {
19479
 
19479
 
19480
 exports[`regression tests supports nested groups: [end of test] number of elements 1`] = `3`;
19480
 exports[`regression tests supports nested groups: [end of test] number of elements 1`] = `3`;
19481
 
19481
 
19482
-exports[`regression tests supports nested groups: [end of test] number of renders 1`] = `30`;
19482
+exports[`regression tests supports nested groups: [end of test] number of renders 1`] = `31`;
19483
 
19483
 
19484
 exports[`regression tests switches from group of selected elements to another element on pointer down: [end of test] appState 1`] = `
19484
 exports[`regression tests switches from group of selected elements to another element on pointer down: [end of test] appState 1`] = `
19485
 Object {
19485
 Object {
19884
 
19884
 
19885
 exports[`regression tests switches from group of selected elements to another element on pointer down: [end of test] number of elements 1`] = `3`;
19885
 exports[`regression tests switches from group of selected elements to another element on pointer down: [end of test] number of elements 1`] = `3`;
19886
 
19886
 
19887
-exports[`regression tests switches from group of selected elements to another element on pointer down: [end of test] number of renders 1`] = `18`;
19887
+exports[`regression tests switches from group of selected elements to another element on pointer down: [end of test] number of renders 1`] = `19`;
19888
 
19888
 
19889
 exports[`regression tests switches selected element on pointer down: [end of test] appState 1`] = `
19889
 exports[`regression tests switches selected element on pointer down: [end of test] appState 1`] = `
19890
 Object {
19890
 Object {
20179
 
20179
 
20180
 exports[`regression tests switches selected element on pointer down: [end of test] number of elements 1`] = `2`;
20180
 exports[`regression tests switches selected element on pointer down: [end of test] number of elements 1`] = `2`;
20181
 
20181
 
20182
-exports[`regression tests switches selected element on pointer down: [end of test] number of renders 1`] = `12`;
20182
+exports[`regression tests switches selected element on pointer down: [end of test] number of renders 1`] = `13`;
20183
 
20183
 
20184
 exports[`regression tests two-finger scroll works: [end of test] appState 1`] = `
20184
 exports[`regression tests two-finger scroll works: [end of test] appState 1`] = `
20185
 Object {
20185
 Object {
20281
 
20281
 
20282
 exports[`regression tests two-finger scroll works: [end of test] number of elements 1`] = `0`;
20282
 exports[`regression tests two-finger scroll works: [end of test] number of elements 1`] = `0`;
20283
 
20283
 
20284
-exports[`regression tests two-finger scroll works: [end of test] number of renders 1`] = `11`;
20284
+exports[`regression tests two-finger scroll works: [end of test] number of renders 1`] = `12`;
20285
 
20285
 
20286
 exports[`regression tests undo/redo drawing an element: [end of test] appState 1`] = `
20286
 exports[`regression tests undo/redo drawing an element: [end of test] appState 1`] = `
20287
 Object {
20287
 Object {
20779
 
20779
 
20780
 exports[`regression tests undo/redo drawing an element: [end of test] number of elements 1`] = `3`;
20780
 exports[`regression tests undo/redo drawing an element: [end of test] number of elements 1`] = `3`;
20781
 
20781
 
20782
-exports[`regression tests undo/redo drawing an element: [end of test] number of renders 1`] = `28`;
20782
+exports[`regression tests undo/redo drawing an element: [end of test] number of renders 1`] = `29`;
20783
 
20783
 
20784
 exports[`regression tests updates fontSize & fontFamily appState: [end of test] appState 1`] = `
20784
 exports[`regression tests updates fontSize & fontFamily appState: [end of test] appState 1`] = `
20785
 Object {
20785
 Object {
20879
 
20879
 
20880
 exports[`regression tests updates fontSize & fontFamily appState: [end of test] number of elements 1`] = `0`;
20880
 exports[`regression tests updates fontSize & fontFamily appState: [end of test] number of elements 1`] = `0`;
20881
 
20881
 
20882
-exports[`regression tests updates fontSize & fontFamily appState: [end of test] number of renders 1`] = `5`;
20882
+exports[`regression tests updates fontSize & fontFamily appState: [end of test] number of renders 1`] = `6`;
20883
 
20883
 
20884
 exports[`regression tests zoom hotkeys: [end of test] appState 1`] = `
20884
 exports[`regression tests zoom hotkeys: [end of test] appState 1`] = `
20885
 Object {
20885
 Object {
20979
 
20979
 
20980
 exports[`regression tests zoom hotkeys: [end of test] number of elements 1`] = `0`;
20980
 exports[`regression tests zoom hotkeys: [end of test] number of elements 1`] = `0`;
20981
 
20981
 
20982
-exports[`regression tests zoom hotkeys: [end of test] number of renders 1`] = `5`;
20982
+exports[`regression tests zoom hotkeys: [end of test] number of renders 1`] = `6`;

+ 10
- 10
src/tests/__snapshots__/selection.test.tsx.snap View File

36
   "version": 3,
36
   "version": 3,
37
   "versionNonce": 449462985,
37
   "versionNonce": 449462985,
38
   "width": 30,
38
   "width": 30,
39
-  "x": 30,
40
-  "y": 20,
39
+  "x": 10,
40
+  "y": 10,
41
 }
41
 }
42
 `;
42
 `;
43
 
43
 
77
   "version": 3,
77
   "version": 3,
78
   "versionNonce": 449462985,
78
   "versionNonce": 449462985,
79
   "width": 30,
79
   "width": 30,
80
-  "x": 30,
81
-  "y": 20,
80
+  "x": 10,
81
+  "y": 10,
82
 }
82
 }
83
 `;
83
 `;
84
 
84
 
103
   "version": 2,
103
   "version": 2,
104
   "versionNonce": 1278240551,
104
   "versionNonce": 1278240551,
105
   "width": 30,
105
   "width": 30,
106
-  "x": 30,
107
-  "y": 20,
106
+  "x": 10,
107
+  "y": 10,
108
 }
108
 }
109
 `;
109
 `;
110
 
110
 
129
   "version": 2,
129
   "version": 2,
130
   "versionNonce": 1278240551,
130
   "versionNonce": 1278240551,
131
   "width": 30,
131
   "width": 30,
132
-  "x": 30,
133
-  "y": 20,
132
+  "x": 10,
133
+  "y": 10,
134
 }
134
 }
135
 `;
135
 `;
136
 
136
 
155
   "version": 2,
155
   "version": 2,
156
   "versionNonce": 1278240551,
156
   "versionNonce": 1278240551,
157
   "width": 30,
157
   "width": 30,
158
-  "x": 30,
159
-  "y": 20,
158
+  "x": 10,
159
+  "y": 10,
160
 }
160
 }
161
 `;
161
 `;

+ 18
- 6
src/tests/dragCreate.test.tsx View File

3
 import ExcalidrawApp from "../excalidraw-app";
3
 import ExcalidrawApp from "../excalidraw-app";
4
 import * as Renderer from "../renderer/renderScene";
4
 import * as Renderer from "../renderer/renderScene";
5
 import { KEYS } from "../keys";
5
 import { KEYS } from "../keys";
6
-import { render, fireEvent } from "./test-utils";
6
+import {
7
+  render,
8
+  fireEvent,
9
+  mockBoundingClientRect,
10
+  restoreOriginalGetBoundingClientRect,
11
+} from "./test-utils";
7
 import { ExcalidrawLinearElement } from "../element/types";
12
 import { ExcalidrawLinearElement } from "../element/types";
8
 import { reseed } from "../random";
13
 import { reseed } from "../random";
9
 
14
 
37
     // finish (position does not matter)
42
     // finish (position does not matter)
38
     fireEvent.pointerUp(canvas);
43
     fireEvent.pointerUp(canvas);
39
 
44
 
40
-    expect(renderScene).toHaveBeenCalledTimes(7);
45
+    expect(renderScene).toHaveBeenCalledTimes(8);
41
     expect(h.state.selectionElement).toBeNull();
46
     expect(h.state.selectionElement).toBeNull();
42
 
47
 
43
     expect(h.elements.length).toEqual(1);
48
     expect(h.elements.length).toEqual(1);
68
     // finish (position does not matter)
73
     // finish (position does not matter)
69
     fireEvent.pointerUp(canvas);
74
     fireEvent.pointerUp(canvas);
70
 
75
 
71
-    expect(renderScene).toHaveBeenCalledTimes(7);
76
+    expect(renderScene).toHaveBeenCalledTimes(8);
72
     expect(h.state.selectionElement).toBeNull();
77
     expect(h.state.selectionElement).toBeNull();
73
 
78
 
74
     expect(h.elements.length).toEqual(1);
79
     expect(h.elements.length).toEqual(1);
99
     // finish (position does not matter)
104
     // finish (position does not matter)
100
     fireEvent.pointerUp(canvas);
105
     fireEvent.pointerUp(canvas);
101
 
106
 
102
-    expect(renderScene).toHaveBeenCalledTimes(7);
107
+    expect(renderScene).toHaveBeenCalledTimes(8);
103
     expect(h.state.selectionElement).toBeNull();
108
     expect(h.state.selectionElement).toBeNull();
104
 
109
 
105
     expect(h.elements.length).toEqual(1);
110
     expect(h.elements.length).toEqual(1);
130
     // finish (position does not matter)
135
     // finish (position does not matter)
131
     fireEvent.pointerUp(canvas);
136
     fireEvent.pointerUp(canvas);
132
 
137
 
133
-    expect(renderScene).toHaveBeenCalledTimes(7);
138
+    expect(renderScene).toHaveBeenCalledTimes(8);
134
     expect(h.state.selectionElement).toBeNull();
139
     expect(h.state.selectionElement).toBeNull();
135
 
140
 
136
     expect(h.elements.length).toEqual(1);
141
     expect(h.elements.length).toEqual(1);
165
     // finish (position does not matter)
170
     // finish (position does not matter)
166
     fireEvent.pointerUp(canvas);
171
     fireEvent.pointerUp(canvas);
167
 
172
 
168
-    expect(renderScene).toHaveBeenCalledTimes(7);
173
+    expect(renderScene).toHaveBeenCalledTimes(8);
169
     expect(h.state.selectionElement).toBeNull();
174
     expect(h.state.selectionElement).toBeNull();
170
 
175
 
171
     expect(h.elements.length).toEqual(1);
176
     expect(h.elements.length).toEqual(1);
184
 });
189
 });
185
 
190
 
186
 describe("do not add element to the scene if size is too small", () => {
191
 describe("do not add element to the scene if size is too small", () => {
192
+  beforeAll(() => {
193
+    mockBoundingClientRect();
194
+  });
195
+  afterAll(() => {
196
+    restoreOriginalGetBoundingClientRect();
197
+  });
198
+
187
   it("rectangle", async () => {
199
   it("rectangle", async () => {
188
     const { getByToolName, container } = await render(<ExcalidrawApp />);
200
     const { getByToolName, container } = await render(<ExcalidrawApp />);
189
     // select tool
201
     // select tool

+ 2
- 2
src/tests/move.test.tsx View File

38
       fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 });
38
       fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 });
39
       fireEvent.pointerUp(canvas);
39
       fireEvent.pointerUp(canvas);
40
 
40
 
41
-      expect(renderScene).toHaveBeenCalledTimes(7);
41
+      expect(renderScene).toHaveBeenCalledTimes(8);
42
       expect(h.state.selectionElement).toBeNull();
42
       expect(h.state.selectionElement).toBeNull();
43
       expect(h.elements.length).toEqual(1);
43
       expect(h.elements.length).toEqual(1);
44
       expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy();
44
       expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy();
120
       fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 });
120
       fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 });
121
       fireEvent.pointerUp(canvas);
121
       fireEvent.pointerUp(canvas);
122
 
122
 
123
-      expect(renderScene).toHaveBeenCalledTimes(7);
123
+      expect(renderScene).toHaveBeenCalledTimes(8);
124
       expect(h.state.selectionElement).toBeNull();
124
       expect(h.state.selectionElement).toBeNull();
125
       expect(h.elements.length).toEqual(1);
125
       expect(h.elements.length).toEqual(1);
126
       expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy();
126
       expect(h.state.selectedElementIds[h.elements[0].id]).toBeTruthy();

+ 16
- 3
src/tests/multiPointCreate.test.tsx View File

1
 import React from "react";
1
 import React from "react";
2
 import ReactDOM from "react-dom";
2
 import ReactDOM from "react-dom";
3
-import { render, fireEvent } from "./test-utils";
3
+import {
4
+  render,
5
+  fireEvent,
6
+  mockBoundingClientRect,
7
+  restoreOriginalGetBoundingClientRect,
8
+} from "./test-utils";
4
 import ExcalidrawApp from "../excalidraw-app";
9
 import ExcalidrawApp from "../excalidraw-app";
5
 import * as Renderer from "../renderer/renderScene";
10
 import * as Renderer from "../renderer/renderScene";
6
 import { KEYS } from "../keys";
11
 import { KEYS } from "../keys";
20
 const { h } = window;
25
 const { h } = window;
21
 
26
 
22
 describe("remove shape in non linear elements", () => {
27
 describe("remove shape in non linear elements", () => {
28
+  beforeAll(() => {
29
+    mockBoundingClientRect();
30
+  });
31
+
32
+  afterAll(() => {
33
+    restoreOriginalGetBoundingClientRect();
34
+  });
35
+
23
   it("rectangle", async () => {
36
   it("rectangle", async () => {
24
     const { getByToolName, container } = await render(<ExcalidrawApp />);
37
     const { getByToolName, container } = await render(<ExcalidrawApp />);
25
     // select tool
38
     // select tool
88
     fireEvent.pointerUp(canvas);
101
     fireEvent.pointerUp(canvas);
89
     fireEvent.keyDown(document, { key: KEYS.ENTER });
102
     fireEvent.keyDown(document, { key: KEYS.ENTER });
90
 
103
 
91
-    expect(renderScene).toHaveBeenCalledTimes(13);
104
+    expect(renderScene).toHaveBeenCalledTimes(14);
92
     expect(h.elements.length).toEqual(1);
105
     expect(h.elements.length).toEqual(1);
93
 
106
 
94
     const element = h.elements[0] as ExcalidrawLinearElement;
107
     const element = h.elements[0] as ExcalidrawLinearElement;
129
     fireEvent.pointerUp(canvas);
142
     fireEvent.pointerUp(canvas);
130
     fireEvent.keyDown(document, { key: KEYS.ENTER });
143
     fireEvent.keyDown(document, { key: KEYS.ENTER });
131
 
144
 
132
-    expect(renderScene).toHaveBeenCalledTimes(13);
145
+    expect(renderScene).toHaveBeenCalledTimes(14);
133
     expect(h.elements.length).toEqual(1);
146
     expect(h.elements.length).toEqual(1);
134
 
147
 
135
     const element = h.elements[0] as ExcalidrawLinearElement;
148
     const element = h.elements[0] as ExcalidrawLinearElement;

+ 0
- 4
src/tests/packages/__snapshots__/utils.test.ts.snap View File

32
   "exportWithDarkMode": false,
32
   "exportWithDarkMode": false,
33
   "fileHandle": null,
33
   "fileHandle": null,
34
   "gridSize": null,
34
   "gridSize": null,
35
-  "height": 768,
36
   "isBindingEnabled": true,
35
   "isBindingEnabled": true,
37
   "isLibraryOpen": false,
36
   "isLibraryOpen": false,
38
   "isLoading": false,
37
   "isLoading": false,
42
   "metadata": undefined,
41
   "metadata": undefined,
43
   "multiElement": null,
42
   "multiElement": null,
44
   "name": "name",
43
   "name": "name",
45
-  "offsetLeft": 0,
46
-  "offsetTop": 0,
47
   "openMenu": null,
44
   "openMenu": null,
48
   "pasteDialog": Object {
45
   "pasteDialog": Object {
49
     "data": null,
46
     "data": null,
67
   "toastMessage": null,
64
   "toastMessage": null,
68
   "viewBackgroundColor": "#ffffff",
65
   "viewBackgroundColor": "#ffffff",
69
   "viewModeEnabled": false,
66
   "viewModeEnabled": false,
70
-  "width": 1024,
71
   "zenModeEnabled": false,
67
   "zenModeEnabled": false,
72
   "zoom": Object {
68
   "zoom": Object {
73
     "translation": Object {
69
     "translation": Object {

+ 1
- 0
src/tests/regressionTests.test.tsx View File

76
   finger2.reset();
76
   finger2.reset();
77
 
77
 
78
   await render(<ExcalidrawApp />);
78
   await render(<ExcalidrawApp />);
79
+  h.setState({ height: 768, width: 1024 });
79
 });
80
 });
80
 
81
 
81
 afterEach(() => {
82
 afterEach(() => {

+ 14
- 24
src/tests/scroll.test.tsx View File

1
 import React from "react";
1
 import React from "react";
2
-import { render, waitFor } from "./test-utils";
2
+import {
3
+  mockBoundingClientRect,
4
+  render,
5
+  restoreOriginalGetBoundingClientRect,
6
+  waitFor,
7
+} from "./test-utils";
3
 import Excalidraw from "../packages/excalidraw/index";
8
 import Excalidraw from "../packages/excalidraw/index";
4
 import { API } from "./helpers/api";
9
 import { API } from "./helpers/api";
5
 
10
 
7
 
12
 
8
 describe("appState", () => {
13
 describe("appState", () => {
9
   it("scroll-to-content on init works with non-zero offsets", async () => {
14
   it("scroll-to-content on init works with non-zero offsets", async () => {
10
-    const WIDTH = 600;
11
-    const HEIGHT = 700;
12
-    const OFFSET_LEFT = 200;
13
-    const OFFSET_TOP = 100;
15
+    const WIDTH = 200;
16
+    const HEIGHT = 100;
17
+    const OFFSET_LEFT = 20;
18
+    const OFFSET_TOP = 10;
14
 
19
 
15
     const ELEM_WIDTH = 100;
20
     const ELEM_WIDTH = 100;
16
     const ELEM_HEIGHT = 60;
21
     const ELEM_HEIGHT = 60;
17
 
22
 
18
-    const originalGetBoundingClientRect =
19
-      global.window.HTMLDivElement.prototype.getBoundingClientRect;
20
-    // override getBoundingClientRect as by default it will always return all values as 0 even if customized in html
21
-    global.window.HTMLDivElement.prototype.getBoundingClientRect = () => ({
22
-      top: OFFSET_TOP,
23
-      left: OFFSET_LEFT,
24
-      bottom: 10,
25
-      right: 10,
26
-      width: 100,
27
-      x: 10,
28
-      y: 20,
29
-      height: 100,
30
-      toJSON: () => {},
31
-    });
23
+    mockBoundingClientRect();
32
 
24
 
33
     await render(
25
     await render(
34
       <div>
26
       <div>
35
         <Excalidraw
27
         <Excalidraw
36
-          width={WIDTH}
37
-          height={HEIGHT}
38
           initialData={{
28
           initialData={{
39
             elements: [
29
             elements: [
40
               API.createElement({
30
               API.createElement({
50
       </div>,
40
       </div>,
51
     );
41
     );
52
     await waitFor(() => {
42
     await waitFor(() => {
53
-      expect(h.state.width).toBe(WIDTH);
54
-      expect(h.state.height).toBe(HEIGHT);
43
+      expect(h.state.width).toBe(200);
44
+      expect(h.state.height).toBe(100);
55
       expect(h.state.offsetLeft).toBe(OFFSET_LEFT);
45
       expect(h.state.offsetLeft).toBe(OFFSET_LEFT);
56
       expect(h.state.offsetTop).toBe(OFFSET_TOP);
46
       expect(h.state.offsetTop).toBe(OFFSET_TOP);
57
 
47
 
59
       expect(h.state.scrollX).toBe(WIDTH / 2 - ELEM_WIDTH / 2);
49
       expect(h.state.scrollX).toBe(WIDTH / 2 - ELEM_WIDTH / 2);
60
       expect(h.state.scrollY).toBe(HEIGHT / 2 - ELEM_HEIGHT / 2);
50
       expect(h.state.scrollY).toBe(HEIGHT / 2 - ELEM_HEIGHT / 2);
61
     });
51
     });
62
-    global.window.HTMLDivElement.prototype.getBoundingClientRect = originalGetBoundingClientRect;
52
+    restoreOriginalGetBoundingClientRect();
63
   });
53
   });
64
 });
54
 });

+ 14
- 1
src/tests/selection.test.tsx View File

1
 import React from "react";
1
 import React from "react";
2
 import ReactDOM from "react-dom";
2
 import ReactDOM from "react-dom";
3
-import { render, fireEvent } from "./test-utils";
3
+import {
4
+  render,
5
+  fireEvent,
6
+  mockBoundingClientRect,
7
+  restoreOriginalGetBoundingClientRect,
8
+} from "./test-utils";
4
 import ExcalidrawApp from "../excalidraw-app";
9
 import ExcalidrawApp from "../excalidraw-app";
5
 import * as Renderer from "../renderer/renderScene";
10
 import * as Renderer from "../renderer/renderScene";
6
 import { KEYS } from "../keys";
11
 import { KEYS } from "../keys";
77
 });
82
 });
78
 
83
 
79
 describe("select single element on the scene", () => {
84
 describe("select single element on the scene", () => {
85
+  beforeAll(() => {
86
+    mockBoundingClientRect();
87
+  });
88
+
89
+  afterAll(() => {
90
+    restoreOriginalGetBoundingClientRect();
91
+  });
92
+
80
   it("rectangle", async () => {
93
   it("rectangle", async () => {
81
     const { getByToolName, container } = await render(<ExcalidrawApp />);
94
     const { getByToolName, container } = await render(<ExcalidrawApp />);
82
     const canvas = container.querySelector("canvas")!;
95
     const canvas = container.querySelector("canvas")!;

+ 22
- 0
src/tests/test-utils.ts View File

102
 export const updateSceneData = (data: SceneData) => {
102
 export const updateSceneData = (data: SceneData) => {
103
   (window.collab as any).excalidrawAPI.updateScene(data);
103
   (window.collab as any).excalidrawAPI.updateScene(data);
104
 };
104
 };
105
+
106
+const originalGetBoundingClientRect =
107
+  global.window.HTMLDivElement.prototype.getBoundingClientRect;
108
+
109
+export const mockBoundingClientRect = () => {
110
+  // override getBoundingClientRect as by default it will always return all values as 0 even if customized in html
111
+  global.window.HTMLDivElement.prototype.getBoundingClientRect = () => ({
112
+    top: 10,
113
+    left: 20,
114
+    bottom: 10,
115
+    right: 10,
116
+    width: 200,
117
+    x: 10,
118
+    y: 20,
119
+    height: 100,
120
+    toJSON: () => {},
121
+  });
122
+};
123
+
124
+export const restoreOriginalGetBoundingClientRect = () => {
125
+  global.window.HTMLDivElement.prototype.getBoundingClientRect = originalGetBoundingClientRect;
126
+};

+ 0
- 2
src/types.ts View File

159
     };
159
     };
160
 
160
 
161
 export interface ExcalidrawProps {
161
 export interface ExcalidrawProps {
162
-  width?: number;
163
-  height?: number;
164
   onChange?: (
162
   onChange?: (
165
     elements: readonly ExcalidrawElement[],
163
     elements: readonly ExcalidrawElement[],
166
     appState: AppState,
164
     appState: AppState,

Loading…
Cancel
Save