diff --git a/src/components/App.tsx b/src/components/App.tsx index 2bfa6687..91464364 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -111,7 +111,6 @@ import { import { LinearElementEditor } from "../element/linearElementEditor"; import { mutateElement } from "../element/mutateElement"; import { deepCopyElement, newFreeDrawElement } from "../element/newElement"; -import { MaybeTransformHandleType } from "../element/transformHandles"; import { isBindingElement, isBindingElementType, @@ -167,9 +166,11 @@ import { findShapeByKey } from "../shapes"; import { AppProps, AppState, + ExcalidrawImperativeAPI, Gesture, GestureEvent, LibraryItems, + PointerDownState, SceneData, } from "../types"; import { @@ -180,7 +181,6 @@ import { isToolIcon, isWritableElement, resetCursor, - ResolvablePromise, resolvablePromise, sceneCoordsToViewportCoords, setCursor, @@ -222,83 +222,6 @@ const gesture: Gesture = { initialScale: null, }; -export type PointerDownState = Readonly<{ - // The first position at which pointerDown happened - origin: Readonly<{ x: number; y: number }>; - // Same as "origin" but snapped to the grid, if grid is on - originInGrid: Readonly<{ x: number; y: number }>; - // Scrollbar checks - scrollbars: ReturnType; - // The previous pointer position - lastCoords: { x: number; y: number }; - // map of original elements data - originalElements: Map>; - resize: { - // Handle when resizing, might change during the pointer interaction - handleType: MaybeTransformHandleType; - // This is determined on the initial pointer down event - isResizing: boolean; - // This is determined on the initial pointer down event - offset: { x: number; y: number }; - // This is determined on the initial pointer down event - arrowDirection: "origin" | "end"; - // This is a center point of selected elements determined on the initial pointer down event (for rotation only) - center: { x: number; y: number }; - }; - hit: { - // The element the pointer is "hitting", is determined on the initial - // pointer down event - element: NonDeleted | null; - // The elements the pointer is "hitting", is determined on the initial - // pointer down event - allHitElements: NonDeleted[]; - // This is determined on the initial pointer down event - wasAddedToSelection: boolean; - // Whether selected element(s) were duplicated, might change during the - // pointer interaction - hasBeenDuplicated: boolean; - hasHitCommonBoundingBoxOfSelectedElements: boolean; - }; - withCmdOrCtrl: boolean; - drag: { - // Might change during the pointer interation - hasOccurred: boolean; - // Might change during the pointer interation - offset: { x: number; y: number } | null; - }; - // We need to have these in the state so that we can unsubscribe them - eventListeners: { - // It's defined on the initial pointer down event - onMove: null | ((event: PointerEvent) => void); - // It's defined on the initial pointer down event - onUp: null | ((event: PointerEvent) => void); - // It's defined on the initial pointer down event - onKeyDown: null | ((event: KeyboardEvent) => void); - // It's defined on the initial pointer down event - onKeyUp: null | ((event: KeyboardEvent) => void); - }; -}>; - -export type ExcalidrawImperativeAPI = { - updateScene: InstanceType["updateScene"]; - resetScene: InstanceType["resetScene"]; - getSceneElementsIncludingDeleted: InstanceType< - typeof App - >["getSceneElementsIncludingDeleted"]; - history: { - clear: InstanceType["resetHistory"]; - }; - scrollToContent: InstanceType["scrollToContent"]; - getSceneElements: InstanceType["getSceneElements"]; - getAppState: () => InstanceType["state"]; - refresh: InstanceType["refresh"]; - importLibrary: InstanceType["importLibraryFromUrl"]; - setToastMessage: InstanceType["setToastMessage"]; - readyPromise: ResolvablePromise; - ready: true; - id: string; -}; - class App extends React.Component { canvas: HTMLCanvasElement | null = null; rc: RoughCanvas | null = null; diff --git a/src/data/library.ts b/src/data/library.ts index ab5bae35..64ee2c98 100644 --- a/src/data/library.ts +++ b/src/data/library.ts @@ -2,7 +2,7 @@ import { loadLibraryFromBlob } from "./blob"; import { LibraryItems, LibraryItem } from "../types"; import { restoreElements } from "./restore"; import { getNonDeletedElements } from "../element"; -import App from "../components/App"; +import type App from "../components/App"; class Library { private libraryCache: LibraryItems | null = null; diff --git a/src/element/dragElements.ts b/src/element/dragElements.ts index a269b438..f10017f3 100644 --- a/src/element/dragElements.ts +++ b/src/element/dragElements.ts @@ -5,7 +5,7 @@ import { mutateElement } from "./mutateElement"; import { getPerfectElementSize } from "./sizeHelpers"; import Scene from "../scene/Scene"; import { NonDeletedExcalidrawElement } from "./types"; -import { PointerDownState } from "../components/App"; +import { PointerDownState } from "../types"; export const dragSelectedElements = ( pointerDownState: PointerDownState, diff --git a/src/element/resizeElements.ts b/src/element/resizeElements.ts index 28c551c7..e65fdf0a 100644 --- a/src/element/resizeElements.ts +++ b/src/element/resizeElements.ts @@ -32,8 +32,7 @@ import { MaybeTransformHandleType, TransformHandleDirection, } from "./transformHandles"; -import { PointerDownState } from "../components/App"; -import { Point } from "../types"; +import { Point, PointerDownState } from "../types"; export const normalizeAngle = (angle: number): number => { if (angle >= 2 * Math.PI) { diff --git a/src/excalidraw-app/collab/CollabWrapper.tsx b/src/excalidraw-app/collab/CollabWrapper.tsx index f961e5ad..793c4c9d 100644 --- a/src/excalidraw-app/collab/CollabWrapper.tsx +++ b/src/excalidraw-app/collab/CollabWrapper.tsx @@ -1,6 +1,6 @@ import throttle from "lodash.throttle"; import React, { PureComponent } from "react"; -import { ExcalidrawImperativeAPI } from "../../components/App"; +import { ExcalidrawImperativeAPI } from "../../types"; import { ErrorDialog } from "../../components/ErrorDialog"; import { APP_NAME, ENV, EVENT } from "../../constants"; import { ImportedDataState } from "../../data/types"; diff --git a/src/excalidraw-app/index.tsx b/src/excalidraw-app/index.tsx index 1d71dfe6..a2705825 100644 --- a/src/excalidraw-app/index.tsx +++ b/src/excalidraw-app/index.tsx @@ -8,7 +8,6 @@ import React, { } from "react"; import { trackEvent } from "../analytics"; import { getDefaultAppState } from "../appState"; -import { ExcalidrawImperativeAPI } from "../components/App"; import { ErrorDialog } from "../components/ErrorDialog"; import { TopErrorBoundary } from "../components/TopErrorBoundary"; import { @@ -31,7 +30,7 @@ import Excalidraw, { defaultLang, languages, } from "../packages/excalidraw/index"; -import { AppState, LibraryItems } from "../types"; +import { AppState, LibraryItems, ExcalidrawImperativeAPI } from "../types"; import { debounce, getVersion, diff --git a/src/tests/__snapshots__/excalidrawPackage.test.tsx.snap b/src/tests/packages/__snapshots__/excalidraw.test.tsx.snap similarity index 100% rename from src/tests/__snapshots__/excalidrawPackage.test.tsx.snap rename to src/tests/packages/__snapshots__/excalidraw.test.tsx.snap diff --git a/src/tests/excalidrawPackage.test.tsx b/src/tests/packages/excalidraw.test.tsx similarity index 97% rename from src/tests/excalidrawPackage.test.tsx rename to src/tests/packages/excalidraw.test.tsx index 03e2a629..6dbc234d 100644 --- a/src/tests/excalidrawPackage.test.tsx +++ b/src/tests/packages/excalidraw.test.tsx @@ -1,9 +1,9 @@ import React from "react"; -import { fireEvent, GlobalTestState, render } from "./test-utils"; -import Excalidraw from "../packages/excalidraw/index"; +import { fireEvent, GlobalTestState, render } from "../test-utils"; +import Excalidraw from "../../packages/excalidraw/index"; import { queryByText, queryByTestId } from "@testing-library/react"; -import { GRID_SIZE } from "../constants"; -import { t } from "../i18n"; +import { GRID_SIZE } from "../../constants"; +import { t } from "../../i18n"; const { h } = window; diff --git a/src/types.ts b/src/types.ts index b8adaf34..213b373b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,11 +16,13 @@ import { Point as RoughPoint } from "roughjs/bin/geometry"; import { LinearElementEditor } from "./element/linearElementEditor"; import { SuggestedBinding } from "./element/binding"; import { ImportedDataState } from "./data/types"; -import { ExcalidrawImperativeAPI } from "./components/App"; +import type App from "./components/App"; import type { ResolvablePromise } from "./utils"; import { Spreadsheet } from "./charts"; import { Language } from "./i18n"; import { ClipboardData } from "./clipboard"; +import { isOverScrollBars } from "./scene"; +import { MaybeTransformHandleType } from "./element/transformHandles"; export type Point = Readonly; @@ -249,3 +251,80 @@ export type AppProps = ExcalidrawProps & { detectScroll: boolean; handleKeyboardGlobally: boolean; }; + +export type PointerDownState = Readonly<{ + // The first position at which pointerDown happened + origin: Readonly<{ x: number; y: number }>; + // Same as "origin" but snapped to the grid, if grid is on + originInGrid: Readonly<{ x: number; y: number }>; + // Scrollbar checks + scrollbars: ReturnType; + // The previous pointer position + lastCoords: { x: number; y: number }; + // map of original elements data + originalElements: Map>; + resize: { + // Handle when resizing, might change during the pointer interaction + handleType: MaybeTransformHandleType; + // This is determined on the initial pointer down event + isResizing: boolean; + // This is determined on the initial pointer down event + offset: { x: number; y: number }; + // This is determined on the initial pointer down event + arrowDirection: "origin" | "end"; + // This is a center point of selected elements determined on the initial pointer down event (for rotation only) + center: { x: number; y: number }; + }; + hit: { + // The element the pointer is "hitting", is determined on the initial + // pointer down event + element: NonDeleted | null; + // The elements the pointer is "hitting", is determined on the initial + // pointer down event + allHitElements: NonDeleted[]; + // This is determined on the initial pointer down event + wasAddedToSelection: boolean; + // Whether selected element(s) were duplicated, might change during the + // pointer interaction + hasBeenDuplicated: boolean; + hasHitCommonBoundingBoxOfSelectedElements: boolean; + }; + withCmdOrCtrl: boolean; + drag: { + // Might change during the pointer interation + hasOccurred: boolean; + // Might change during the pointer interation + offset: { x: number; y: number } | null; + }; + // We need to have these in the state so that we can unsubscribe them + eventListeners: { + // It's defined on the initial pointer down event + onMove: null | ((event: PointerEvent) => void); + // It's defined on the initial pointer down event + onUp: null | ((event: PointerEvent) => void); + // It's defined on the initial pointer down event + onKeyDown: null | ((event: KeyboardEvent) => void); + // It's defined on the initial pointer down event + onKeyUp: null | ((event: KeyboardEvent) => void); + }; +}>; + +export type ExcalidrawImperativeAPI = { + updateScene: InstanceType["updateScene"]; + resetScene: InstanceType["resetScene"]; + getSceneElementsIncludingDeleted: InstanceType< + typeof App + >["getSceneElementsIncludingDeleted"]; + history: { + clear: InstanceType["resetHistory"]; + }; + scrollToContent: InstanceType["scrollToContent"]; + getSceneElements: InstanceType["getSceneElements"]; + getAppState: () => InstanceType["state"]; + refresh: InstanceType["refresh"]; + importLibrary: InstanceType["importLibraryFromUrl"]; + setToastMessage: InstanceType["setToastMessage"]; + readyPromise: ResolvablePromise; + ready: true; + id: string; +};