diff --git a/excalidraw-app/App.tsx b/excalidraw-app/App.tsx index 7091d4bc57..60e9b30083 100644 --- a/excalidraw-app/App.tsx +++ b/excalidraw-app/App.tsx @@ -22,13 +22,6 @@ import { THEME, TITLE_TIMEOUT, VERSION_TIMEOUT, -} from "@excalidraw/excalidraw/constants"; -import polyfill from "@excalidraw/excalidraw/polyfill"; -import { useCallback, useEffect, useRef, useState } from "react"; -import { loadFromBlob } from "@excalidraw/excalidraw/data/blob"; -import { useCallbackRefState } from "@excalidraw/excalidraw/hooks/useCallbackRefState"; -import { t } from "@excalidraw/excalidraw/i18n"; -import { debounce, getVersion, getFrame, @@ -37,7 +30,13 @@ import { resolvablePromise, isRunningInIframe, isDevEnv, -} from "@excalidraw/excalidraw/utils"; +} from "@excalidraw/common"; +import polyfill from "@excalidraw/excalidraw/polyfill"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { loadFromBlob } from "@excalidraw/excalidraw/data/blob"; +import { useCallbackRefState } from "@excalidraw/excalidraw/hooks/useCallbackRefState"; +import { t } from "@excalidraw/excalidraw/i18n"; + import { GithubIcon, XBrandIcon, @@ -48,10 +47,10 @@ import { share, youtubeIcon, } from "@excalidraw/excalidraw/components/icons"; -import { isElementLink } from "@excalidraw/excalidraw/element/elementLink"; +import { isElementLink } from "@excalidraw/element/elementLink"; import { restore, restoreAppState } from "@excalidraw/excalidraw/data/restore"; -import { newElementWith } from "@excalidraw/excalidraw/element/mutateElement"; -import { isInitializedImageElement } from "@excalidraw/excalidraw/element/typeChecks"; +import { newElementWith } from "@excalidraw/element/mutateElement"; +import { isInitializedImageElement } from "@excalidraw/element/typeChecks"; import clsx from "clsx"; import { parseLibraryTokensFromUrl, @@ -64,7 +63,7 @@ import type { FileId, NonDeletedExcalidrawElement, OrderedExcalidrawElement, -} from "@excalidraw/excalidraw/element/types"; +} from "@excalidraw/element/types"; import type { AppState, ExcalidrawImperativeAPI, @@ -72,8 +71,8 @@ import type { ExcalidrawInitialDataState, UIAppState, } from "@excalidraw/excalidraw/types"; -import type { ResolutionType } from "@excalidraw/excalidraw/utility-types"; -import type { ResolvablePromise } from "@excalidraw/excalidraw/utils"; +import type { ResolutionType } from "@excalidraw/common/utility-types"; +import type { ResolvablePromise } from "@excalidraw/common/utils"; import CustomStats from "./CustomStats"; import { diff --git a/excalidraw-app/CustomStats.tsx b/excalidraw-app/CustomStats.tsx index c57f297fe1..543af5cfde 100644 --- a/excalidraw-app/CustomStats.tsx +++ b/excalidraw-app/CustomStats.tsx @@ -1,11 +1,15 @@ import { Stats } from "@excalidraw/excalidraw"; import { copyTextToSystemClipboard } from "@excalidraw/excalidraw/clipboard"; -import { DEFAULT_VERSION } from "@excalidraw/excalidraw/constants"; +import { + DEFAULT_VERSION, + debounce, + getVersion, + nFormatter, +} from "@excalidraw/common"; import { t } from "@excalidraw/excalidraw/i18n"; -import { debounce, getVersion, nFormatter } from "@excalidraw/excalidraw/utils"; import { useEffect, useState } from "react"; -import type { NonDeletedExcalidrawElement } from "@excalidraw/excalidraw/element/types"; +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; import type { UIAppState } from "@excalidraw/excalidraw/types"; import { diff --git a/excalidraw-app/ExcalidrawPlusIframeExport.tsx b/excalidraw-app/ExcalidrawPlusIframeExport.tsx index be046f795c..0ad27cafb0 100644 --- a/excalidraw-app/ExcalidrawPlusIframeExport.tsx +++ b/excalidraw-app/ExcalidrawPlusIframeExport.tsx @@ -5,7 +5,7 @@ import { useLayoutEffect, useRef } from "react"; import type { FileId, OrderedExcalidrawElement, -} from "@excalidraw/excalidraw/element/types"; +} from "@excalidraw/element/types"; import type { AppState, BinaryFileData } from "@excalidraw/excalidraw/types"; import { STORAGE_KEYS } from "./app_constants"; diff --git a/excalidraw-app/collab/Collab.tsx b/excalidraw-app/collab/Collab.tsx index be889e2c7d..f6f7630412 100644 --- a/excalidraw-app/collab/Collab.tsx +++ b/excalidraw-app/collab/Collab.tsx @@ -6,30 +6,29 @@ import { reconcileElements, } from "@excalidraw/excalidraw"; import { ErrorDialog } from "@excalidraw/excalidraw/components/ErrorDialog"; -import { APP_NAME, EVENT } from "@excalidraw/excalidraw/constants"; +import { APP_NAME, EVENT } from "@excalidraw/common"; import { IDLE_THRESHOLD, ACTIVE_THRESHOLD, UserIdleState, -} from "@excalidraw/excalidraw/constants"; -import { decryptData } from "@excalidraw/excalidraw/data/encryption"; -import { getVisibleSceneBounds } from "@excalidraw/excalidraw/element/bounds"; -import { newElementWith } from "@excalidraw/excalidraw/element/mutateElement"; -import { - isImageElement, - isInitializedImageElement, -} from "@excalidraw/excalidraw/element/typeChecks"; -import { AbortError } from "@excalidraw/excalidraw/errors"; -import { t } from "@excalidraw/excalidraw/i18n"; -import { withBatchedUpdates } from "@excalidraw/excalidraw/reactUtils"; -import { assertNever, isDevEnv, isTestEnv, preventUnload, resolvablePromise, throttleRAF, -} from "@excalidraw/excalidraw/utils"; +} from "@excalidraw/common"; +import { decryptData } from "@excalidraw/excalidraw/data/encryption"; +import { getVisibleSceneBounds } from "@excalidraw/element/bounds"; +import { newElementWith } from "@excalidraw/element/mutateElement"; +import { + isImageElement, + isInitializedImageElement, +} from "@excalidraw/element/typeChecks"; +import { AbortError } from "@excalidraw/excalidraw/errors"; +import { t } from "@excalidraw/excalidraw/i18n"; +import { withBatchedUpdates } from "@excalidraw/excalidraw/reactUtils"; + import throttle from "lodash.throttle"; import { PureComponent } from "react"; @@ -43,7 +42,7 @@ import type { FileId, InitializedExcalidrawImageElement, OrderedExcalidrawElement, -} from "@excalidraw/excalidraw/element/types"; +} from "@excalidraw/element/types"; import type { BinaryFileData, ExcalidrawImperativeAPI, @@ -51,7 +50,7 @@ import type { Collaborator, Gesture, } from "@excalidraw/excalidraw/types"; -import type { Mutable, ValueOf } from "@excalidraw/excalidraw/utility-types"; +import type { Mutable, ValueOf } from "@excalidraw/common/utility-types"; import { appJotaiStore, atom } from "../app-jotai"; import { diff --git a/excalidraw-app/collab/Portal.tsx b/excalidraw-app/collab/Portal.tsx index 037bca314e..26a7d0d9e0 100644 --- a/excalidraw-app/collab/Portal.tsx +++ b/excalidraw-app/collab/Portal.tsx @@ -1,11 +1,11 @@ import { CaptureUpdateAction } from "@excalidraw/excalidraw"; import { trackEvent } from "@excalidraw/excalidraw/analytics"; import { encryptData } from "@excalidraw/excalidraw/data/encryption"; -import { newElementWith } from "@excalidraw/excalidraw/element/mutateElement"; +import { newElementWith } from "@excalidraw/element/mutateElement"; import throttle from "lodash.throttle"; -import type { UserIdleState } from "@excalidraw/excalidraw/constants"; -import type { OrderedExcalidrawElement } from "@excalidraw/excalidraw/element/types"; +import type { UserIdleState } from "@excalidraw/common"; +import type { OrderedExcalidrawElement } from "@excalidraw/element/types"; import type { OnUserFollowedPayload, SocketId, diff --git a/excalidraw-app/components/AI.tsx b/excalidraw-app/components/AI.tsx index c9b6684b32..4469d74f66 100644 --- a/excalidraw-app/components/AI.tsx +++ b/excalidraw-app/components/AI.tsx @@ -6,7 +6,7 @@ import { TTDDialog, } from "@excalidraw/excalidraw"; import { getDataURL } from "@excalidraw/excalidraw/data/blob"; -import { safelyParseJSON } from "@excalidraw/excalidraw/utils"; +import { safelyParseJSON } from "@excalidraw/common"; import type { ExcalidrawImperativeAPI } from "@excalidraw/excalidraw/types"; diff --git a/excalidraw-app/components/AppMainMenu.tsx b/excalidraw-app/components/AppMainMenu.tsx index 4bc6bb471c..cd0aca2683 100644 --- a/excalidraw-app/components/AppMainMenu.tsx +++ b/excalidraw-app/components/AppMainMenu.tsx @@ -6,9 +6,9 @@ import { import { MainMenu } from "@excalidraw/excalidraw/index"; import React from "react"; -import { isDevEnv } from "@excalidraw/excalidraw/utils"; +import { isDevEnv } from "@excalidraw/common"; -import type { Theme } from "@excalidraw/excalidraw/element/types"; +import type { Theme } from "@excalidraw/element/types"; import { LanguageList } from "../app-language/LanguageList"; import { isExcalidrawPlusSignedUser } from "../app_constants"; diff --git a/excalidraw-app/components/AppWelcomeScreen.tsx b/excalidraw-app/components/AppWelcomeScreen.tsx index c33de092a8..5bb5073e9c 100644 --- a/excalidraw-app/components/AppWelcomeScreen.tsx +++ b/excalidraw-app/components/AppWelcomeScreen.tsx @@ -1,5 +1,5 @@ import { loginIcon } from "@excalidraw/excalidraw/components/icons"; -import { POINTER_EVENTS } from "@excalidraw/excalidraw/constants"; +import { POINTER_EVENTS } from "@excalidraw/common"; import { useI18n } from "@excalidraw/excalidraw/i18n"; import { WelcomeScreen } from "@excalidraw/excalidraw/index"; import React from "react"; diff --git a/excalidraw-app/components/DebugCanvas.tsx b/excalidraw-app/components/DebugCanvas.tsx index af1a2b1400..e83a62647d 100644 --- a/excalidraw-app/components/DebugCanvas.tsx +++ b/excalidraw-app/components/DebugCanvas.tsx @@ -8,20 +8,21 @@ import { getNormalizedCanvasDimensions, } from "@excalidraw/excalidraw/renderer/helpers"; import { type AppState } from "@excalidraw/excalidraw/types"; -import { throttleRAF } from "@excalidraw/excalidraw/utils"; +import { throttleRAF } from "@excalidraw/common"; import { useCallback, useImperativeHandle, useRef } from "react"; -import type { DebugElement } from "@excalidraw/excalidraw/visualdebug"; - import { isLineSegment, type GlobalPoint, type LineSegment, -} from "../../packages/math"; -import { isCurve } from "../../packages/math/curve"; -import { STORAGE_KEYS } from "../app_constants"; +} from "@excalidraw/math"; +import { isCurve } from "@excalidraw/math/curve"; -import type { Curve } from "../../packages/math"; +import type { DebugElement } from "@excalidraw/excalidraw/visualdebug"; + +import type { Curve } from "@excalidraw/math"; + +import { STORAGE_KEYS } from "../app_constants"; const renderLine = ( context: CanvasRenderingContext2D, diff --git a/excalidraw-app/components/ExportToExcalidrawPlus.tsx b/excalidraw-app/components/ExportToExcalidrawPlus.tsx index a630f804f1..60f1608b26 100644 --- a/excalidraw-app/components/ExportToExcalidrawPlus.tsx +++ b/excalidraw-app/components/ExportToExcalidrawPlus.tsx @@ -1,24 +1,24 @@ +import React from "react"; +import { uploadBytes, ref } from "firebase/storage"; +import { nanoid } from "nanoid"; + import { trackEvent } from "@excalidraw/excalidraw/analytics"; import { Card } from "@excalidraw/excalidraw/components/Card"; import { ExcalidrawLogo } from "@excalidraw/excalidraw/components/ExcalidrawLogo"; import { ToolButton } from "@excalidraw/excalidraw/components/ToolButton"; -import { MIME_TYPES } from "@excalidraw/excalidraw/constants"; +import { MIME_TYPES, getFrame } from "@excalidraw/common"; import { encryptData, generateEncryptionKey, } from "@excalidraw/excalidraw/data/encryption"; import { serializeAsJSON } from "@excalidraw/excalidraw/data/json"; -import { isInitializedImageElement } from "@excalidraw/excalidraw/element/typeChecks"; +import { isInitializedImageElement } from "@excalidraw/element/typeChecks"; import { useI18n } from "@excalidraw/excalidraw/i18n"; -import { getFrame } from "@excalidraw/excalidraw/utils"; -import { uploadBytes, ref } from "firebase/storage"; -import { nanoid } from "nanoid"; -import React from "react"; import type { FileId, NonDeletedExcalidrawElement, -} from "@excalidraw/excalidraw/element/types"; +} from "@excalidraw/element/types"; import type { AppState, BinaryFileData, diff --git a/excalidraw-app/components/GitHubCorner.tsx b/excalidraw-app/components/GitHubCorner.tsx index b1c17f29e9..6a4108813c 100644 --- a/excalidraw-app/components/GitHubCorner.tsx +++ b/excalidraw-app/components/GitHubCorner.tsx @@ -1,8 +1,8 @@ -import { THEME } from "@excalidraw/excalidraw/constants"; +import { THEME } from "@excalidraw/common"; import oc from "open-color"; import React from "react"; -import type { Theme } from "@excalidraw/excalidraw/element/types"; +import type { Theme } from "@excalidraw/element/types"; // https://github.com/tholman/github-corners export const GitHubCorner = React.memo( diff --git a/excalidraw-app/data/FileManager.ts b/excalidraw-app/data/FileManager.ts index 93d7ddec8c..5d134144fd 100644 --- a/excalidraw-app/data/FileManager.ts +++ b/excalidraw-app/data/FileManager.ts @@ -1,7 +1,7 @@ import { CaptureUpdateAction } from "@excalidraw/excalidraw"; import { compressData } from "@excalidraw/excalidraw/data/encode"; -import { newElementWith } from "@excalidraw/excalidraw/element/mutateElement"; -import { isInitializedImageElement } from "@excalidraw/excalidraw/element/typeChecks"; +import { newElementWith } from "@excalidraw/element/mutateElement"; +import { isInitializedImageElement } from "@excalidraw/element/typeChecks"; import { t } from "@excalidraw/excalidraw/i18n"; import type { @@ -9,7 +9,7 @@ import type { ExcalidrawImageElement, FileId, InitializedExcalidrawImageElement, -} from "@excalidraw/excalidraw/element/types"; +} from "@excalidraw/element/types"; import type { BinaryFileData, BinaryFileMetadata, diff --git a/excalidraw-app/data/LocalData.ts b/excalidraw-app/data/LocalData.ts index 6b53cc4826..9ad6dc9256 100644 --- a/excalidraw-app/data/LocalData.ts +++ b/excalidraw-app/data/LocalData.ts @@ -14,9 +14,9 @@ import { clearAppStateForLocalStorage } from "@excalidraw/excalidraw/appState"; import { CANVAS_SEARCH_TAB, DEFAULT_SIDEBAR, -} from "@excalidraw/excalidraw/constants"; -import { clearElementsForLocalStorage } from "@excalidraw/excalidraw/element"; -import { debounce } from "@excalidraw/excalidraw/utils"; + debounce, +} from "@excalidraw/common"; +import { clearElementsForLocalStorage } from "@excalidraw/element"; import { createStore, entries, @@ -29,16 +29,13 @@ import { import type { LibraryPersistedData } from "@excalidraw/excalidraw/data/library"; import type { ImportedDataState } from "@excalidraw/excalidraw/data/types"; -import type { - ExcalidrawElement, - FileId, -} from "@excalidraw/excalidraw/element/types"; +import type { ExcalidrawElement, FileId } from "@excalidraw/element/types"; import type { AppState, BinaryFileData, BinaryFiles, } from "@excalidraw/excalidraw/types"; -import type { MaybePromise } from "@excalidraw/excalidraw/utility-types"; +import type { MaybePromise } from "@excalidraw/common/utility-types"; import { SAVE_TO_LOCAL_STORAGE_TIMEOUT, STORAGE_KEYS } from "../app_constants"; diff --git a/excalidraw-app/data/firebase.ts b/excalidraw-app/data/firebase.ts index 66893b5133..568054f7ef 100644 --- a/excalidraw-app/data/firebase.ts +++ b/excalidraw-app/data/firebase.ts @@ -1,12 +1,12 @@ import { reconcileElements } from "@excalidraw/excalidraw"; -import { MIME_TYPES } from "@excalidraw/excalidraw/constants"; +import { MIME_TYPES } from "@excalidraw/common"; import { decompressData } from "@excalidraw/excalidraw/data/encode"; import { encryptData, decryptData, } from "@excalidraw/excalidraw/data/encryption"; import { restoreElements } from "@excalidraw/excalidraw/data/restore"; -import { getSceneVersion } from "@excalidraw/excalidraw/element"; +import { getSceneVersion } from "@excalidraw/element"; import { initializeApp } from "firebase/app"; import { getFirestore, @@ -22,7 +22,7 @@ import type { ExcalidrawElement, FileId, OrderedExcalidrawElement, -} from "@excalidraw/excalidraw/element/types"; +} from "@excalidraw/element/types"; import type { AppState, BinaryFileData, diff --git a/excalidraw-app/data/index.ts b/excalidraw-app/data/index.ts index e8fbc1f4dd..7bb0f9d8d7 100644 --- a/excalidraw-app/data/index.ts +++ b/excalidraw-app/data/index.ts @@ -9,26 +9,26 @@ import { } from "@excalidraw/excalidraw/data/encryption"; import { serializeAsJSON } from "@excalidraw/excalidraw/data/json"; import { restore } from "@excalidraw/excalidraw/data/restore"; -import { isInvisiblySmallElement } from "@excalidraw/excalidraw/element/sizeHelpers"; -import { isInitializedImageElement } from "@excalidraw/excalidraw/element/typeChecks"; +import { isInvisiblySmallElement } from "@excalidraw/element/sizeHelpers"; +import { isInitializedImageElement } from "@excalidraw/element/typeChecks"; import { t } from "@excalidraw/excalidraw/i18n"; -import { bytesToHexString } from "@excalidraw/excalidraw/utils"; +import { bytesToHexString } from "@excalidraw/common"; -import type { UserIdleState } from "@excalidraw/excalidraw/constants"; +import type { UserIdleState } from "@excalidraw/common"; import type { ImportedDataState } from "@excalidraw/excalidraw/data/types"; -import type { SceneBounds } from "@excalidraw/excalidraw/element/bounds"; +import type { SceneBounds } from "@excalidraw/element/bounds"; import type { ExcalidrawElement, FileId, OrderedExcalidrawElement, -} from "@excalidraw/excalidraw/element/types"; +} from "@excalidraw/element/types"; import type { AppState, BinaryFileData, BinaryFiles, SocketId, } from "@excalidraw/excalidraw/types"; -import type { MakeBrand } from "@excalidraw/excalidraw/utility-types"; +import type { MakeBrand } from "@excalidraw/common/utility-types"; import { DELETED_ELEMENT_TIMEOUT, diff --git a/excalidraw-app/data/localStorage.ts b/excalidraw-app/data/localStorage.ts index ac12064983..bc0df4a678 100644 --- a/excalidraw-app/data/localStorage.ts +++ b/excalidraw-app/data/localStorage.ts @@ -2,9 +2,9 @@ import { clearAppStateForLocalStorage, getDefaultAppState, } from "@excalidraw/excalidraw/appState"; -import { clearElementsForLocalStorage } from "@excalidraw/excalidraw/element"; +import { clearElementsForLocalStorage } from "@excalidraw/element"; -import type { ExcalidrawElement } from "@excalidraw/excalidraw/element/types"; +import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { AppState } from "@excalidraw/excalidraw/types"; import { STORAGE_KEYS } from "../app_constants"; diff --git a/excalidraw-app/share/ShareDialog.tsx b/excalidraw-app/share/ShareDialog.tsx index de77c60798..884d64680d 100644 --- a/excalidraw-app/share/ShareDialog.tsx +++ b/excalidraw-app/share/ShareDialog.tsx @@ -15,8 +15,7 @@ import { import { useUIAppState } from "@excalidraw/excalidraw/context/ui-appState"; import { useCopyStatus } from "@excalidraw/excalidraw/hooks/useCopiedIndicator"; import { useI18n } from "@excalidraw/excalidraw/i18n"; -import { KEYS } from "@excalidraw/excalidraw/keys"; -import { getFrame } from "@excalidraw/excalidraw/utils"; +import { KEYS, getFrame } from "@excalidraw/common"; import { useEffect, useRef, useState } from "react"; import { atom, useAtom, useAtomValue } from "../app-jotai"; diff --git a/excalidraw-app/tests/collab.test.tsx b/excalidraw-app/tests/collab.test.tsx index f6cd68fab7..3572303f43 100644 --- a/excalidraw-app/tests/collab.test.tsx +++ b/excalidraw-app/tests/collab.test.tsx @@ -3,7 +3,7 @@ import { createRedoAction, createUndoAction, } from "@excalidraw/excalidraw/actions/actionHistory"; -import { syncInvalidIndices } from "@excalidraw/excalidraw/fractionalIndex"; +import { syncInvalidIndices } from "@excalidraw/element/fractionalIndex"; import { API } from "@excalidraw/excalidraw/tests/helpers/api"; import { act, render, waitFor } from "@excalidraw/excalidraw/tests/test-utils"; import { vi } from "vitest"; diff --git a/excalidraw-app/useHandleAppTheme.ts b/excalidraw-app/useHandleAppTheme.ts index 6fc2ff54fa..94f5a3e58f 100644 --- a/excalidraw-app/useHandleAppTheme.ts +++ b/excalidraw-app/useHandleAppTheme.ts @@ -1,9 +1,8 @@ import { THEME } from "@excalidraw/excalidraw"; -import { EVENT } from "@excalidraw/excalidraw/constants"; -import { CODES, KEYS } from "@excalidraw/excalidraw/keys"; +import { EVENT, CODES, KEYS } from "@excalidraw/common"; import { useEffect, useLayoutEffect, useState } from "react"; -import type { Theme } from "@excalidraw/excalidraw/element/types"; +import type { Theme } from "@excalidraw/element/types"; import { STORAGE_KEYS } from "./app_constants"; diff --git a/excalidraw-app/vite.config.mts b/excalidraw-app/vite.config.mts index 57a4d19ecf..f10e742f5b 100644 --- a/excalidraw-app/vite.config.mts +++ b/excalidraw-app/vite.config.mts @@ -23,6 +23,22 @@ export default defineConfig(({ mode }) => { envDir: "../", resolve: { alias: [ + { + find: /^@excalidraw\/common$/, + replacement: path.resolve(__dirname, "../packages/common/src/index.ts"), + }, + { + find: /^@excalidraw\/common\/(.*?)/, + replacement: path.resolve(__dirname, "../packages/common/src/$1"), + }, + { + find: /^@excalidraw\/element$/, + replacement: path.resolve(__dirname, "../packages/element/src/index.ts"), + }, + { + find: /^@excalidraw\/element\/(.*?)/, + replacement: path.resolve(__dirname, "../packages/element/src/$1"), + }, { find: /^@excalidraw\/excalidraw$/, replacement: path.resolve(__dirname, "../packages/excalidraw/index.tsx"), @@ -31,21 +47,21 @@ export default defineConfig(({ mode }) => { find: /^@excalidraw\/excalidraw\/(.*?)/, replacement: path.resolve(__dirname, "../packages/excalidraw/$1"), }, - { - find: /^@excalidraw\/utils$/, - replacement: path.resolve(__dirname, "../packages/utils/index.ts"), - }, - { - find: /^@excalidraw\/utils\/(.*?)/, - replacement: path.resolve(__dirname, "../packages/utils/$1"), - }, { find: /^@excalidraw\/math$/, - replacement: path.resolve(__dirname, "../packages/math/index.ts"), + replacement: path.resolve(__dirname, "../packages/math/src/index.ts"), }, { find: /^@excalidraw\/math\/(.*?)/, - replacement: path.resolve(__dirname, "../packages/math/$1"), + replacement: path.resolve(__dirname, "../packages/math/src/$1"), + }, + { + find: /^@excalidraw\/utils$/, + replacement: path.resolve(__dirname, "../packages/utils/src/index.ts"), + }, + { + find: /^@excalidraw\/utils\/(.*?)/, + replacement: path.resolve(__dirname, "../packages/utils/src/$1"), }, ], }, diff --git a/package.json b/package.json index 9ff4379d18..6f57f7e7ca 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,7 @@ "packageManager": "yarn@1.22.22", "workspaces": [ "excalidraw-app", - "packages/excalidraw", - "packages/utils", - "packages/math", + "packages/*", "examples/*" ], "devDependencies": { diff --git a/packages/common/.eslintrc.json b/packages/common/.eslintrc.json new file mode 100644 index 0000000000..a31aaa1473 --- /dev/null +++ b/packages/common/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["../eslintrc.base.json"] +} diff --git a/packages/common/README.md b/packages/common/README.md new file mode 100644 index 0000000000..76435e6ff8 --- /dev/null +++ b/packages/common/README.md @@ -0,0 +1,19 @@ +# @excalidraw/common + +## Install + +```bash +npm install @excalidraw/common +``` + +If you prefer Yarn over npm, use this command to install the Excalidraw utils package: + +```bash +yarn add @excalidraw/common +``` + +With PNPM, similarly install the package with this command: + +```bash +pnpm add @excalidraw/common +``` diff --git a/packages/common/global.d.ts b/packages/common/global.d.ts new file mode 100644 index 0000000000..16ade7a7df --- /dev/null +++ b/packages/common/global.d.ts @@ -0,0 +1,3 @@ +/// +import "@excalidraw/excalidraw/global"; +import "@excalidraw/excalidraw/css"; diff --git a/packages/common/package.json b/packages/common/package.json new file mode 100644 index 0000000000..1632157cc7 --- /dev/null +++ b/packages/common/package.json @@ -0,0 +1,65 @@ +{ + "name": "@excalidraw/common", + "version": "0.1.0", + "type": "module", + "types": "./dist/types/common/index.d.ts", + "main": "./dist/prod/index.js", + "module": "./dist/prod/index.js", + "exports": { + ".": { + "types": "./dist/types/common/index.d.ts", + "development": "./dist/dev/index.js", + "production": "./dist/prod/index.js", + "default": "./dist/prod/index.js" + }, + "./*": { + "types": "./../common/dist/types/common/*" + } + }, + "files": [ + "dist/*" + ], + "description": "Excalidraw common functions, constants, etc.", + "publishConfig": { + "access": "public" + }, + "license": "MIT", + "keywords": [ + "excalidraw", + "excalidraw-utils" + ], + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not ie <= 11", + "not op_mini all", + "not safari < 12", + "not kaios <= 2.5", + "not edge < 79", + "not chrome < 70", + "not and_uc < 13", + "not samsung < 10" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "dependencies": { + "es6-promise-pool": "2.5.0", + "nanoid": "3.3.3", + "open-color": "1.9.1", + "roughjs": "4.6.4" + }, + "devDependencies": { + "typescript": "4.9.4" + }, + "bugs": "https://github.com/excalidraw/excalidraw/issues", + "repository": "https://github.com/excalidraw/excalidraw", + "scripts": { + "gen:types": "rm -rf types && tsc", + "build:esm": "rm -rf dist && node ../../scripts/buildBase.js && yarn gen:types" + } +} diff --git a/packages/excalidraw/binaryheap.ts b/packages/common/src/binary-heap.ts similarity index 98% rename from packages/excalidraw/binaryheap.ts rename to packages/common/src/binary-heap.ts index 0bacadceb8..788a05c223 100644 --- a/packages/excalidraw/binaryheap.ts +++ b/packages/common/src/binary-heap.ts @@ -1,4 +1,4 @@ -export default class BinaryHeap { +export class BinaryHeap { private content: T[] = []; constructor(private scoreFunction: (node: T) => number) {} diff --git a/packages/excalidraw/colors.ts b/packages/common/src/colors.ts similarity index 100% rename from packages/excalidraw/colors.ts rename to packages/common/src/colors.ts diff --git a/packages/excalidraw/constants.ts b/packages/common/src/constants.ts similarity index 98% rename from packages/excalidraw/constants.ts rename to packages/common/src/constants.ts index 88cddd5c55..31046f1ef7 100644 --- a/packages/excalidraw/constants.ts +++ b/packages/common/src/constants.ts @@ -1,7 +1,10 @@ -import { COLOR_PALETTE } from "./colors"; +import type { + ExcalidrawElement, + FontFamilyValues, +} from "@excalidraw/element/types"; +import type { AppProps, AppState } from "@excalidraw/excalidraw/types"; -import type { ExcalidrawElement, FontFamilyValues } from "./element/types"; -import type { AppProps, AppState } from "./types"; +import { COLOR_PALETTE } from "./colors"; export const isDarwin = /Mac|iPod|iPhone|iPad/.test(navigator.platform); export const isWindows = /^Win/.test(navigator.platform); diff --git a/packages/excalidraw/fonts/FontMetadata.ts b/packages/common/src/font-metadata.ts similarity index 76% rename from packages/excalidraw/fonts/FontMetadata.ts rename to packages/common/src/font-metadata.ts index e8b46205b5..de4cc57bf9 100644 --- a/packages/excalidraw/fonts/FontMetadata.ts +++ b/packages/common/src/font-metadata.ts @@ -1,12 +1,9 @@ -import { - FreedrawIcon, - FontFamilyNormalIcon, - FontFamilyHeadingIcon, - FontFamilyCodeIcon, -} from "../components/icons"; -import { FONT_FAMILY, FONT_FAMILY_FALLBACKS } from "../constants"; +import type { + ExcalidrawTextElement, + FontFamilyValues, +} from "@excalidraw/element/types"; -import type { JSX } from "react"; +import { FONT_FAMILY, FONT_FAMILY_FALLBACKS } from "./constants"; /** * Encapsulates font metrics with additional font metadata. @@ -23,8 +20,6 @@ export interface FontMetadata { /** harcoded unitless line-height, https://github.com/excalidraw/excalidraw/pull/6360#issuecomment-1477635971 */ lineHeight: number; }; - /** element to be displayed as an icon */ - icon?: JSX.Element; /** flag to indicate a deprecated font */ deprecated?: true; /** flag to indicate a server-side only font */ @@ -43,7 +38,6 @@ export const FONT_METADATA: Record = { descender: -374, lineHeight: 1.25, }, - icon: FreedrawIcon, }, [FONT_FAMILY.Nunito]: { metrics: { @@ -52,7 +46,6 @@ export const FONT_METADATA: Record = { descender: -353, lineHeight: 1.35, }, - icon: FontFamilyNormalIcon, }, [FONT_FAMILY["Lilita One"]]: { metrics: { @@ -61,7 +54,6 @@ export const FONT_METADATA: Record = { descender: -220, lineHeight: 1.15, }, - icon: FontFamilyHeadingIcon, }, [FONT_FAMILY["Comic Shanns"]]: { metrics: { @@ -70,7 +62,6 @@ export const FONT_METADATA: Record = { descender: -250, lineHeight: 1.25, }, - icon: FontFamilyCodeIcon, }, [FONT_FAMILY.Virgil]: { metrics: { @@ -79,7 +70,6 @@ export const FONT_METADATA: Record = { descender: -374, lineHeight: 1.25, }, - icon: FreedrawIcon, deprecated: true, }, [FONT_FAMILY.Helvetica]: { @@ -89,7 +79,6 @@ export const FONT_METADATA: Record = { descender: -471, lineHeight: 1.15, }, - icon: FontFamilyNormalIcon, deprecated: true, local: true, }, @@ -100,7 +89,6 @@ export const FONT_METADATA: Record = { descender: -480, lineHeight: 1.2, }, - icon: FontFamilyCodeIcon, deprecated: true, }, [FONT_FAMILY["Liberation Sans"]]: { @@ -149,3 +137,34 @@ export const GOOGLE_FONTS_RANGES = { /** local protocol to skip the local font from registering or inlining */ export const LOCAL_FONT_PROTOCOL = "local:"; + +/** + * Calculates vertical offset for a text with alphabetic baseline. + */ +export const getVerticalOffset = ( + fontFamily: ExcalidrawTextElement["fontFamily"], + fontSize: ExcalidrawTextElement["fontSize"], + lineHeightPx: number, +) => { + const { unitsPerEm, ascender, descender } = + FONT_METADATA[fontFamily]?.metrics || + FONT_METADATA[FONT_FAMILY.Excalifont].metrics; + + const fontSizeEm = fontSize / unitsPerEm; + const lineGap = + (lineHeightPx - fontSizeEm * ascender + fontSizeEm * descender) / 2; + + const verticalOffset = fontSizeEm * ascender + lineGap; + return verticalOffset; +}; + +/** + * Gets line height for a selected family. + */ +export const getLineHeight = (fontFamily: FontFamilyValues) => { + const { lineHeight } = + FONT_METADATA[fontFamily]?.metrics || + FONT_METADATA[FONT_FAMILY.Excalifont].metrics; + + return lineHeight as ExcalidrawTextElement["lineHeight"]; +}; diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts new file mode 100644 index 0000000000..d896ba98e5 --- /dev/null +++ b/packages/common/src/index.ts @@ -0,0 +1,11 @@ +export * from "./binary-heap"; +export * from "./colors"; +export * from "./constants"; +export * from "./font-metadata"; +export * from "./queue"; +export * from "./keys"; +export * from "./points"; +export * from "./promise-pool"; +export * from "./random"; +export * from "./url"; +export * from "./utils"; diff --git a/packages/excalidraw/keys.ts b/packages/common/src/keys.ts similarity index 100% rename from packages/excalidraw/keys.ts rename to packages/common/src/keys.ts diff --git a/packages/excalidraw/points.ts b/packages/common/src/points.ts similarity index 81% rename from packages/excalidraw/points.ts rename to packages/common/src/points.ts index 9d48857db0..e8f988203b 100644 --- a/packages/excalidraw/points.ts +++ b/packages/common/src/points.ts @@ -4,6 +4,8 @@ import { type LocalPoint, } from "@excalidraw/math"; +import type { NullableGridSize } from "@excalidraw/excalidraw/types"; + export const getSizeFromPoints = ( points: readonly (GlobalPoint | LocalPoint)[], ) => { @@ -61,3 +63,18 @@ export const rescalePoints = ( return nextPoints; }; + +// TODO: Rounding this point causes some shake when free drawing +export const getGridPoint = ( + x: number, + y: number, + gridSize: NullableGridSize, +): [number, number] => { + if (gridSize) { + return [ + Math.round(x / gridSize) * gridSize, + Math.round(y / gridSize) * gridSize, + ]; + } + return [x, y]; +}; diff --git a/packages/common/src/promise-pool.ts b/packages/common/src/promise-pool.ts new file mode 100644 index 0000000000..79d22d8afb --- /dev/null +++ b/packages/common/src/promise-pool.ts @@ -0,0 +1,50 @@ +import Pool from "es6-promise-pool"; + +// extending the missing types +// relying on the [Index, T] to keep a correct order +type TPromisePool = Pool<[Index, T][]> & { + addEventListener: ( + type: "fulfilled", + listener: (event: { data: { result: [Index, T] } }) => void, + ) => (event: { data: { result: [Index, T] } }) => void; + removeEventListener: ( + type: "fulfilled", + listener: (event: { data: { result: [Index, T] } }) => void, + ) => void; +}; + +export class PromisePool { + private readonly pool: TPromisePool; + private readonly entries: Record = {}; + + constructor( + source: IterableIterator>, + concurrency: number, + ) { + this.pool = new Pool( + source as unknown as () => void | PromiseLike<[number, T][]>, + concurrency, + ) as TPromisePool; + } + + public all() { + const listener = (event: { data: { result: void | [number, T] } }) => { + if (event.data.result) { + // by default pool does not return the results, so we are gathering them manually + // with the correct call order (represented by the index in the tuple) + const [index, value] = event.data.result; + this.entries[index] = value; + } + }; + + this.pool.addEventListener("fulfilled", listener); + + return this.pool.start().then(() => { + setTimeout(() => { + this.pool.removeEventListener("fulfilled", listener); + }); + + return Object.values(this.entries); + }); + } +} diff --git a/packages/excalidraw/queue.ts b/packages/common/src/queue.ts similarity index 90% rename from packages/excalidraw/queue.ts rename to packages/common/src/queue.ts index b7369e5e0b..2043f5e069 100644 --- a/packages/excalidraw/queue.ts +++ b/packages/common/src/queue.ts @@ -1,7 +1,8 @@ -import { promiseTry, resolvablePromise } from "./utils"; +import { promiseTry, resolvablePromise } from "."; + +import type { ResolvablePromise } from "."; import type { MaybePromise } from "./utility-types"; -import type { ResolvablePromise } from "./utils"; type Job = (...args: TArgs) => MaybePromise; diff --git a/packages/excalidraw/random.ts b/packages/common/src/random.ts similarity index 100% rename from packages/excalidraw/random.ts rename to packages/common/src/random.ts diff --git a/packages/excalidraw/data/url.ts b/packages/common/src/url.ts similarity index 94% rename from packages/excalidraw/data/url.ts rename to packages/common/src/url.ts index a758d233ea..eaa89633a7 100644 --- a/packages/excalidraw/data/url.ts +++ b/packages/common/src/url.ts @@ -1,6 +1,6 @@ import { sanitizeUrl } from "@braintree/sanitize-url"; -import { escapeDoubleQuotes } from "../utils"; +import { escapeDoubleQuotes } from "./utils"; export const normalizeLink = (link: string) => { link = link.trim(); diff --git a/packages/excalidraw/utility-types.ts b/packages/common/src/utility-types.ts similarity index 100% rename from packages/excalidraw/utility-types.ts rename to packages/common/src/utility-types.ts diff --git a/packages/excalidraw/utils.ts b/packages/common/src/utils.ts similarity index 94% rename from packages/excalidraw/utils.ts rename to packages/common/src/utils.ts index 18b6f2a93f..10837a02f8 100644 --- a/packages/excalidraw/utils.ts +++ b/packages/common/src/utils.ts @@ -1,30 +1,33 @@ import { average } from "@excalidraw/math"; -import Pool from "es6-promise-pool"; -import { COLOR_PALETTE } from "./colors"; -import { - DEFAULT_VERSION, - FONT_FAMILY, - getFontFamilyFallbacks, - isDarwin, - WINDOWS_EMOJI_FALLBACK_FONT, -} from "./constants"; - -import type { EVENT } from "./constants"; import type { ExcalidrawBindableElement, FontFamilyValues, FontString, -} from "./element/types"; +} from "@excalidraw/element/types"; + import type { ActiveTool, AppState, ToolType, UnsubscribeCallback, Zoom, -} from "./types"; +} from "@excalidraw/excalidraw/types"; + +import { COLOR_PALETTE } from "./colors"; +import { + DEFAULT_VERSION, + ENV, + FONT_FAMILY, + getFontFamilyFallbacks, + isDarwin, + WINDOWS_EMOJI_FALLBACK_FONT, +} from "./constants"; + import type { MaybePromise, ResolutionType } from "./utility-types"; +import type { EVENT } from "./constants"; + let mockDateTime: string | null = null; export const setDateTimeForTests = (dateTime: string) => { @@ -730,9 +733,9 @@ export const arrayToList = (array: readonly T[]): Node[] => return acc; }, [] as Node[]); -export const isTestEnv = () => import.meta.env.MODE === "test"; +export const isTestEnv = () => import.meta.env.MODE === ENV.TEST; -export const isDevEnv = () => import.meta.env.MODE === "development"; +export const isDevEnv = () => import.meta.env.MODE === ENV.DEVELOPMENT; export const isServerEnv = () => typeof process !== "undefined" && !!process?.env?.NODE_ENV; @@ -1186,54 +1189,6 @@ export const safelyParseJSON = (json: string): Record | null => { return null; } }; -// extending the missing types -// relying on the [Index, T] to keep a correct order -type TPromisePool = Pool<[Index, T][]> & { - addEventListener: ( - type: "fulfilled", - listener: (event: { data: { result: [Index, T] } }) => void, - ) => (event: { data: { result: [Index, T] } }) => void; - removeEventListener: ( - type: "fulfilled", - listener: (event: { data: { result: [Index, T] } }) => void, - ) => void; -}; - -export class PromisePool { - private readonly pool: TPromisePool; - private readonly entries: Record = {}; - - constructor( - source: IterableIterator>, - concurrency: number, - ) { - this.pool = new Pool( - source as unknown as () => void | PromiseLike<[number, T][]>, - concurrency, - ) as TPromisePool; - } - - public all() { - const listener = (event: { data: { result: void | [number, T] } }) => { - if (event.data.result) { - // by default pool does not return the results, so we are gathering them manually - // with the correct call order (represented by the index in the tuple) - const [index, value] = event.data.result; - this.entries[index] = value; - } - }; - - this.pool.addEventListener("fulfilled", listener); - - return this.pool.start().then(() => { - setTimeout(() => { - this.pool.removeEventListener("fulfilled", listener); - }); - - return Object.values(this.entries); - }); - } -} /** * use when you need to render unsafe string as HTML attribute, but MAKE SURE diff --git a/packages/excalidraw/keys.test.ts b/packages/common/tests/keys.test.ts similarity index 99% rename from packages/excalidraw/keys.test.ts rename to packages/common/tests/keys.test.ts index df2a36746b..bed2a0536b 100644 --- a/packages/excalidraw/keys.test.ts +++ b/packages/common/tests/keys.test.ts @@ -1,4 +1,4 @@ -import { KEYS, matchKey } from "./keys"; +import { KEYS, matchKey } from "../src/keys"; describe("key matcher", async () => { it("should not match unexpected key", async () => { diff --git a/packages/excalidraw/queue.test.ts b/packages/common/tests/queue.test.ts similarity index 97% rename from packages/excalidraw/queue.test.ts rename to packages/common/tests/queue.test.ts index 66a10583e1..d7623b3543 100644 --- a/packages/excalidraw/queue.test.ts +++ b/packages/common/tests/queue.test.ts @@ -1,4 +1,4 @@ -import { Queue } from "./queue"; +import { Queue } from "../src/queue"; describe("Queue", () => { const calls: any[] = []; diff --git a/packages/excalidraw/data/url.test.tsx b/packages/common/tests/url.test.tsx similarity index 96% rename from packages/excalidraw/data/url.test.tsx rename to packages/common/tests/url.test.tsx index 9a40aad048..b04423456f 100644 --- a/packages/excalidraw/data/url.test.tsx +++ b/packages/common/tests/url.test.tsx @@ -1,4 +1,4 @@ -import { normalizeLink } from "./url"; +import { normalizeLink } from "../src/url"; describe("normalizeLink", () => { // NOTE not an extensive XSS test suite, just to check if we're not diff --git a/packages/common/tsconfig.json b/packages/common/tsconfig.json new file mode 100644 index 0000000000..82cc2c2377 --- /dev/null +++ b/packages/common/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist/types" + } +} diff --git a/packages/element/.eslintrc.json b/packages/element/.eslintrc.json new file mode 100644 index 0000000000..a31aaa1473 --- /dev/null +++ b/packages/element/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["../eslintrc.base.json"] +} diff --git a/packages/element/README.md b/packages/element/README.md new file mode 100644 index 0000000000..9f003a9eaf --- /dev/null +++ b/packages/element/README.md @@ -0,0 +1,19 @@ +# @excalidraw/element + +## Install + +```bash +npm install @excalidraw/element +``` + +If you prefer Yarn over npm, use this command to install the Excalidraw utils package: + +```bash +yarn add @excalidraw/element +``` + +With PNPM, similarly install the package with this command: + +```bash +pnpm add @excalidraw/element +``` diff --git a/packages/element/global.d.ts b/packages/element/global.d.ts new file mode 100644 index 0000000000..16ade7a7df --- /dev/null +++ b/packages/element/global.d.ts @@ -0,0 +1,3 @@ +/// +import "@excalidraw/excalidraw/global"; +import "@excalidraw/excalidraw/css"; diff --git a/packages/element/package.json b/packages/element/package.json new file mode 100644 index 0000000000..dfb2f2af62 --- /dev/null +++ b/packages/element/package.json @@ -0,0 +1,63 @@ +{ + "name": "@excalidraw/element", + "version": "0.1.0", + "type": "module", + "types": "./dist/types/element/index.d.ts", + "main": "./dist/prod/index.js", + "module": "./dist/prod/index.js", + "exports": { + ".": { + "types": "./dist/types/element/index.d.ts", + "development": "./dist/dev/index.js", + "production": "./dist/prod/index.js", + "default": "./dist/prod/index.js" + }, + "./*": { + "types": "./../element/dist/types/element/*" + } + }, + "files": [ + "dist/*" + ], + "description": "Excalidraw elements-related logic", + "publishConfig": { + "access": "public" + }, + "license": "MIT", + "keywords": [ + "excalidraw", + "excalidraw-utils" + ], + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not ie <= 11", + "not op_mini all", + "not safari < 12", + "not kaios <= 2.5", + "not edge < 79", + "not chrome < 70", + "not and_uc < 13", + "not samsung < 10" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "dependencies": { + "fractional-indexing": "3.2.0", + "perfect-freehand": "1.2.0", + "points-on-curve": "1.0.1", + "roughjs": "4.6.4" + }, + "devDependencies": {}, + "bugs": "https://github.com/excalidraw/excalidraw/issues", + "repository": "https://github.com/excalidraw/excalidraw", + "scripts": { + "gen:types": "rm -rf types && tsc", + "build:esm": "rm -rf dist && node ../../scripts/buildBase.js && yarn gen:types" + } +} diff --git a/packages/excalidraw/scene/Shape.ts b/packages/element/src/Shape.ts similarity index 96% rename from packages/excalidraw/scene/Shape.ts rename to packages/element/src/Shape.ts index 64d90b7896..4def419574 100644 --- a/packages/excalidraw/scene/Shape.ts +++ b/packages/element/src/Shape.ts @@ -1,21 +1,26 @@ -import { pointFrom, pointDistance, type LocalPoint } from "@excalidraw/math"; import { simplify } from "points-on-curve"; -import { ROUGHNESS } from "../constants"; -import { getDiamondPoints, getArrowheadPoints } from "../element"; -import { headingForPointIsHorizontal } from "../element/heading"; +import { pointFrom, pointDistance, type LocalPoint } from "@excalidraw/math"; +import { ROUGHNESS, isTransparent, assertNever } from "@excalidraw/common"; + +import type { Mutable } from "@excalidraw/common/utility-types"; + +import type { EmbedsValidationStatus } from "@excalidraw/excalidraw/types"; +import type { ElementShapes } from "@excalidraw/excalidraw/scene/types"; + import { isElbowArrow, isEmbeddableElement, isIframeElement, isIframeLikeElement, isLinearElement, -} from "../element/typeChecks"; -import { generateFreeDrawShape } from "../renderer/renderElement"; -import { getCornerRadius, isPathALoop } from "../shapes"; -import { isTransparent, assertNever } from "../utils"; +} from "./typeChecks"; +import { getCornerRadius, isPathALoop } from "./shapes"; +import { headingForPointIsHorizontal } from "./heading"; import { canChangeRoundness } from "./comparisons"; +import { generateFreeDrawShape } from "./renderElement"; +import { getArrowheadPoints, getDiamondPoints } from "./bounds"; import type { ExcalidrawElement, @@ -23,9 +28,8 @@ import type { ExcalidrawSelectionElement, ExcalidrawLinearElement, Arrowhead, -} from "../element/types"; -import type { EmbedsValidationStatus } from "../types"; -import type { ElementShapes } from "./types"; +} from "./types"; + import type { Drawable, Options } from "roughjs/bin/core"; import type { RoughGenerator } from "roughjs/bin/generator"; import type { Point as RoughPoint } from "roughjs/bin/geometry"; @@ -511,7 +515,10 @@ export const _generateElementShape = ( if (isPathALoop(element.points)) { // generate rough polygon to fill freedraw shape - const simplifiedPoints = simplify(element.points, 0.75); + const simplifiedPoints = simplify( + element.points as Mutable, + 0.75, + ); shape = generator.curve(simplifiedPoints as [number, number][], { ...generateRoughOptions(element), stroke: "none", diff --git a/packages/excalidraw/scene/ShapeCache.ts b/packages/element/src/ShapeCache.ts similarity index 86% rename from packages/excalidraw/scene/ShapeCache.ts rename to packages/element/src/ShapeCache.ts index c170b0a809..8f0c94324c 100644 --- a/packages/excalidraw/scene/ShapeCache.ts +++ b/packages/element/src/ShapeCache.ts @@ -1,16 +1,22 @@ import { RoughGenerator } from "roughjs/bin/generator"; -import { COLOR_PALETTE } from "../colors"; -import { elementWithCanvasCache } from "../renderer/renderElement"; +import { COLOR_PALETTE } from "@excalidraw/common"; + +import type { + AppState, + EmbedsValidationStatus, +} from "@excalidraw/excalidraw/types"; +import type { + ElementShape, + ElementShapes, +} from "@excalidraw/excalidraw/scene/types"; import { _generateElementShape } from "./Shape"; -import type { - ExcalidrawElement, - ExcalidrawSelectionElement, -} from "../element/types"; -import type { AppState, EmbedsValidationStatus } from "../types"; -import type { ElementShape, ElementShapes } from "./types"; +import { elementWithCanvasCache } from "./renderElement"; + +import type { ExcalidrawElement, ExcalidrawSelectionElement } from "./types"; + import type { Drawable } from "roughjs/bin/core"; export class ShapeCache { diff --git a/packages/excalidraw/align.ts b/packages/element/src/align.ts similarity index 84% rename from packages/excalidraw/align.ts rename to packages/element/src/align.ts index 36e5d66035..61535b4348 100644 --- a/packages/excalidraw/align.ts +++ b/packages/element/src/align.ts @@ -1,11 +1,12 @@ -import { updateBoundElements } from "./element/binding"; -import { getCommonBoundingBox } from "./element/bounds"; -import { mutateElement } from "./element/mutateElement"; +import type Scene from "@excalidraw/excalidraw/scene/Scene"; + +import { updateBoundElements } from "./binding"; +import { getCommonBoundingBox } from "./bounds"; +import { mutateElement } from "./mutateElement"; import { getMaximumGroups } from "./groups"; -import type { BoundingBox } from "./element/bounds"; -import type { ElementsMap, ExcalidrawElement } from "./element/types"; -import type Scene from "./scene/Scene"; +import type { BoundingBox } from "./bounds"; +import type { ElementsMap, ExcalidrawElement } from "./types"; export interface Alignment { position: "start" | "center" | "end"; diff --git a/packages/excalidraw/element/binding.ts b/packages/element/src/binding.ts similarity index 99% rename from packages/excalidraw/element/binding.ts rename to packages/element/src/binding.ts index 6799d1a6b2..c84d80577c 100644 --- a/packages/excalidraw/element/binding.ts +++ b/packages/element/src/binding.ts @@ -1,3 +1,13 @@ +import { + KEYS, + arrayToMap, + isBindingFallthroughEnabled, + tupleToCoors, + invariant, + isDevEnv, + isTestEnv, +} from "@excalidraw/common"; + import { lineSegment, pointFrom, @@ -15,20 +25,16 @@ import { lineSegmentIntersectionPoints, PRECISION, } from "@excalidraw/math"; + import { isPointOnShape } from "@excalidraw/utils/collision"; import type { LocalPoint, Radians } from "@excalidraw/math"; -import { KEYS } from "../keys"; -import { aabbForElement, getElementShape, pointInsideBounds } from "../shapes"; -import { - arrayToMap, - invariant, - isBindingFallthroughEnabled, - isDevEnv, - isTestEnv, - tupleToCoors, -} from "../utils"; +import type Scene from "@excalidraw/excalidraw/scene/Scene"; + +import type { AppState } from "@excalidraw/excalidraw/types"; + +import type { Mutable } from "@excalidraw/common/utility-types"; import { getCenterForBounds, @@ -58,10 +64,9 @@ import { isTextElement, } from "./typeChecks"; +import { aabbForElement, getElementShape, pointInsideBounds } from "./shapes"; import { updateElbowArrowPoints } from "./elbowArrow"; -import type { Mutable } from "../utility-types"; - import type { Bounds } from "./bounds"; import type { ElementUpdate } from "./mutateElement"; import type { @@ -81,8 +86,6 @@ import type { SceneElementsMap, FixedPointBinding, } from "./types"; -import type Scene from "../scene/Scene"; -import type { AppState } from "../types"; export type SuggestedBinding = | NonDeleted diff --git a/packages/excalidraw/element/bounds.ts b/packages/element/src/bounds.ts similarity index 98% rename from packages/excalidraw/element/bounds.ts rename to packages/element/src/bounds.ts index 9d8fd22d37..bab1a1871f 100644 --- a/packages/excalidraw/element/bounds.ts +++ b/packages/element/src/bounds.ts @@ -1,3 +1,7 @@ +import rough from "roughjs/bin/rough"; + +import { rescalePoints, arrayToMap, invariant } from "@excalidraw/common"; + import { degreesToRadians, lineSegment, @@ -6,8 +10,8 @@ import { pointFromArray, pointRotateRads, } from "@excalidraw/math"; -import { getCurvePathOps } from "@excalidraw/utils/geometry/shape"; -import rough from "roughjs/bin/rough"; + +import { getCurvePathOps } from "@excalidraw/utils/shape"; import type { Degrees, @@ -17,11 +21,12 @@ import type { Radians, } from "@excalidraw/math"; -import { rescalePoints } from "../points"; -import { generateRoughOptions } from "../scene/Shape"; -import { ShapeCache } from "../scene/ShapeCache"; -import { arrayToMap, invariant } from "../utils"; +import type { AppState } from "@excalidraw/excalidraw/types"; +import type { Mutable } from "@excalidraw/common/utility-types"; + +import { ShapeCache } from "./ShapeCache"; +import { generateRoughOptions } from "./Shape"; import { LinearElementEditor } from "./linearElementEditor"; import { getBoundTextElement, getContainerElement } from "./textElement"; import { @@ -32,8 +37,6 @@ import { isTextElement, } from "./typeChecks"; -import type { AppState } from "../types"; -import type { Mutable } from "../utility-types"; import type { ExcalidrawElement, ExcalidrawLinearElement, diff --git a/packages/excalidraw/element/collision.ts b/packages/element/src/collision.ts similarity index 96% rename from packages/excalidraw/element/collision.ts rename to packages/element/src/collision.ts index 931b8c800d..0fabe98392 100644 --- a/packages/excalidraw/element/collision.ts +++ b/packages/element/src/collision.ts @@ -1,3 +1,4 @@ +import { isTransparent } from "@excalidraw/common"; import { curveIntersectLineSegment, isPointWithinBounds, @@ -8,12 +9,14 @@ import { pointRotateRads, pointsEqual, } from "@excalidraw/math"; + import { ellipse, ellipseLineIntersectionPoints, } from "@excalidraw/math/ellipse"; + import { isPointInShape, isPointOnShape } from "@excalidraw/utils/collision"; -import { getPolygonShape } from "@excalidraw/utils/geometry/shape"; +import { getPolygonShape } from "@excalidraw/utils/shape"; import type { GlobalPoint, @@ -22,11 +25,12 @@ import type { Polygon, Radians, } from "@excalidraw/math"; -import type { GeometricShape } from "@excalidraw/utils/geometry/shape"; -import { getBoundTextShape, isPathALoop } from "../shapes"; -import { isTransparent } from "../utils"; +import type { GeometricShape } from "@excalidraw/utils/shape"; +import type { FrameNameBounds } from "@excalidraw/excalidraw/types"; + +import { getBoundTextShape, isPathALoop } from "./shapes"; import { getElementBounds } from "./bounds"; import { hasBoundTextElement, @@ -47,7 +51,6 @@ import type { ExcalidrawRectangleElement, ExcalidrawRectanguloidElement, } from "./types"; -import type { FrameNameBounds } from "../types"; export const shouldTestInside = (element: ExcalidrawElement) => { if (element.type === "arrow") { diff --git a/packages/excalidraw/scene/comparisons.ts b/packages/element/src/comparisons.ts similarity index 94% rename from packages/excalidraw/scene/comparisons.ts rename to packages/element/src/comparisons.ts index 9af3e66cb6..75fac889dc 100644 --- a/packages/excalidraw/scene/comparisons.ts +++ b/packages/element/src/comparisons.ts @@ -1,4 +1,4 @@ -import type { ElementOrToolType } from "../types"; +import type { ElementOrToolType } from "@excalidraw/excalidraw/types"; export const hasBackground = (type: ElementOrToolType) => type === "rectangle" || diff --git a/packages/excalidraw/element/containerCache.ts b/packages/element/src/containerCache.ts similarity index 100% rename from packages/excalidraw/element/containerCache.ts rename to packages/element/src/containerCache.ts diff --git a/packages/excalidraw/element/cropElement.ts b/packages/element/src/cropElement.ts similarity index 100% rename from packages/excalidraw/element/cropElement.ts rename to packages/element/src/cropElement.ts diff --git a/packages/excalidraw/element/distance.ts b/packages/element/src/distance.ts similarity index 99% rename from packages/excalidraw/element/distance.ts rename to packages/element/src/distance.ts index 0382335556..d9db939e4d 100644 --- a/packages/excalidraw/element/distance.ts +++ b/packages/element/src/distance.ts @@ -4,6 +4,7 @@ import { pointFrom, pointRotateRads, } from "@excalidraw/math"; + import { ellipse, ellipseDistanceFromPoint } from "@excalidraw/math/ellipse"; import type { GlobalPoint, Radians } from "@excalidraw/math"; diff --git a/packages/excalidraw/distribute.ts b/packages/element/src/distribute.ts similarity index 92% rename from packages/excalidraw/distribute.ts rename to packages/element/src/distribute.ts index 767d3802c6..da79837da6 100644 --- a/packages/excalidraw/distribute.ts +++ b/packages/element/src/distribute.ts @@ -1,8 +1,9 @@ -import { getCommonBoundingBox } from "./element/bounds"; -import { newElementWith } from "./element/mutateElement"; +import { getCommonBoundingBox } from "./bounds"; +import { newElementWith } from "./mutateElement"; + import { getMaximumGroups } from "./groups"; -import type { ElementsMap, ExcalidrawElement } from "./element/types"; +import type { ElementsMap, ExcalidrawElement } from "./types"; export interface Distribution { space: "between"; diff --git a/packages/excalidraw/element/dragElements.ts b/packages/element/src/dragElements.ts similarity index 95% rename from packages/excalidraw/element/dragElements.ts rename to packages/element/src/dragElements.ts index e3a6a48b3c..669417a54e 100644 --- a/packages/excalidraw/element/dragElements.ts +++ b/packages/element/src/dragElements.ts @@ -1,6 +1,19 @@ -import { TEXT_AUTOWRAP_THRESHOLD } from "../constants"; -import { getGridPoint } from "../snapping"; -import { getFontString } from "../utils"; +import { + TEXT_AUTOWRAP_THRESHOLD, + getGridPoint, + getFontString, +} from "@excalidraw/common"; + +import type { + AppState, + NormalizedZoomValue, + NullableGridSize, + PointerDownState, +} from "@excalidraw/excalidraw/types"; + +import type Scene from "@excalidraw/excalidraw/scene/Scene"; + +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; import { updateBoundElements } from "./binding"; import { getCommonBounds } from "./bounds"; @@ -17,14 +30,7 @@ import { } from "./typeChecks"; import type { Bounds } from "./bounds"; -import type { ExcalidrawElement, NonDeletedExcalidrawElement } from "./types"; -import type Scene from "../scene/Scene"; -import type { - AppState, - NormalizedZoomValue, - NullableGridSize, - PointerDownState, -} from "../types"; +import type { ExcalidrawElement } from "./types"; export const dragSelectedElements = ( pointerDownState: PointerDownState, diff --git a/packages/excalidraw/element/duplicate.ts b/packages/element/src/duplicate.ts similarity index 98% rename from packages/excalidraw/element/duplicate.ts rename to packages/element/src/duplicate.ts index c126c57c9c..5b95f9085b 100644 --- a/packages/excalidraw/element/duplicate.ts +++ b/packages/element/src/duplicate.ts @@ -1,24 +1,28 @@ -import { ORIG_ID } from "../constants"; -import { - getElementsInGroup, - getNewGroupIdsForDuplication, - getSelectedGroupForElement, -} from "../groups"; - -import { randomId, randomInteger } from "../random"; - import { + ORIG_ID, + randomId, + randomInteger, arrayToMap, castArray, findLastIndex, getUpdatedTimestamp, isTestEnv, -} from "../utils"; +} from "@excalidraw/common"; + +import type { Mutable } from "@excalidraw/common/utility-types"; + +import type { AppState } from "@excalidraw/excalidraw/types"; + +import { + getElementsInGroup, + getNewGroupIdsForDuplication, + getSelectedGroupForElement, +} from "./groups"; import { bindElementsToFramesAfterDuplication, getFrameChildren, -} from "../frame"; +} from "./frame"; import { normalizeElementOrder } from "./sortElements"; @@ -34,9 +38,6 @@ import { getBoundTextElement, getContainerElement } from "./textElement"; import { fixBindingsAfterDuplication } from "./binding"; -import type { AppState } from "../types"; -import type { Mutable } from "../utility-types"; - import type { ElementsMap, ExcalidrawElement, diff --git a/packages/excalidraw/element/elbowArrow.ts b/packages/element/src/elbowArrow.ts similarity index 99% rename from packages/excalidraw/element/elbowArrow.ts rename to packages/element/src/elbowArrow.ts index c72357eb6f..a70e265bc6 100644 --- a/packages/excalidraw/element/elbowArrow.ts +++ b/packages/element/src/elbowArrow.ts @@ -13,10 +13,16 @@ import { type LocalPoint, } from "@excalidraw/math"; -import BinaryHeap from "../binaryheap"; -import { getSizeFromPoints } from "../points"; -import { aabbForElement, pointInsideBounds } from "../shapes"; -import { invariant, isAnyTrue, isDevEnv, tupleToCoors } from "../utils"; +import { + BinaryHeap, + invariant, + isAnyTrue, + tupleToCoors, + getSizeFromPoints, + isDevEnv, +} from "@excalidraw/common"; + +import type { AppState } from "@excalidraw/excalidraw/types"; import { bindPointToSnapToElementOutline, @@ -47,6 +53,8 @@ import { type SceneElementsMap, } from "./types"; +import { aabbForElement, pointInsideBounds } from "./shapes"; + import type { Bounds } from "./bounds"; import type { Heading } from "./heading"; import type { @@ -57,7 +65,6 @@ import type { FixedSegment, NonDeletedExcalidrawElement, } from "./types"; -import type { AppState } from "../types"; type GridAddress = [number, number] & { _brand: "gridaddress" }; diff --git a/packages/excalidraw/element/elementLink.ts b/packages/element/src/elementLink.ts similarity index 91% rename from packages/excalidraw/element/elementLink.ts rename to packages/element/src/elementLink.ts index 79b689c93b..8781e696d5 100644 --- a/packages/excalidraw/element/elementLink.ts +++ b/packages/element/src/elementLink.ts @@ -2,11 +2,12 @@ * Create and link between shapes. */ -import { ELEMENT_LINK_KEY } from "../constants"; -import { normalizeLink } from "../data/url"; -import { elementsAreInSameGroup } from "../groups"; +import { ELEMENT_LINK_KEY, normalizeLink } from "@excalidraw/common"; + +import type { AppProps, AppState } from "@excalidraw/excalidraw/types"; + +import { elementsAreInSameGroup } from "./groups"; -import type { AppProps, AppState } from "../types"; import type { ExcalidrawElement } from "./types"; export const defaultGetElementLinkFromSelection: Exclude< diff --git a/packages/excalidraw/element/embeddable.ts b/packages/element/src/embeddable.ts similarity index 91% rename from packages/excalidraw/element/embeddable.ts rename to packages/element/src/embeddable.ts index 1dc1968a07..e6d6b4af3e 100644 --- a/packages/excalidraw/element/embeddable.ts +++ b/packages/element/src/embeddable.ts @@ -1,15 +1,17 @@ -import { register } from "../actions/register"; -import { FONT_FAMILY, VERTICAL_ALIGN } from "../constants"; -import { setCursorForShape } from "../cursor"; -import { CaptureUpdateAction } from "../store"; -import { escapeDoubleQuotes, getFontString, updateActiveTool } from "../utils"; +import { + FONT_FAMILY, + VERTICAL_ALIGN, + escapeDoubleQuotes, + getFontString, +} from "@excalidraw/common"; + +import type { ExcalidrawProps } from "@excalidraw/excalidraw/types"; +import type { MarkRequired } from "@excalidraw/common/utility-types"; import { newTextElement } from "./newElement"; import { wrapText } from "./textWrapping"; import { isIframeElement } from "./typeChecks"; -import type { ExcalidrawProps } from "../types"; -import type { MarkRequired } from "../utility-types"; import type { ExcalidrawElement, ExcalidrawIframeLikeElement, @@ -319,34 +321,6 @@ export const createPlaceholderEmbeddableLabel = ( }); }; -export const actionSetEmbeddableAsActiveTool = register({ - name: "setEmbeddableAsActiveTool", - trackEvent: { category: "toolbar" }, - target: "Tool", - label: "toolBar.embeddable", - perform: (elements, appState, _, app) => { - const nextActiveTool = updateActiveTool(appState, { - type: "embeddable", - }); - - setCursorForShape(app.canvas, { - ...appState, - activeTool: nextActiveTool, - }); - - return { - elements, - appState: { - ...appState, - activeTool: updateActiveTool(appState, { - type: "embeddable", - }), - }, - captureUpdate: CaptureUpdateAction.EVENTUALLY, - }; - }, -}); - const matchHostname = ( url: string, /** using a Set assumes it already contains normalized bare domains */ diff --git a/packages/excalidraw/element/flowchart.ts b/packages/element/src/flowchart.ts similarity index 98% rename from packages/excalidraw/element/flowchart.ts rename to packages/element/src/flowchart.ts index 1790ef3f04..8ee2ba530a 100644 --- a/packages/excalidraw/element/flowchart.ts +++ b/packages/element/src/flowchart.ts @@ -1,9 +1,11 @@ +import { KEYS, invariant, toBrandedType } from "@excalidraw/common"; + import { type GlobalPoint, pointFrom, type LocalPoint } from "@excalidraw/math"; -import { elementOverlapsWithFrame, elementsAreInFrameBounds } from "../frame"; -import { KEYS } from "../keys"; -import { aabbForElement } from "../shapes"; -import { invariant, toBrandedType } from "../utils"; +import type { + AppState, + PendingExcalidrawElements, +} from "@excalidraw/excalidraw/types"; import { bindLinearElement } from "./binding"; import { updateElbowArrowPoints } from "./elbowArrow"; @@ -19,6 +21,8 @@ import { import { LinearElementEditor } from "./linearElementEditor"; import { mutateElement } from "./mutateElement"; import { newArrowElement, newElement } from "./newElement"; +import { aabbForElement } from "./shapes"; +import { elementsAreInFrameBounds, elementOverlapsWithFrame } from "./frame"; import { isBindableElement, isElbowArrow, @@ -35,8 +39,6 @@ import { type OrderedExcalidrawElement, } from "./types"; -import type { AppState, PendingExcalidrawElements } from "../types"; - type LinkDirection = "up" | "right" | "down" | "left"; const VERTICAL_OFFSET = 100; diff --git a/packages/excalidraw/fractionalIndex.ts b/packages/element/src/fractionalIndex.ts similarity index 97% rename from packages/excalidraw/fractionalIndex.ts rename to packages/element/src/fractionalIndex.ts index 8a1459ddda..bbe739f29a 100644 --- a/packages/excalidraw/fractionalIndex.ts +++ b/packages/element/src/fractionalIndex.ts @@ -1,16 +1,20 @@ import { generateNKeysBetween } from "fractional-indexing"; -import { mutateElement } from "./element/mutateElement"; -import { getBoundTextElement } from "./element/textElement"; -import { hasBoundTextElement } from "./element/typeChecks"; -import { InvalidFractionalIndexError } from "./errors"; -import { arrayToMap } from "./utils"; +import { arrayToMap } from "@excalidraw/common"; + +import { mutateElement } from "./mutateElement"; +import { getBoundTextElement } from "./textElement"; +import { hasBoundTextElement } from "./typeChecks"; import type { ExcalidrawElement, FractionalIndex, OrderedExcalidrawElement, -} from "./element/types"; +} from "./types"; + +export class InvalidFractionalIndexError extends Error { + public code = "ELEMENT_HAS_INVALID_INDEX" as const; +} /** * Envisioned relation between array order and fractional indices: diff --git a/packages/excalidraw/frame.ts b/packages/element/src/frame.ts similarity index 97% rename from packages/excalidraw/frame.ts rename to packages/element/src/frame.ts index 758bc273e5..7f40148b7a 100644 --- a/packages/excalidraw/frame.ts +++ b/packages/element/src/frame.ts @@ -1,24 +1,33 @@ +import { arrayToMap } from "@excalidraw/common"; import { isPointWithinBounds, pointFrom } from "@excalidraw/math"; -import { - doLineSegmentsIntersect, - elementsOverlappingBBox, -} from "@excalidraw/utils"; +import { doLineSegmentsIntersect } from "@excalidraw/utils/bbox"; +import { elementsOverlappingBBox } from "@excalidraw/utils/withinBounds"; + +import type { ExcalidrawElementsIncludingDeleted } from "@excalidraw/excalidraw/scene/Scene"; + +import type { + AppClassProperties, + AppState, + StaticCanvasAppState, +} from "@excalidraw/excalidraw/types"; + +import type { ReadonlySetLike } from "@excalidraw/common/utility-types"; + +import { getElementsWithinSelection, getSelectedElements } from "./selection"; +import { getElementsInGroup, selectGroupsFromGivenElements } from "./groups"; import { + getElementLineSegments, getCommonBounds, getElementAbsoluteCoords, - isTextElement, -} from "./element"; -import { getElementLineSegments } from "./element/bounds"; -import { mutateElement } from "./element/mutateElement"; +} from "./bounds"; +import { mutateElement } from "./mutateElement"; +import { getBoundTextElement, getContainerElement } from "./textElement"; import { - getBoundTextElement, - getContainerElement, -} from "./element/textElement"; -import { isFrameElement, isFrameLikeElement } from "./element/typeChecks"; -import { getElementsInGroup, selectGroupsFromGivenElements } from "./groups"; -import { getElementsWithinSelection, getSelectedElements } from "./scene"; -import { arrayToMap } from "./utils"; + isFrameElement, + isFrameLikeElement, + isTextElement, +} from "./typeChecks"; import type { ElementsMap, @@ -27,14 +36,7 @@ import type { ExcalidrawFrameLikeElement, NonDeleted, NonDeletedExcalidrawElement, -} from "./element/types"; -import type { ExcalidrawElementsIncludingDeleted } from "./scene/Scene"; -import type { - AppClassProperties, - AppState, - StaticCanvasAppState, } from "./types"; -import type { ReadonlySetLike } from "./utility-types"; // --------------------------- Frame State ------------------------------------ export const bindElementsToFramesAfterDuplication = ( diff --git a/packages/excalidraw/groups.ts b/packages/element/src/groups.ts similarity index 97% rename from packages/excalidraw/groups.ts rename to packages/element/src/groups.ts index 61b493fd40..1cd1536e11 100644 --- a/packages/excalidraw/groups.ts +++ b/packages/element/src/groups.ts @@ -1,6 +1,13 @@ -import { getBoundTextElement } from "./element/textElement"; -import { getSelectedElements } from "./scene"; -import { makeNextSelectedElementIds } from "./scene/selection"; +import type { + AppClassProperties, + AppState, + InteractiveCanvasAppState, +} from "@excalidraw/excalidraw/types"; +import type { Mutable } from "@excalidraw/common/utility-types"; + +import { getBoundTextElement } from "./textElement"; + +import { makeNextSelectedElementIds, getSelectedElements } from "./selection"; import type { GroupId, @@ -9,13 +16,7 @@ import type { NonDeletedExcalidrawElement, ElementsMapOrArray, ElementsMap, -} from "./element/types"; -import type { - AppClassProperties, - AppState, - InteractiveCanvasAppState, } from "./types"; -import type { Mutable } from "./utility-types"; export const selectGroup = ( groupId: GroupId, @@ -297,24 +298,6 @@ export const getSelectedGroupIdForElement = ( selectedGroupIds: { [groupId: string]: boolean }, ) => element.groupIds.find((groupId) => selectedGroupIds[groupId]); -export const getNewGroupIdsForDuplication = ( - groupIds: ExcalidrawElement["groupIds"], - editingGroupId: AppState["editingGroupId"], - mapper: (groupId: GroupId) => GroupId, -) => { - const copy = [...groupIds]; - const positionOfEditingGroupId = editingGroupId - ? groupIds.indexOf(editingGroupId) - : -1; - const endIndex = - positionOfEditingGroupId > -1 ? positionOfEditingGroupId : groupIds.length; - for (let index = 0; index < endIndex; index++) { - copy[index] = mapper(copy[index]); - } - - return copy; -}; - export const addToGroup = ( prevGroupIds: ExcalidrawElement["groupIds"], newGroupId: GroupId, @@ -401,3 +384,21 @@ export const elementsAreInSameGroup = ( export const isInGroup = (element: NonDeletedExcalidrawElement) => { return element.groupIds.length > 0; }; + +export const getNewGroupIdsForDuplication = ( + groupIds: ExcalidrawElement["groupIds"], + editingGroupId: AppState["editingGroupId"], + mapper: (groupId: GroupId) => GroupId, +) => { + const copy = [...groupIds]; + const positionOfEditingGroupId = editingGroupId + ? groupIds.indexOf(editingGroupId) + : -1; + const endIndex = + positionOfEditingGroupId > -1 ? positionOfEditingGroupId : groupIds.length; + for (let index = 0; index < endIndex; index++) { + copy[index] = mapper(copy[index]); + } + + return copy; +}; diff --git a/packages/excalidraw/element/heading.ts b/packages/element/src/heading.ts similarity index 100% rename from packages/excalidraw/element/heading.ts rename to packages/element/src/heading.ts diff --git a/packages/excalidraw/element/image.ts b/packages/element/src/image.ts similarity index 96% rename from packages/excalidraw/element/image.ts rename to packages/element/src/image.ts index 0d5f9fb5a0..562b489048 100644 --- a/packages/excalidraw/element/image.ts +++ b/packages/element/src/image.ts @@ -2,11 +2,16 @@ // ExcalidrawImageElement & related helpers // ----------------------------------------------------------------------------- -import { MIME_TYPES, SVG_NS } from "../constants"; +import { MIME_TYPES, SVG_NS } from "@excalidraw/common"; + +import type { + AppClassProperties, + DataURL, + BinaryFiles, +} from "@excalidraw/excalidraw/types"; import { isInitializedImageElement } from "./typeChecks"; -import type { AppClassProperties, DataURL, BinaryFiles } from "../types"; import type { ExcalidrawElement, FileId, diff --git a/packages/excalidraw/element/index.ts b/packages/element/src/index.ts similarity index 64% rename from packages/excalidraw/element/index.ts rename to packages/element/src/index.ts index 6244e2740c..d7edec8ae9 100644 --- a/packages/excalidraw/element/index.ts +++ b/packages/element/src/index.ts @@ -7,56 +7,6 @@ import type { NonDeleted, } from "./types"; -export { - newElement, - newTextElement, - refreshTextDimensions, - newLinearElement, - newArrowElement, - newImageElement, -} from "./newElement"; -export { duplicateElement } from "./duplicate"; -export { - getElementAbsoluteCoords, - getElementBounds, - getCommonBounds, - getDiamondPoints, - getArrowheadPoints, - getClosestElementBounds, -} from "./bounds"; - -export { - OMIT_SIDES_FOR_MULTIPLE_ELEMENTS, - getTransformHandlesFromCoords, - getTransformHandles, -} from "./transformHandles"; -export { - resizeTest, - getCursorForResizingElement, - getElementWithTransformHandleType, - getTransformHandleTypeFromCoords, -} from "./resizeTest"; -export { - transformElements, - getResizeOffsetXY, - getResizeArrowDirection, -} from "./resizeElements"; -export { - dragSelectedElements, - getDragOffsetXY, - dragNewElement, -} from "./dragElements"; -export { isTextElement, isExcalidrawElement } from "./typeChecks"; -export { redrawTextBoundingBox, getTextFromElements } from "./textElement"; -export { - getPerfectElementSize, - getLockedLinearCursorAlignSize, - isInvisiblySmallElement, - resizePerfectLineForNWHandler, - getNormalizedDimensions, -} from "./sizeHelpers"; -export { showSelectedShapeActions } from "./showSelectedShapeActions"; - /** * @deprecated unsafe, use hashElementsVersion instead */ diff --git a/packages/excalidraw/element/linearElementEditor.ts b/packages/element/src/linearElementEditor.ts similarity index 98% rename from packages/excalidraw/element/linearElementEditor.ts rename to packages/element/src/linearElementEditor.ts index adc4362369..bd4e740b23 100644 --- a/packages/excalidraw/element/linearElementEditor.ts +++ b/packages/element/src/linearElementEditor.ts @@ -8,34 +8,50 @@ import { pointDistance, vectorFromPoint, } from "@excalidraw/math"; -import { getCurvePathOps } from "@excalidraw/utils/geometry/shape"; + +import { getCurvePathOps } from "@excalidraw/utils/shape"; + +import { + DRAGGING_THRESHOLD, + KEYS, + shouldRotateWithDiscreteAngle, + getGridPoint, + invariant, + tupleToCoors, +} from "@excalidraw/common"; + +// TODO: remove direct dependency on the scene, should be passed in or injected instead +// eslint-disable-next-line @typescript-eslint/no-restricted-imports +import Scene from "@excalidraw/excalidraw/scene/Scene"; + +import type { Store } from "@excalidraw/excalidraw/store"; import type { Radians } from "@excalidraw/math"; -import { DRAGGING_THRESHOLD } from "../constants"; -import { KEYS, shouldRotateWithDiscreteAngle } from "../keys"; -import { ShapeCache } from "../scene/ShapeCache"; -import { - getBezierCurveLength, - getBezierXY, - getControlPointsForBezierCurve, - isPathALoop, - mapIntervalToBezierT, -} from "../shapes"; -import { getGridPoint } from "../snapping"; -import { invariant, tupleToCoors } from "../utils"; +import type { + AppState, + PointerCoords, + InteractiveCanvasAppState, + AppClassProperties, + NullableGridSize, + Zoom, +} from "@excalidraw/excalidraw/types"; -import Scene from "../scene/Scene"; +import type { Mutable } from "@excalidraw/common/utility-types"; import { bindOrUnbindLinearElement, getHoveredElementForBinding, isBindingEnabled, } from "./binding"; +import { + getElementAbsoluteCoords, + getElementPointsCoords, + getMinMaxXYFromCurvePathOps, +} from "./bounds"; import { updateElbowArrowPoints } from "./elbowArrow"; -import { getElementPointsCoords, getMinMaxXYFromCurvePathOps } from "./bounds"; import { headingIsHorizontal, vectorToHeading } from "./heading"; import { bumpVersion, mutateElement } from "./mutateElement"; import { getBoundTextElement, handleBindTextResize } from "./textElement"; @@ -45,7 +61,17 @@ import { isFixedPointBinding, } from "./typeChecks"; -import { getElementAbsoluteCoords, getLockedLinearCursorAlignSize } from "."; +import { ShapeCache } from "./ShapeCache"; + +import { + isPathALoop, + getBezierCurveLength, + getControlPointsForBezierCurve, + mapIntervalToBezierT, + getBezierXY, +} from "./shapes"; + +import { getLockedLinearCursorAlignSize } from "./sizeHelpers"; import type { Bounds } from "./bounds"; import type { @@ -62,17 +88,6 @@ import type { FixedSegment, ExcalidrawElbowArrowElement, } from "./types"; -import type { Store } from "../store"; -import type { - AppState, - PointerCoords, - InteractiveCanvasAppState, - AppClassProperties, - NullableGridSize, - Zoom, -} from "../types"; - -import type { Mutable } from "../utility-types"; const editorMidPointsCache: { version: number | null; diff --git a/packages/excalidraw/element/mutateElement.ts b/packages/element/src/mutateElement.ts similarity index 92% rename from packages/excalidraw/element/mutateElement.ts rename to packages/element/src/mutateElement.ts index fc96ec3127..d870073690 100644 --- a/packages/excalidraw/element/mutateElement.ts +++ b/packages/element/src/mutateElement.ts @@ -1,16 +1,24 @@ +import { + getSizeFromPoints, + randomInteger, + getUpdatedTimestamp, + toBrandedType, +} from "@excalidraw/common"; + +// TODO: remove direct dependency on the scene, should be passed in or injected instead +// eslint-disable-next-line @typescript-eslint/no-restricted-imports +import Scene from "@excalidraw/excalidraw/scene/Scene"; + import type { Radians } from "@excalidraw/math"; -import { getSizeFromPoints } from "../points"; -import { randomInteger } from "../random"; -import Scene from "../scene/Scene"; -import { ShapeCache } from "../scene/ShapeCache"; -import { getUpdatedTimestamp, toBrandedType } from "../utils"; +import type { Mutable } from "@excalidraw/common/utility-types"; + +import { ShapeCache } from "./ShapeCache"; import { updateElbowArrowPoints } from "./elbowArrow"; import { isElbowArrow } from "./typeChecks"; import type { ExcalidrawElement, NonDeletedSceneElementsMap } from "./types"; -import type { Mutable } from "../utility-types"; export type ElementUpdate = Omit< Partial, diff --git a/packages/excalidraw/element/newElement.ts b/packages/element/src/newElement.ts similarity index 97% rename from packages/excalidraw/element/newElement.ts rename to packages/element/src/newElement.ts index 67dbed0212..53a2f05aed 100644 --- a/packages/excalidraw/element/newElement.ts +++ b/packages/element/src/newElement.ts @@ -1,5 +1,3 @@ -import type { Radians } from "@excalidraw/math"; - import { DEFAULT_ELEMENT_PROPS, DEFAULT_FONT_FAMILY, @@ -7,20 +5,26 @@ import { DEFAULT_TEXT_ALIGN, DEFAULT_VERTICAL_ALIGN, VERTICAL_ALIGN, -} from "../constants"; -import { getLineHeight } from "../fonts"; -import { randomInteger, randomId } from "../random"; + randomInteger, + randomId, + getFontString, + getUpdatedTimestamp, + getLineHeight, +} from "@excalidraw/common"; -import { getFontString, getUpdatedTimestamp } from "../utils"; +import type { Radians } from "@excalidraw/math"; -import { getResizedElementAbsoluteCoords } from "./bounds"; +import type { MarkOptional, Merge } from "@excalidraw/common/utility-types"; + +import { + getElementAbsoluteCoords, + getResizedElementAbsoluteCoords, +} from "./bounds"; import { newElementWith } from "./mutateElement"; import { getBoundTextMaxWidth } from "./textElement"; import { normalizeText, measureText } from "./textMeasurements"; import { wrapText } from "./textWrapping"; -import { getElementAbsoluteCoords } from "."; - import type { ExcalidrawElement, ExcalidrawImageElement, @@ -43,7 +47,6 @@ import type { FixedSegment, ExcalidrawElbowArrowElement, } from "./types"; -import type { MarkOptional, Merge } from "../utility-types"; export type ElementConstructorOpts = MarkOptional< Omit, diff --git a/packages/excalidraw/renderer/renderElement.ts b/packages/element/src/renderElement.ts similarity index 97% rename from packages/excalidraw/renderer/renderElement.ts rename to packages/element/src/renderElement.ts index 9209c46d68..c8091e8edb 100644 --- a/packages/excalidraw/renderer/renderElement.ts +++ b/packages/element/src/renderElement.ts @@ -1,8 +1,8 @@ -import { isRightAngleRads } from "@excalidraw/math"; -import { getStroke } from "perfect-freehand"; import rough from "roughjs/bin/rough"; +import { getStroke } from "perfect-freehand"; + +import { isRightAngleRads } from "@excalidraw/math"; -import { getDefaultAppState } from "../appState"; import { BOUND_TEXT_PADDING, DEFAULT_REDUCED_GLOBAL_ALPHA, @@ -10,18 +10,39 @@ import { FRAME_STYLE, MIME_TYPES, THEME, -} from "../constants"; -import { getElementAbsoluteCoords } from "../element/bounds"; -import { getUncroppedImageElement } from "../element/cropElement"; -import { LinearElementEditor } from "../element/linearElementEditor"; + distance, + getFontString, + isRTL, + getVerticalOffset, +} from "@excalidraw/common"; + +import type { + AppState, + StaticCanvasAppState, + Zoom, + InteractiveCanvasAppState, + ElementsPendingErasure, + PendingExcalidrawElements, + NormalizedZoomValue, +} from "@excalidraw/excalidraw/types"; + +import type { + StaticCanvasRenderConfig, + RenderableElementsMap, + InteractiveCanvasRenderConfig, +} from "@excalidraw/excalidraw/scene/types"; + +import { getElementAbsoluteCoords } from "./bounds"; +import { getUncroppedImageElement } from "./cropElement"; +import { LinearElementEditor } from "./linearElementEditor"; import { getBoundTextElement, getContainerCoords, getContainerElement, getBoundTextMaxHeight, getBoundTextMaxWidth, -} from "../element/textElement"; -import { getLineHeightInPx } from "../element/textMeasurements"; +} from "./textElement"; +import { getLineHeightInPx } from "./textMeasurements"; import { isTextElement, isLinearElement, @@ -31,12 +52,11 @@ import { hasBoundTextElement, isMagicFrameElement, isImageElement, -} from "../element/typeChecks"; -import { getVerticalOffset } from "../fonts"; -import { getContainingFrame } from "../frame"; -import { ShapeCache } from "../scene/ShapeCache"; -import { getCornerRadius } from "../shapes"; -import { distance, getFontString, isRTL } from "../utils"; +} from "./typeChecks"; +import { getContainingFrame } from "./frame"; +import { getCornerRadius } from "./shapes"; + +import { ShapeCache } from "./ShapeCache"; import type { ExcalidrawElement, @@ -48,20 +68,8 @@ import type { ExcalidrawFrameLikeElement, NonDeletedSceneElementsMap, ElementsMap, -} from "../element/types"; -import type { - StaticCanvasRenderConfig, - RenderableElementsMap, - InteractiveCanvasRenderConfig, -} from "../scene/types"; -import type { - AppState, - StaticCanvasAppState, - Zoom, - InteractiveCanvasAppState, - ElementsPendingErasure, - PendingExcalidrawElements, -} from "../types"; +} from "./types"; + import type { StrokeOptions } from "perfect-freehand"; import type { RoughCanvas } from "roughjs/bin/canvas"; @@ -72,8 +80,6 @@ import type { RoughCanvas } from "roughjs/bin/canvas"; export const IMAGE_INVERT_FILTER = "invert(100%) hue-rotate(180deg) saturate(1.25)"; -const defaultAppState = getDefaultAppState(); - const isPendingImageElement = ( element: ExcalidrawElement, renderConfig: StaticCanvasRenderConfig, @@ -533,7 +539,11 @@ const generateElementWithCanvas = ( renderConfig: StaticCanvasRenderConfig, appState: StaticCanvasAppState, ) => { - const zoom: Zoom = renderConfig ? appState.zoom : defaultAppState.zoom; + const zoom: Zoom = renderConfig + ? appState.zoom + : { + value: 1 as NormalizedZoomValue, + }; const prevElementWithCanvas = elementWithCanvasCache.get(element); const shouldRegenerateBecauseZoom = prevElementWithCanvas && diff --git a/packages/excalidraw/element/resizeElements.ts b/packages/element/src/resizeElements.ts similarity index 99% rename from packages/excalidraw/element/resizeElements.ts rename to packages/element/src/resizeElements.ts index cd51b8bd55..3ff405603a 100644 --- a/packages/excalidraw/element/resizeElements.ts +++ b/packages/element/src/resizeElements.ts @@ -8,12 +8,20 @@ import { type LocalPoint, } from "@excalidraw/math"; +import { + MIN_FONT_SIZE, + SHIFT_LOCKING_ANGLE, + rescalePoints, + getFontString, +} from "@excalidraw/common"; + import type { GlobalPoint } from "@excalidraw/math"; -import { MIN_FONT_SIZE, SHIFT_LOCKING_ANGLE } from "../constants"; -import { isInGroup } from "../groups"; -import { rescalePoints } from "../points"; -import { getFontString } from "../utils"; +import type Scene from "@excalidraw/excalidraw/scene/Scene"; + +import type { PointerDownState } from "@excalidraw/excalidraw/types"; + +import type { Mutable } from "@excalidraw/common/utility-types"; import { getArrowLocalFixedPoints, updateBoundElements } from "./binding"; import { @@ -50,6 +58,8 @@ import { isTextElement, } from "./typeChecks"; +import { isInGroup } from "./groups"; + import type { BoundingBox } from "./bounds"; import type { MaybeTransformHandleType, @@ -67,9 +77,6 @@ import type { SceneElementsMap, ExcalidrawElbowArrowElement, } from "./types"; -import type Scene from "../scene/Scene"; -import type { PointerDownState } from "../types"; -import type { Mutable } from "../utility-types"; // Returns true when transform (resizing/rotation) happened export const transformElements = ( diff --git a/packages/excalidraw/element/resizeTest.ts b/packages/element/src/resizeTest.ts similarity index 98% rename from packages/excalidraw/element/resizeTest.ts rename to packages/element/src/resizeTest.ts index 1eb36d0b27..411dcf9a7b 100644 --- a/packages/excalidraw/element/resizeTest.ts +++ b/packages/element/src/resizeTest.ts @@ -5,9 +5,11 @@ import { type Radians, } from "@excalidraw/math"; +import { SIDE_RESIZING_THRESHOLD } from "@excalidraw/common"; + import type { GlobalPoint, LineSegment, LocalPoint } from "@excalidraw/math"; -import { SIDE_RESIZING_THRESHOLD } from "../constants"; +import type { AppState, Device, Zoom } from "@excalidraw/excalidraw/types"; import { getElementAbsoluteCoords } from "./bounds"; import { @@ -18,7 +20,6 @@ import { } from "./transformHandles"; import { isImageElement, isLinearElement } from "./typeChecks"; -import type { AppState, Device, Zoom } from "../types"; import type { Bounds } from "./bounds"; import type { TransformHandleType, diff --git a/packages/excalidraw/scene/selection.ts b/packages/element/src/selection.ts similarity index 94% rename from packages/excalidraw/scene/selection.ts rename to packages/element/src/selection.ts index 02f8f05e76..a767039208 100644 --- a/packages/excalidraw/scene/selection.ts +++ b/packages/element/src/selection.ts @@ -1,20 +1,25 @@ -import { getElementAbsoluteCoords, getElementBounds } from "../element"; -import { isElementInViewport } from "../element/sizeHelpers"; -import { isBoundToContainer, isFrameLikeElement } from "../element/typeChecks"; +import { isShallowEqual } from "@excalidraw/common"; + +import type { + AppState, + InteractiveCanvasAppState, +} from "@excalidraw/excalidraw/types"; + +import { getElementAbsoluteCoords, getElementBounds } from "./bounds"; +import { isElementInViewport } from "./sizeHelpers"; +import { isBoundToContainer, isFrameLikeElement } from "./typeChecks"; import { elementOverlapsWithFrame, getContainingFrame, getFrameChildren, -} from "../frame"; -import { isShallowEqual } from "../utils"; +} from "./frame"; import type { ElementsMap, ElementsMapOrArray, ExcalidrawElement, NonDeletedExcalidrawElement, -} from "../element/types"; -import type { AppState, InteractiveCanvasAppState } from "../types"; +} from "./types"; /** * Frames and their containing elements are not to be selected at the same time. diff --git a/packages/excalidraw/shapes.tsx b/packages/element/src/shapes.ts similarity index 81% rename from packages/excalidraw/shapes.tsx rename to packages/element/src/shapes.ts index b2c391a42e..1d6e13340f 100644 --- a/packages/excalidraw/shapes.tsx +++ b/packages/element/src/shapes.ts @@ -1,3 +1,10 @@ +import { + DEFAULT_ADAPTIVE_RADIUS, + DEFAULT_PROPORTIONAL_RADIUS, + LINE_CONFIRM_THRESHOLD, + ROUNDNESS, + invariant, +} from "@excalidraw/common"; import { isPoint, pointFrom, @@ -16,131 +23,26 @@ import { getFreedrawShape, getPolygonShape, type GeometricShape, -} from "@excalidraw/utils/geometry/shape"; +} from "@excalidraw/utils/shape"; -import { - ArrowIcon, - DiamondIcon, - EllipseIcon, - EraserIcon, - FreedrawIcon, - ImageIcon, - LineIcon, - RectangleIcon, - SelectionIcon, - TextIcon, -} from "./components/icons"; -import { - DEFAULT_ADAPTIVE_RADIUS, - DEFAULT_PROPORTIONAL_RADIUS, - LINE_CONFIRM_THRESHOLD, - ROUNDNESS, -} from "./constants"; -import { getElementAbsoluteCoords } from "./element"; -import { shouldTestInside } from "./element/collision"; -import { LinearElementEditor } from "./element/linearElementEditor"; -import { getBoundTextElement } from "./element/textElement"; -import { KEYS } from "./keys"; -import { ShapeCache } from "./scene/ShapeCache"; -import { invariant } from "./utils"; +import type { NormalizedZoomValue, Zoom } from "@excalidraw/excalidraw/types"; + +import { shouldTestInside } from "./collision"; +import { LinearElementEditor } from "./linearElementEditor"; +import { getBoundTextElement } from "./textElement"; +import { ShapeCache } from "./ShapeCache"; + +import { getElementAbsoluteCoords, type Bounds } from "./bounds"; -import type { Bounds } from "./element/bounds"; import type { ElementsMap, ExcalidrawElement, ExcalidrawLinearElement, NonDeleted, -} from "./element/types"; -import type { NormalizedZoomValue, Zoom } from "./types"; - -export const SHAPES = [ - { - icon: SelectionIcon, - value: "selection", - key: KEYS.V, - numericKey: KEYS["1"], - fillable: true, - }, - { - icon: RectangleIcon, - value: "rectangle", - key: KEYS.R, - numericKey: KEYS["2"], - fillable: true, - }, - { - icon: DiamondIcon, - value: "diamond", - key: KEYS.D, - numericKey: KEYS["3"], - fillable: true, - }, - { - icon: EllipseIcon, - value: "ellipse", - key: KEYS.O, - numericKey: KEYS["4"], - fillable: true, - }, - { - icon: ArrowIcon, - value: "arrow", - key: KEYS.A, - numericKey: KEYS["5"], - fillable: true, - }, - { - icon: LineIcon, - value: "line", - key: KEYS.L, - numericKey: KEYS["6"], - fillable: true, - }, - { - icon: FreedrawIcon, - value: "freedraw", - key: [KEYS.P, KEYS.X], - numericKey: KEYS["7"], - fillable: false, - }, - { - icon: TextIcon, - value: "text", - key: KEYS.T, - numericKey: KEYS["8"], - fillable: false, - }, - { - icon: ImageIcon, - value: "image", - key: null, - numericKey: KEYS["9"], - fillable: false, - }, - { - icon: EraserIcon, - value: "eraser", - key: KEYS.E, - numericKey: KEYS["0"], - fillable: false, - }, -] as const; - -export const findShapeByKey = (key: string) => { - const shape = SHAPES.find((shape, index) => { - return ( - (shape.numericKey != null && key === shape.numericKey.toString()) || - (shape.key && - (typeof shape.key === "string" - ? shape.key === key - : (shape.key as readonly string[]).includes(key))) - ); - }); - return shape?.value || null; -}; +} from "./types"; /** - * get the pure geometric shape of an excalidraw element + * get the pure geometric shape of an excalidraw elementw * which is then used for hit detection */ export const getElementShape = ( diff --git a/packages/excalidraw/element/showSelectedShapeActions.ts b/packages/element/src/showSelectedShapeActions.ts similarity index 84% rename from packages/excalidraw/element/showSelectedShapeActions.ts rename to packages/element/src/showSelectedShapeActions.ts index 44c2e75c33..efcf83894a 100644 --- a/packages/excalidraw/element/showSelectedShapeActions.ts +++ b/packages/element/src/showSelectedShapeActions.ts @@ -1,6 +1,7 @@ -import { getSelectedElements } from "../scene"; +import type { UIAppState } from "@excalidraw/excalidraw/types"; + +import { getSelectedElements } from "./selection"; -import type { UIAppState } from "../types"; import type { NonDeletedExcalidrawElement } from "./types"; export const showSelectedShapeActions = ( diff --git a/packages/excalidraw/element/sizeHelpers.ts b/packages/element/src/sizeHelpers.ts similarity index 97% rename from packages/excalidraw/element/sizeHelpers.ts rename to packages/element/src/sizeHelpers.ts index 33b13e1887..7a84dadba4 100644 --- a/packages/excalidraw/element/sizeHelpers.ts +++ b/packages/element/src/sizeHelpers.ts @@ -1,12 +1,15 @@ -import { SHIFT_LOCKING_ANGLE } from "../constants"; -import { viewportCoordsToSceneCoords } from "../utils"; +import { + SHIFT_LOCKING_ANGLE, + viewportCoordsToSceneCoords, +} from "@excalidraw/common"; + +import type { AppState, Offsets, Zoom } from "@excalidraw/excalidraw/types"; import { getCommonBounds, getElementBounds } from "./bounds"; import { mutateElement } from "./mutateElement"; import { isFreeDrawElement, isLinearElement } from "./typeChecks"; import type { ElementsMap, ExcalidrawElement } from "./types"; -import type { AppState, Offsets, Zoom } from "../types"; // TODO: remove invisible elements consistently actions, so that invisible elements are not recorded by the store, exported, broadcasted or persisted // - perhaps could be as part of a standalone 'cleanup' action, in addition to 'finalize' diff --git a/packages/excalidraw/element/sortElements.ts b/packages/element/src/sortElements.ts similarity index 98% rename from packages/excalidraw/element/sortElements.ts rename to packages/element/src/sortElements.ts index d395adf2f6..c98ff9d523 100644 --- a/packages/excalidraw/element/sortElements.ts +++ b/packages/element/src/sortElements.ts @@ -1,4 +1,4 @@ -import { arrayToMapWithIndex } from "../utils"; +import { arrayToMapWithIndex } from "@excalidraw/common"; import type { ExcalidrawElement } from "./types"; diff --git a/packages/excalidraw/element/textElement.ts b/packages/element/src/textElement.ts similarity index 98% rename from packages/excalidraw/element/textElement.ts rename to packages/element/src/textElement.ts index b8399f0385..ea27c318fd 100644 --- a/packages/excalidraw/element/textElement.ts +++ b/packages/element/src/textElement.ts @@ -5,8 +5,12 @@ import { DEFAULT_FONT_SIZE, TEXT_ALIGN, VERTICAL_ALIGN, -} from "../constants"; -import { getFontString } from "../utils"; + getFontString, +} from "@excalidraw/common"; + +import type { AppState } from "@excalidraw/excalidraw/types"; + +import type { ExtractSetType } from "@excalidraw/common/utility-types"; import { resetOriginalContainerCache, @@ -16,9 +20,11 @@ import { LinearElementEditor } from "./linearElementEditor"; import { mutateElement } from "./mutateElement"; import { measureText } from "./textMeasurements"; import { wrapText } from "./textWrapping"; -import { isBoundToContainer, isArrowElement } from "./typeChecks"; - -import { isTextElement } from "."; +import { + isBoundToContainer, + isArrowElement, + isTextElement, +} from "./typeChecks"; import type { MaybeTransformHandleType } from "./transformHandles"; import type { @@ -30,8 +36,6 @@ import type { ExcalidrawTextElementWithContainer, NonDeletedExcalidrawElement, } from "./types"; -import type { AppState } from "../types"; -import type { ExtractSetType } from "../utility-types"; export const redrawTextBoundingBox = ( textElement: ExcalidrawTextElement, diff --git a/packages/excalidraw/element/textMeasurements.ts b/packages/element/src/textMeasurements.ts similarity index 98% rename from packages/excalidraw/element/textMeasurements.ts rename to packages/element/src/textMeasurements.ts index 840896cfcc..5e790261d1 100644 --- a/packages/excalidraw/element/textMeasurements.ts +++ b/packages/element/src/textMeasurements.ts @@ -2,8 +2,10 @@ import { BOUND_TEXT_PADDING, DEFAULT_FONT_SIZE, DEFAULT_FONT_FAMILY, -} from "../constants"; -import { getFontString, isTestEnv, normalizeEOL } from "../utils"; + getFontString, + isTestEnv, + normalizeEOL, +} from "@excalidraw/common"; import type { FontString, ExcalidrawTextElement } from "./types"; diff --git a/packages/excalidraw/element/textWrapping.ts b/packages/element/src/textWrapping.ts similarity index 99% rename from packages/excalidraw/element/textWrapping.ts rename to packages/element/src/textWrapping.ts index 4585b52c32..5ec9bb42a9 100644 --- a/packages/excalidraw/element/textWrapping.ts +++ b/packages/element/src/textWrapping.ts @@ -1,4 +1,4 @@ -import { isDevEnv, isTestEnv } from "../utils"; +import { isDevEnv, isTestEnv } from "@excalidraw/common"; import { charWidth, getLineWidth } from "./textMeasurements"; diff --git a/packages/excalidraw/element/transformHandles.ts b/packages/element/src/transformHandles.ts similarity index 98% rename from packages/excalidraw/element/transformHandles.ts rename to packages/element/src/transformHandles.ts index ab5691df8c..f2b0cd2782 100644 --- a/packages/excalidraw/element/transformHandles.ts +++ b/packages/element/src/transformHandles.ts @@ -1,12 +1,18 @@ -import { pointFrom, pointRotateRads } from "@excalidraw/math"; - -import type { Radians } from "@excalidraw/math"; - import { DEFAULT_TRANSFORM_HANDLE_SPACING, isAndroid, isIOS, -} from "../constants"; +} from "@excalidraw/common"; + +import { pointFrom, pointRotateRads } from "@excalidraw/math"; + +import type { Radians } from "@excalidraw/math"; + +import type { + Device, + InteractiveCanvasAppState, + Zoom, +} from "@excalidraw/excalidraw/types"; import { getElementAbsoluteCoords } from "./bounds"; import { @@ -16,7 +22,6 @@ import { isLinearElement, } from "./typeChecks"; -import type { Device, InteractiveCanvasAppState, Zoom } from "../types"; import type { Bounds } from "./bounds"; import type { ElementsMap, diff --git a/packages/excalidraw/element/typeChecks.ts b/packages/element/src/typeChecks.ts similarity index 97% rename from packages/excalidraw/element/typeChecks.ts rename to packages/element/src/typeChecks.ts index 77ac38f9d9..54619726df 100644 --- a/packages/excalidraw/element/typeChecks.ts +++ b/packages/element/src/typeChecks.ts @@ -1,8 +1,9 @@ -import { ROUNDNESS } from "../constants"; -import { assertNever } from "../utils"; +import { ROUNDNESS, assertNever } from "@excalidraw/common"; + +import type { ElementOrToolType } from "@excalidraw/excalidraw/types"; + +import type { MarkNonNullable } from "@excalidraw/common/utility-types"; -import type { ElementOrToolType } from "../types"; -import type { MarkNonNullable } from "../utility-types"; import type { Bounds } from "./bounds"; import type { ExcalidrawElement, diff --git a/packages/excalidraw/element/types.ts b/packages/element/src/types.ts similarity index 99% rename from packages/excalidraw/element/types.ts rename to packages/element/src/types.ts index 49ad800afe..3b40135d5e 100644 --- a/packages/excalidraw/element/types.ts +++ b/packages/element/src/types.ts @@ -6,13 +6,14 @@ import type { TEXT_ALIGN, THEME, VERTICAL_ALIGN, -} from "../constants"; +} from "@excalidraw/common"; + import type { MakeBrand, MarkNonNullable, Merge, ValueOf, -} from "../utility-types"; +} from "@excalidraw/common/utility-types"; export type ChartType = "bar" | "line"; export type FillStyle = "hachure" | "cross-hatch" | "solid" | "zigzag"; diff --git a/packages/excalidraw/element/utils.ts b/packages/element/src/utils.ts similarity index 99% rename from packages/excalidraw/element/utils.ts rename to packages/element/src/utils.ts index 8992850dc6..7042b5d8f1 100644 --- a/packages/excalidraw/element/utils.ts +++ b/packages/element/src/utils.ts @@ -12,9 +12,9 @@ import { import type { Curve, LineSegment } from "@excalidraw/math"; -import { getCornerRadius } from "../shapes"; +import { getCornerRadius } from "./shapes"; -import { getDiamondPoints } from "."; +import { getDiamondPoints } from "./bounds"; import type { ExcalidrawDiamondElement, diff --git a/packages/excalidraw/zindex.ts b/packages/element/src/zindex.ts similarity index 92% rename from packages/excalidraw/zindex.ts rename to packages/element/src/zindex.ts index 8ffcec5d17..e09142e4a0 100644 --- a/packages/excalidraw/zindex.ts +++ b/packages/element/src/zindex.ts @@ -1,15 +1,18 @@ -import { isFrameLikeElement } from "./element/typeChecks"; -import { syncMovedIndices } from "./fractionalIndex"; -import { getElementsInGroup } from "./groups"; -import { getSelectedElements } from "./scene"; -import Scene from "./scene/Scene"; -import { arrayToMap, findIndex, findLastIndex } from "./utils"; +import { arrayToMap, findIndex, findLastIndex } from "@excalidraw/common"; -import type { - ExcalidrawElement, - ExcalidrawFrameLikeElement, -} from "./element/types"; -import type { AppState } from "./types"; +import type { AppState } from "@excalidraw/excalidraw/types"; + +import type Scene from "@excalidraw/excalidraw/scene/Scene"; + +import { isFrameLikeElement } from "./typeChecks"; + +import { getElementsInGroup } from "./groups"; + +import { syncMovedIndices } from "./fractionalIndex"; + +import { getSelectedElements } from "./selection"; + +import type { ExcalidrawElement, ExcalidrawFrameLikeElement } from "./types"; const isOfTargetFrame = (element: ExcalidrawElement, frameId: string) => { return element.frameId === frameId || element.id === frameId; @@ -79,11 +82,11 @@ const getTargetIndexAccountingForBinding = ( nextElement: ExcalidrawElement, elements: readonly ExcalidrawElement[], direction: "left" | "right", + scene: Scene, ) => { if ("containerId" in nextElement && nextElement.containerId) { - const containerElement = Scene.getScene(nextElement)!.getElement( - nextElement.containerId, - ); + // TODO: why not to get the container from the nextElements? + const containerElement = scene.getElement(nextElement.containerId); if (containerElement) { return direction === "left" ? Math.min( @@ -100,8 +103,7 @@ const getTargetIndexAccountingForBinding = ( (binding) => binding.type !== "arrow", )?.id; if (boundElementId) { - const boundTextElement = - Scene.getScene(nextElement)!.getElement(boundElementId); + const boundTextElement = scene.getElement(boundElementId); if (boundTextElement) { return direction === "left" ? Math.min( @@ -151,6 +153,7 @@ const getTargetIndex = ( * If whole frame (including all children) is being moved, supply `null`. */ containingFrame: ExcalidrawFrameLikeElement["id"] | null, + scene: Scene, ) => { const sourceElement = elements[boundaryIndex]; @@ -190,8 +193,12 @@ const getTargetIndex = ( sourceElement?.groupIds.join("") === nextElement?.groupIds.join("") ) { return ( - getTargetIndexAccountingForBinding(nextElement, elements, direction) ?? - candidateIndex + getTargetIndexAccountingForBinding( + nextElement, + elements, + direction, + scene, + ) ?? candidateIndex ); } else if (!nextElement?.groupIds.includes(appState.editingGroupId)) { // candidate element is outside current editing group → prevent @@ -214,8 +221,12 @@ const getTargetIndex = ( if (!nextElement.groupIds.length) { return ( - getTargetIndexAccountingForBinding(nextElement, elements, direction) ?? - candidateIndex + getTargetIndexAccountingForBinding( + nextElement, + elements, + direction, + scene, + ) ?? candidateIndex ); } @@ -255,6 +266,7 @@ const shiftElementsByOne = ( elements: readonly ExcalidrawElement[], appState: AppState, direction: "left" | "right", + scene: Scene, ) => { const indicesToMove = getIndicesToMove(elements, appState); const targetElementsMap = getTargetElementsMap(elements, indicesToMove); @@ -289,6 +301,7 @@ const shiftElementsByOne = ( boundaryIndex, direction, containingFrame, + scene, ); if (targetIndex === -1 || boundaryIndex === targetIndex) { @@ -502,15 +515,17 @@ function shiftElementsAccountingForFrames( export const moveOneLeft = ( allElements: readonly ExcalidrawElement[], appState: AppState, + scene: Scene, ) => { - return shiftElementsByOne(allElements, appState, "left"); + return shiftElementsByOne(allElements, appState, "left", scene); }; export const moveOneRight = ( allElements: readonly ExcalidrawElement[], appState: AppState, + scene: Scene, ) => { - return shiftElementsByOne(allElements, appState, "right"); + return shiftElementsByOne(allElements, appState, "right", scene); }; export const moveAllLeft = ( diff --git a/packages/excalidraw/tests/align.test.tsx b/packages/element/tests/align.test.tsx similarity index 97% rename from packages/excalidraw/tests/align.test.tsx rename to packages/element/tests/align.test.tsx index d29e497ece..2dcafc65b8 100644 --- a/packages/excalidraw/tests/align.test.tsx +++ b/packages/element/tests/align.test.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import { KEYS } from "@excalidraw/common"; import { actionAlignVerticallyCentered, @@ -8,14 +8,17 @@ import { actionAlignBottom, actionAlignLeft, actionAlignRight, -} from "../actions"; -import { defaultLang, setLanguage } from "../i18n"; -import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; +} from "@excalidraw/excalidraw/actions"; +import { defaultLang, setLanguage } from "@excalidraw/excalidraw/i18n"; +import { Excalidraw } from "@excalidraw/excalidraw"; -import { API } from "./helpers/api"; -import { UI, Pointer, Keyboard } from "./helpers/ui"; -import { act, unmountComponent, render } from "./test-utils"; +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; +import { UI, Pointer, Keyboard } from "@excalidraw/excalidraw/tests/helpers/ui"; +import { + act, + unmountComponent, + render, +} from "@excalidraw/excalidraw/tests/test-utils"; const mouse = new Pointer("mouse"); diff --git a/packages/excalidraw/tests/binding.test.tsx b/packages/element/tests/binding.test.tsx similarity index 96% rename from packages/excalidraw/tests/binding.test.tsx rename to packages/element/tests/binding.test.tsx index 1c50062c17..f57d7793ae 100644 --- a/packages/excalidraw/tests/binding.test.tsx +++ b/packages/element/tests/binding.test.tsx @@ -1,15 +1,16 @@ +import { KEYS, arrayToMap } from "@excalidraw/common"; + import { pointFrom } from "@excalidraw/math"; -import React from "react"; -import { actionWrapTextInContainer } from "../actions/actionBoundText"; -import { getTransformHandles } from "../element/transformHandles"; -import { Excalidraw, isLinearElement } from "../index"; -import { KEYS } from "../keys"; -import { arrayToMap } from "../utils"; +import { actionWrapTextInContainer } from "@excalidraw/excalidraw/actions/actionBoundText"; -import { API } from "./helpers/api"; -import { UI, Pointer, Keyboard } from "./helpers/ui"; -import { fireEvent, render } from "./test-utils"; +import { Excalidraw, isLinearElement } from "@excalidraw/excalidraw"; + +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; +import { UI, Pointer, Keyboard } from "@excalidraw/excalidraw/tests/helpers/ui"; +import { fireEvent, render } from "@excalidraw/excalidraw/tests/test-utils"; + +import { getTransformHandles } from "../src/transformHandles"; const { h } = window; diff --git a/packages/excalidraw/element/bounds.test.ts b/packages/element/tests/bounds.test.ts similarity index 95% rename from packages/excalidraw/element/bounds.test.ts rename to packages/element/tests/bounds.test.ts index 936ebf797b..22c669f28a 100644 --- a/packages/excalidraw/element/bounds.test.ts +++ b/packages/element/tests/bounds.test.ts @@ -1,13 +1,12 @@ import { pointFrom } from "@excalidraw/math"; +import { arrayToMap, ROUNDNESS } from "@excalidraw/common"; + import type { LocalPoint } from "@excalidraw/math"; -import { ROUNDNESS } from "../constants"; -import { arrayToMap } from "../utils"; +import { getElementAbsoluteCoords, getElementBounds } from "../src/bounds"; -import { getElementAbsoluteCoords, getElementBounds } from "./bounds"; - -import type { ExcalidrawElement, ExcalidrawLinearElement } from "./types"; +import type { ExcalidrawElement, ExcalidrawLinearElement } from "../src/types"; const _ce = ({ x, diff --git a/packages/excalidraw/element/duplicate.test.tsx b/packages/element/tests/duplicate.test.tsx similarity index 96% rename from packages/excalidraw/element/duplicate.test.tsx rename to packages/element/tests/duplicate.test.tsx index 8e070ff980..d3b5cee963 100644 --- a/packages/excalidraw/element/duplicate.test.tsx +++ b/packages/element/tests/duplicate.test.tsx @@ -1,28 +1,34 @@ import React from "react"; import { pointFrom } from "@excalidraw/math"; -import type { LocalPoint } from "@excalidraw/math"; +import { + FONT_FAMILY, + ORIG_ID, + ROUNDNESS, + isPrimitive, +} from "@excalidraw/common"; -import { FONT_FAMILY, ORIG_ID, ROUNDNESS } from "../constants"; -import { API } from "../tests/helpers/api"; -import { isPrimitive } from "../utils"; +import { Excalidraw } from "@excalidraw/excalidraw"; + +import { actionDuplicateSelection } from "@excalidraw/excalidraw/actions"; + +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; + +import { Keyboard, Pointer } from "@excalidraw/excalidraw/tests/helpers/ui"; import { act, assertElements, getCloneByOrigId, render, -} from "../tests/test-utils"; -import { Excalidraw } from ".."; -import { actionDuplicateSelection } from "../actions"; +} from "@excalidraw/excalidraw/tests/test-utils"; -import { Keyboard, Pointer } from "../tests/helpers/ui"; +import type { LocalPoint } from "@excalidraw/math"; -import { mutateElement } from "./mutateElement"; +import { mutateElement } from "../src/mutateElement"; +import { duplicateElement, duplicateElements } from "../src/duplicate"; -import { duplicateElement, duplicateElements } from "./duplicate"; - -import type { ExcalidrawLinearElement } from "./types"; +import type { ExcalidrawLinearElement } from "../src/types"; const { h } = window; const mouse = new Pointer("mouse"); diff --git a/packages/excalidraw/element/elbowArrow.test.tsx b/packages/element/tests/elbowArrow.test.tsx similarity index 93% rename from packages/excalidraw/element/elbowArrow.test.tsx rename to packages/element/tests/elbowArrow.test.tsx index 621d2640fc..b8b5a8b85d 100644 --- a/packages/excalidraw/element/elbowArrow.test.tsx +++ b/packages/element/tests/elbowArrow.test.tsx @@ -1,31 +1,33 @@ +import { ARROW_TYPE } from "@excalidraw/common"; import { pointFrom } from "@excalidraw/math"; -import React from "react"; +import { Excalidraw, mutateElement } from "@excalidraw/excalidraw"; -import type { LocalPoint } from "@excalidraw/math"; +import Scene from "@excalidraw/excalidraw/scene/Scene"; +import { actionSelectAll } from "@excalidraw/excalidraw/actions"; +import { actionDuplicateSelection } from "@excalidraw/excalidraw/actions/actionDuplicateSelection"; + +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; +import { Pointer, UI } from "@excalidraw/excalidraw/tests/helpers/ui"; -import "../../utils/test-utils"; -import { actionSelectAll } from "../actions"; -import { actionDuplicateSelection } from "../actions/actionDuplicateSelection"; -import { ARROW_TYPE } from "../constants"; -import { Excalidraw, mutateElement } from "../index"; -import Scene from "../scene/Scene"; -import { API } from "../tests/helpers/api"; -import { Pointer, UI } from "../tests/helpers/ui"; import { act, fireEvent, GlobalTestState, queryByTestId, render, -} from "../tests/test-utils"; +} from "@excalidraw/excalidraw/tests/test-utils"; -import { bindLinearElement } from "./binding"; +import "@excalidraw/utils/test-utils"; + +import type { LocalPoint } from "@excalidraw/math"; + +import { bindLinearElement } from "../src/binding"; import type { ExcalidrawArrowElement, ExcalidrawBindableElement, ExcalidrawElbowArrowElement, -} from "./types"; +} from "../src/types"; const { h } = window; diff --git a/packages/excalidraw/element/flowchart.test.tsx b/packages/element/tests/flowchart.test.tsx similarity index 97% rename from packages/excalidraw/element/flowchart.test.tsx rename to packages/element/tests/flowchart.test.tsx index bc026e7d7c..0130fb4c8a 100644 --- a/packages/excalidraw/element/flowchart.test.tsx +++ b/packages/element/tests/flowchart.test.tsx @@ -1,9 +1,13 @@ -import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; -import { reseed } from "../random"; -import { API } from "../tests/helpers/api"; -import { UI, Keyboard, Pointer } from "../tests/helpers/ui"; -import { render, unmountComponent } from "../tests/test-utils"; +import { KEYS, reseed } from "@excalidraw/common"; + +import { Excalidraw } from "@excalidraw/excalidraw"; + +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; +import { UI, Keyboard, Pointer } from "@excalidraw/excalidraw/tests/helpers/ui"; +import { + render, + unmountComponent, +} from "@excalidraw/excalidraw/tests/test-utils"; unmountComponent(); diff --git a/packages/excalidraw/tests/fractionalIndex.test.ts b/packages/element/tests/fractionalIndex.test.ts similarity index 98% rename from packages/excalidraw/tests/fractionalIndex.test.ts rename to packages/element/tests/fractionalIndex.test.ts index e9eb576e70..5d040e29f2 100644 --- a/packages/excalidraw/tests/fractionalIndex.test.ts +++ b/packages/element/tests/fractionalIndex.test.ts @@ -1,19 +1,24 @@ /* eslint-disable no-lone-blocks */ import { generateKeyBetween } from "fractional-indexing"; -import { InvalidFractionalIndexError } from "../errors"; +import { arrayToMap } from "@excalidraw/common"; + import { syncInvalidIndices, syncMovedIndices, validateFractionalIndices, -} from "../fractionalIndex"; -import { arrayToMap } from "../utils"; +} from "@excalidraw/element/fractionalIndex"; -import { deepCopyElement } from "../element/duplicate"; +import { deepCopyElement } from "@excalidraw/element/duplicate"; -import { API } from "./helpers/api"; +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; -import type { ExcalidrawElement, FractionalIndex } from "../element/types"; +import type { + ExcalidrawElement, + FractionalIndex, +} from "@excalidraw/element/types"; + +import { InvalidFractionalIndexError } from "../src/fractionalIndex"; describe("sync invalid indices with array order", () => { describe("should NOT sync empty array", () => { diff --git a/packages/excalidraw/frame.test.tsx b/packages/element/tests/frame.test.tsx similarity index 97% rename from packages/excalidraw/frame.test.tsx rename to packages/element/tests/frame.test.tsx index fce420c020..47f2160ac3 100644 --- a/packages/excalidraw/frame.test.tsx +++ b/packages/element/tests/frame.test.tsx @@ -1,10 +1,16 @@ -import { API } from "./tests/helpers/api"; -import { Keyboard, Pointer } from "./tests/helpers/ui"; -import { getCloneByOrigId, render } from "./tests/test-utils"; +import { + convertToExcalidrawElements, + Excalidraw, +} from "@excalidraw/excalidraw"; -import { convertToExcalidrawElements, Excalidraw } from "./index"; +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; +import { Keyboard, Pointer } from "@excalidraw/excalidraw/tests/helpers/ui"; +import { + getCloneByOrigId, + render, +} from "@excalidraw/excalidraw/tests/test-utils"; -import type { ExcalidrawElement } from "./element/types"; +import type { ExcalidrawElement } from "../src/types"; const { h } = window; const mouse = new Pointer("mouse"); diff --git a/packages/excalidraw/tests/resize.test.tsx b/packages/element/tests/resize.test.tsx similarity index 98% rename from packages/excalidraw/tests/resize.test.tsx rename to packages/element/tests/resize.test.tsx index 055b097b3d..f3804e2a22 100644 --- a/packages/excalidraw/tests/resize.test.tsx +++ b/packages/element/tests/resize.test.tsx @@ -1,28 +1,33 @@ import { pointFrom } from "@excalidraw/math"; -import React from "react"; + +import { Excalidraw } from "@excalidraw/excalidraw"; +import { + KEYS, + getSizeFromPoints, + reseed, + arrayToMap, +} from "@excalidraw/common"; + +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; +import { UI, Keyboard, Pointer } from "@excalidraw/excalidraw/tests/helpers/ui"; +import { + render, + unmountComponent, +} from "@excalidraw/excalidraw/tests/test-utils"; import type { LocalPoint } from "@excalidraw/math"; -import { getElementPointsCoords } from "../element/bounds"; -import { LinearElementEditor } from "../element/linearElementEditor"; -import { resizeSingleElement } from "../element/resizeElements"; -import { isLinearElement } from "../element/typeChecks"; -import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; -import { getSizeFromPoints } from "../points"; -import { reseed } from "../random"; -import { arrayToMap } from "../utils"; +import { isLinearElement } from "../src/typeChecks"; +import { resizeSingleElement } from "../src/resizeElements"; +import { LinearElementEditor } from "../src/linearElementEditor"; +import { getElementPointsCoords } from "../src/bounds"; -import { API } from "./helpers/api"; -import { UI, Keyboard, Pointer } from "./helpers/ui"; -import { render, unmountComponent } from "./test-utils"; - -import type { Bounds } from "../element/bounds"; +import type { Bounds } from "../src/bounds"; import type { ExcalidrawElbowArrowElement, ExcalidrawFreeDrawElement, ExcalidrawLinearElement, -} from "../element/types"; +} from "../src/types"; unmountComponent(); diff --git a/packages/excalidraw/scene/selection.test.ts b/packages/element/tests/selection.test.ts similarity index 95% rename from packages/excalidraw/scene/selection.test.ts rename to packages/element/tests/selection.test.ts index 644d2129f9..fbcdb26935 100644 --- a/packages/excalidraw/scene/selection.test.ts +++ b/packages/element/tests/selection.test.ts @@ -1,4 +1,4 @@ -import { makeNextSelectedElementIds } from "./selection"; +import { makeNextSelectedElementIds } from "../src/selection"; describe("makeNextSelectedElementIds", () => { const _makeNextSelectedElementIds = ( diff --git a/packages/excalidraw/element/sizeHelpers.test.ts b/packages/element/tests/sizeHelpers.test.ts similarity index 95% rename from packages/excalidraw/element/sizeHelpers.test.ts rename to packages/element/tests/sizeHelpers.test.ts index c882e1f3cd..168a9a2adf 100644 --- a/packages/excalidraw/element/sizeHelpers.test.ts +++ b/packages/element/tests/sizeHelpers.test.ts @@ -1,15 +1,15 @@ import { vi } from "vitest"; -import * as constants from "../constants"; +import * as constants from "@excalidraw/common"; -import { getPerfectElementSize } from "./sizeHelpers"; +import { getPerfectElementSize } from "../src/sizeHelpers"; const EPSILON_DIGITS = 3; // Needed so that we can mock the value of constants which is done in // below tests. In Jest this wasn't needed as global override was possible // but vite doesn't allow that hence we need to mock vi.mock( - "../constants.ts", + "@excalidraw/common", //@ts-ignore async (importOriginal) => { const module: any = await importOriginal(); diff --git a/packages/excalidraw/element/sortElements.test.ts b/packages/element/tests/sortElements.test.ts similarity index 97% rename from packages/excalidraw/element/sortElements.test.ts rename to packages/element/tests/sortElements.test.ts index 5f7c4b2e61..509e5e9d0a 100644 --- a/packages/excalidraw/element/sortElements.test.ts +++ b/packages/element/tests/sortElements.test.ts @@ -1,9 +1,9 @@ -import { API } from "../tests/helpers/api"; +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; -import { mutateElement } from "./mutateElement"; -import { normalizeElementOrder } from "./sortElements"; +import { mutateElement } from "../src/mutateElement"; +import { normalizeElementOrder } from "../src/sortElements"; -import type { ExcalidrawElement } from "./types"; +import type { ExcalidrawElement } from "../src/types"; const assertOrder = ( elements: readonly ExcalidrawElement[], diff --git a/packages/excalidraw/element/textElement.test.ts b/packages/element/tests/textElement.test.ts similarity index 94% rename from packages/excalidraw/element/textElement.test.ts rename to packages/element/tests/textElement.test.ts index 41531a7388..5c10681a70 100644 --- a/packages/excalidraw/element/textElement.test.ts +++ b/packages/element/tests/textElement.test.ts @@ -1,16 +1,17 @@ -import { FONT_FAMILY } from "../constants"; -import { getLineHeight } from "../fonts"; -import { API } from "../tests/helpers/api"; +import { getLineHeight } from "@excalidraw/common"; +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; + +import { FONT_FAMILY } from "@excalidraw/common"; import { computeContainerDimensionForBoundText, getContainerCoords, getBoundTextMaxWidth, getBoundTextMaxHeight, -} from "./textElement"; -import { detectLineHeight, getLineHeightInPx } from "./textMeasurements"; +} from "../src/textElement"; +import { detectLineHeight, getLineHeightInPx } from "../src/textMeasurements"; -import type { ExcalidrawTextElementWithContainer } from "./types"; +import type { ExcalidrawTextElementWithContainer } from "../src/types"; describe("Test measureText", () => { describe("Test getContainerCoords", () => { diff --git a/packages/excalidraw/element/textWrapping.test.ts b/packages/element/tests/textWrapping.test.ts similarity index 99% rename from packages/excalidraw/element/textWrapping.test.ts rename to packages/element/tests/textWrapping.test.ts index 357736a2e4..87c96a4c91 100644 --- a/packages/excalidraw/element/textWrapping.test.ts +++ b/packages/element/tests/textWrapping.test.ts @@ -1,6 +1,6 @@ -import { wrapText, parseTokens } from "./textWrapping"; +import { wrapText, parseTokens } from "../src/textWrapping"; -import type { FontString } from "./types"; +import type { FontString } from "../src/types"; describe("Test wrapText", () => { // font is irrelevant as jsdom does not support FontFace API diff --git a/packages/excalidraw/element/typeChecks.test.ts b/packages/element/tests/typeChecks.test.ts similarity index 93% rename from packages/excalidraw/element/typeChecks.test.ts rename to packages/element/tests/typeChecks.test.ts index 44e4dd7557..6be81aaa6d 100644 --- a/packages/excalidraw/element/typeChecks.test.ts +++ b/packages/element/tests/typeChecks.test.ts @@ -1,6 +1,6 @@ -import { API } from "../tests/helpers/api"; +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; -import { hasBoundTextElement } from "./typeChecks"; +import { hasBoundTextElement } from "../src/typeChecks"; describe("Test TypeChecks", () => { describe("Test hasBoundTextElement", () => { diff --git a/packages/excalidraw/tests/zindex.test.tsx b/packages/element/tests/zindex.test.tsx similarity index 98% rename from packages/excalidraw/tests/zindex.test.tsx rename to packages/element/tests/zindex.test.tsx index c8e166aff9..997cb56f81 100644 --- a/packages/excalidraw/tests/zindex.test.tsx +++ b/packages/element/tests/zindex.test.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import { reseed } from "@excalidraw/common"; import { actionSendBackward, @@ -6,20 +6,27 @@ import { actionBringToFront, actionSendToBack, actionDuplicateSelection, -} from "../actions"; -import { selectGroupsForSelectedElements } from "../groups"; -import { Excalidraw } from "../index"; -import { reseed } from "../random"; +} from "@excalidraw/excalidraw/actions"; -import { API } from "./helpers/api"; -import { act, getCloneByOrigId, render, unmountComponent } from "./test-utils"; +import { Excalidraw } from "@excalidraw/excalidraw"; + +import { API } from "@excalidraw/excalidraw/tests/helpers/api"; +import { + act, + getCloneByOrigId, + render, + unmountComponent, +} from "@excalidraw/excalidraw/tests/test-utils"; + +import type { AppState } from "@excalidraw/excalidraw/types"; + +import { selectGroupsForSelectedElements } from "../src/groups"; import type { ExcalidrawElement, ExcalidrawFrameElement, ExcalidrawSelectionElement, -} from "../element/types"; -import type { AppState } from "../types"; +} from "../src/types"; unmountComponent(); diff --git a/packages/element/tsconfig.json b/packages/element/tsconfig.json new file mode 100644 index 0000000000..82cc2c2377 --- /dev/null +++ b/packages/element/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist/types" + } +} diff --git a/packages/eslintrc.base.json b/packages/eslintrc.base.json new file mode 100644 index 0000000000..88d006a096 --- /dev/null +++ b/packages/eslintrc.base.json @@ -0,0 +1,21 @@ +{ + "overrides": [ + { + "files": ["src/**/*.{ts,tsx}"], + "rules": { + "@typescript-eslint/no-restricted-imports": [ + "error", + { + "patterns": [ + { + "group": ["../../excalidraw", "../../../packages/excalidraw", "@excalidraw/excalidraw"], + "message": "Do not import from '@excalidraw/excalidraw' package anything but types, as this package must be independent.", + "allowTypeImports": true + } + ] + } + ] + } + } + ] +} diff --git a/packages/excalidraw/actions/actionAddToLibrary.ts b/packages/excalidraw/actions/actionAddToLibrary.ts index b793533084..9216e52c23 100644 --- a/packages/excalidraw/actions/actionAddToLibrary.ts +++ b/packages/excalidraw/actions/actionAddToLibrary.ts @@ -1,7 +1,7 @@ -import { LIBRARY_DISABLED_TYPES } from "../constants"; -import { deepCopyElement } from "../element/duplicate"; +import { LIBRARY_DISABLED_TYPES, randomId } from "@excalidraw/common"; +import { deepCopyElement } from "@excalidraw/element/duplicate"; + import { t } from "../i18n"; -import { randomId } from "../random"; import { CaptureUpdateAction } from "../store"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionAlign.tsx b/packages/excalidraw/actions/actionAlign.tsx index b42122a509..46023d61ea 100644 --- a/packages/excalidraw/actions/actionAlign.tsx +++ b/packages/excalidraw/actions/actionAlign.tsx @@ -1,4 +1,17 @@ -import { alignElements } from "../align"; +import { getNonDeletedElements } from "@excalidraw/element"; + +import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; + +import { updateFrameMembershipOfSelectedElements } from "@excalidraw/element/frame"; + +import { KEYS, arrayToMap, getShortcutKey } from "@excalidraw/common"; + +import { alignElements } from "@excalidraw/element/align"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + +import type { Alignment } from "@excalidraw/element/align"; + import { ToolButton } from "../components/ToolButton"; import { AlignBottomIcon, @@ -8,19 +21,14 @@ import { CenterHorizontallyIcon, CenterVerticallyIcon, } from "../components/icons"; -import { getNonDeletedElements } from "../element"; -import { isFrameLikeElement } from "../element/typeChecks"; -import { updateFrameMembershipOfSelectedElements } from "../frame"; + import { t } from "../i18n"; -import { KEYS } from "../keys"; + import { isSomeElementSelected } from "../scene"; import { CaptureUpdateAction } from "../store"; -import { arrayToMap, getShortcutKey } from "../utils"; import { register } from "./register"; -import type { Alignment } from "../align"; -import type { ExcalidrawElement } from "../element/types"; import type { AppClassProperties, AppState, UIAppState } from "../types"; export const alignActionsPredicate = ( diff --git a/packages/excalidraw/actions/actionBoundText.tsx b/packages/excalidraw/actions/actionBoundText.tsx index 4da3f99a1b..7cb10c045c 100644 --- a/packages/excalidraw/actions/actionBoundText.tsx +++ b/packages/excalidraw/actions/actionBoundText.tsx @@ -3,40 +3,50 @@ import { ROUNDNESS, TEXT_ALIGN, VERTICAL_ALIGN, -} from "../constants"; -import { isTextElement, newElement } from "../element"; + arrayToMap, + getFontString, +} from "@excalidraw/common"; import { getOriginalContainerHeightFromCache, resetOriginalContainerCache, updateOriginalContainerCache, -} from "../element/containerCache"; -import { mutateElement } from "../element/mutateElement"; +} from "@excalidraw/element/containerCache"; + import { computeBoundTextPosition, computeContainerDimensionForBoundText, getBoundTextElement, redrawTextBoundingBox, -} from "../element/textElement"; -import { measureText } from "../element/textMeasurements"; +} from "@excalidraw/element/textElement"; + import { hasBoundTextElement, isTextBindableContainer, + isTextElement, isUsingAdaptiveRadius, -} from "../element/typeChecks"; -import { syncMovedIndices } from "../fractionalIndex"; -import { CaptureUpdateAction } from "../store"; -import { arrayToMap, getFontString } from "../utils"; +} from "@excalidraw/element/typeChecks"; -import { register } from "./register"; +import { mutateElement } from "@excalidraw/element/mutateElement"; +import { measureText } from "@excalidraw/element/textMeasurements"; + +import { syncMovedIndices } from "@excalidraw/element/fractionalIndex"; + +import { newElement } from "@excalidraw/element/newElement"; import type { ExcalidrawElement, ExcalidrawLinearElement, ExcalidrawTextContainer, ExcalidrawTextElement, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import type { Mutable } from "@excalidraw/common/utility-types"; + +import { CaptureUpdateAction } from "../store"; + +import { register } from "./register"; + import type { AppState } from "../types"; -import type { Mutable } from "../utility-types"; export const actionUnbindText = register({ name: "unbindText", diff --git a/packages/excalidraw/actions/actionCanvas.tsx b/packages/excalidraw/actions/actionCanvas.tsx index f3e0a8a328..0aa83944f8 100644 --- a/packages/excalidraw/actions/actionCanvas.tsx +++ b/packages/excalidraw/actions/actionCanvas.tsx @@ -1,11 +1,29 @@ import { clamp, roundToStep } from "@excalidraw/math"; +import { + DEFAULT_CANVAS_BACKGROUND_PICKS, + CURSOR_TYPE, + MAX_ZOOM, + MIN_ZOOM, + THEME, + ZOOM_STEP, + getShortcutKey, + updateActiveTool, + CODES, + KEYS, +} from "@excalidraw/common"; + +import { getNonDeletedElements } from "@excalidraw/element"; +import { newElementWith } from "@excalidraw/element/mutateElement"; +import { getCommonBounds, type SceneBounds } from "@excalidraw/element/bounds"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { getDefaultAppState, isEraserActive, isHandToolActive, } from "../appState"; -import { DEFAULT_CANVAS_BACKGROUND_PICKS } from "../colors"; import { ColorPicker } from "../components/ColorPicker/ColorPicker"; import { ToolButton } from "../components/ToolButton"; import { Tooltip } from "../components/Tooltip"; @@ -19,28 +37,16 @@ import { ZoomOutIcon, ZoomResetIcon, } from "../components/icons"; -import { - CURSOR_TYPE, - MAX_ZOOM, - MIN_ZOOM, - THEME, - ZOOM_STEP, -} from "../constants"; import { setCursor } from "../cursor"; -import { getCommonBounds, getNonDeletedElements } from "../element"; -import { newElementWith } from "../element/mutateElement"; + import { t } from "../i18n"; -import { CODES, KEYS } from "../keys"; import { getNormalizedZoom } from "../scene"; import { centerScrollOn } from "../scene/scroll"; import { getStateForZoom } from "../scene/zoom"; import { CaptureUpdateAction } from "../store"; -import { getShortcutKey, updateActiveTool } from "../utils"; import { register } from "./register"; -import type { SceneBounds } from "../element/bounds"; -import type { ExcalidrawElement } from "../element/types"; import type { AppState, Offsets } from "../types"; export const actionChangeViewBackgroundColor = register({ diff --git a/packages/excalidraw/actions/actionClipboard.tsx b/packages/excalidraw/actions/actionClipboard.tsx index 4ce3c39ddc..9de6d70f47 100644 --- a/packages/excalidraw/actions/actionClipboard.tsx +++ b/packages/excalidraw/actions/actionClipboard.tsx @@ -1,3 +1,8 @@ +import { isTextElement } from "@excalidraw/element/typeChecks"; +import { getTextFromElements } from "@excalidraw/element/textElement"; + +import { CODES, KEYS, isFirefox } from "@excalidraw/common"; + import { copyTextToSystemClipboard, copyToClipboard, @@ -7,11 +12,9 @@ import { readSystemClipboard, } from "../clipboard"; import { DuplicateIcon, cutIcon, pngIcon, svgIcon } from "../components/icons"; -import { isFirefox } from "../constants"; import { exportCanvas, prepareElementsForExport } from "../data/index"; -import { getTextFromElements, isTextElement } from "../element"; import { t } from "../i18n"; -import { CODES, KEYS } from "../keys"; + import { CaptureUpdateAction } from "../store"; import { actionDeleteSelected } from "./actionDeleteSelected"; diff --git a/packages/excalidraw/actions/actionCropEditor.tsx b/packages/excalidraw/actions/actionCropEditor.tsx index c377b3a02f..1a7b6da696 100644 --- a/packages/excalidraw/actions/actionCropEditor.tsx +++ b/packages/excalidraw/actions/actionCropEditor.tsx @@ -1,13 +1,14 @@ +import { isImageElement } from "@excalidraw/element/typeChecks"; + +import type { ExcalidrawImageElement } from "@excalidraw/element/types"; + import { ToolButton } from "../components/ToolButton"; import { cropIcon } from "../components/icons"; -import { isImageElement } from "../element/typeChecks"; import { t } from "../i18n"; import { CaptureUpdateAction } from "../store"; import { register } from "./register"; -import type { ExcalidrawImageElement } from "../element/types"; - export const actionToggleCropEditor = register({ name: "cropEditor", label: "helpDialog.cropStart", diff --git a/packages/excalidraw/actions/actionDeleteSelected.tsx b/packages/excalidraw/actions/actionDeleteSelected.tsx index 7e5ed919c2..75e666df02 100644 --- a/packages/excalidraw/actions/actionDeleteSelected.tsx +++ b/packages/excalidraw/actions/actionDeleteSelected.tsx @@ -1,26 +1,35 @@ -import { ToolButton } from "../components/ToolButton"; -import { TrashIcon } from "../components/icons"; -import { getNonDeletedElements } from "../element"; -import { fixBindingsAfterDeletion } from "../element/binding"; -import { LinearElementEditor } from "../element/linearElementEditor"; -import { mutateElement, newElementWith } from "../element/mutateElement"; -import { getContainerElement } from "../element/textElement"; +import { KEYS, updateActiveTool } from "@excalidraw/common"; + +import { getNonDeletedElements } from "@excalidraw/element"; +import { fixBindingsAfterDeletion } from "@excalidraw/element/binding"; +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; +import { + mutateElement, + newElementWith, +} from "@excalidraw/element/mutateElement"; +import { getContainerElement } from "@excalidraw/element/textElement"; import { isBoundToContainer, isElbowArrow, isFrameLikeElement, -} from "../element/typeChecks"; -import { getFrameChildren } from "../frame"; -import { getElementsInGroup, selectGroupsForSelectedElements } from "../groups"; +} from "@excalidraw/element/typeChecks"; +import { getFrameChildren } from "@excalidraw/element/frame"; + +import { + getElementsInGroup, + selectGroupsForSelectedElements, +} from "@excalidraw/element/groups"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { t } from "../i18n"; -import { KEYS } from "../keys"; import { getSelectedElements, isSomeElementSelected } from "../scene"; import { CaptureUpdateAction } from "../store"; -import { updateActiveTool } from "../utils"; +import { TrashIcon } from "../components/icons"; +import { ToolButton } from "../components/ToolButton"; import { register } from "./register"; -import type { ExcalidrawElement } from "../element/types"; import type { AppClassProperties, AppState } from "../types"; const deleteSelectedElements = ( diff --git a/packages/excalidraw/actions/actionDistribute.tsx b/packages/excalidraw/actions/actionDistribute.tsx index c96bdaa3e2..9f05ab6bfa 100644 --- a/packages/excalidraw/actions/actionDistribute.tsx +++ b/packages/excalidraw/actions/actionDistribute.tsx @@ -1,22 +1,30 @@ +import { getNonDeletedElements } from "@excalidraw/element"; + +import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; + +import { CODES, KEYS, arrayToMap, getShortcutKey } from "@excalidraw/common"; + +import { updateFrameMembershipOfSelectedElements } from "@excalidraw/element/frame"; + +import { distributeElements } from "@excalidraw/element/distribute"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + +import type { Distribution } from "@excalidraw/element/distribute"; + import { ToolButton } from "../components/ToolButton"; import { DistributeHorizontallyIcon, DistributeVerticallyIcon, } from "../components/icons"; -import { distributeElements } from "../distribute"; -import { getNonDeletedElements } from "../element"; -import { isFrameLikeElement } from "../element/typeChecks"; -import { updateFrameMembershipOfSelectedElements } from "../frame"; + import { t } from "../i18n"; -import { CODES, KEYS } from "../keys"; + import { isSomeElementSelected } from "../scene"; import { CaptureUpdateAction } from "../store"; -import { arrayToMap, getShortcutKey } from "../utils"; import { register } from "./register"; -import type { Distribution } from "../distribute"; -import type { ExcalidrawElement } from "../element/types"; import type { AppClassProperties, AppState } from "../types"; const enableActionGroup = (appState: AppState, app: AppClassProperties) => { diff --git a/packages/excalidraw/actions/actionDuplicateSelection.test.tsx b/packages/excalidraw/actions/actionDuplicateSelection.test.tsx index bbaae2ed6a..71559fe47e 100644 --- a/packages/excalidraw/actions/actionDuplicateSelection.test.tsx +++ b/packages/excalidraw/actions/actionDuplicateSelection.test.tsx @@ -1,6 +1,5 @@ -import React from "react"; +import { ORIG_ID } from "@excalidraw/common"; -import { ORIG_ID } from "../constants"; import { Excalidraw } from "../index"; import { API } from "../tests/helpers/api"; import { diff --git a/packages/excalidraw/actions/actionDuplicateSelection.tsx b/packages/excalidraw/actions/actionDuplicateSelection.tsx index a6dd9d2e12..231fe1913b 100644 --- a/packages/excalidraw/actions/actionDuplicateSelection.tsx +++ b/packages/excalidraw/actions/actionDuplicateSelection.tsx @@ -1,28 +1,41 @@ -import { ToolButton } from "../components/ToolButton"; -import { DuplicateIcon } from "../components/icons"; -import { DEFAULT_GRID_SIZE } from "../constants"; -import { getNonDeletedElements } from "../element"; -import { isBoundToContainer, isLinearElement } from "../element/typeChecks"; -import { LinearElementEditor } from "../element/linearElementEditor"; -import { selectGroupsForSelectedElements } from "../groups"; -import { t } from "../i18n"; -import { KEYS } from "../keys"; -import { isSomeElementSelected } from "../scene"; +import { + DEFAULT_GRID_SIZE, + KEYS, + arrayToMap, + getShortcutKey, +} from "@excalidraw/common"; + +import { getNonDeletedElements } from "@excalidraw/element"; + +import { + isBoundToContainer, + isLinearElement, +} from "@excalidraw/element/typeChecks"; + +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; + +import { selectGroupsForSelectedElements } from "@excalidraw/element/groups"; + import { excludeElementsInFramesFromSelection, getSelectedElements, -} from "../scene/selection"; +} from "@excalidraw/element/selection"; + +import { syncMovedIndices } from "@excalidraw/element/fractionalIndex"; + +import { duplicateElements } from "@excalidraw/element/duplicate"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + +import { ToolButton } from "../components/ToolButton"; +import { DuplicateIcon } from "../components/icons"; + +import { t } from "../i18n"; +import { isSomeElementSelected } from "../scene"; import { CaptureUpdateAction } from "../store"; -import { arrayToMap, getShortcutKey } from "../utils"; - -import { syncMovedIndices } from "../fractionalIndex"; - -import { duplicateElements } from "../element/duplicate"; import { register } from "./register"; -import type { ExcalidrawElement } from "../element/types"; - export const actionDuplicateSelection = register({ name: "duplicateSelection", label: "labels.duplicateSelection", diff --git a/packages/excalidraw/actions/actionElementLink.ts b/packages/excalidraw/actions/actionElementLink.ts index 69fc67dd35..24ea8bbd65 100644 --- a/packages/excalidraw/actions/actionElementLink.ts +++ b/packages/excalidraw/actions/actionElementLink.ts @@ -1,10 +1,11 @@ -import { copyTextToSystemClipboard } from "../clipboard"; -import { copyIcon, elementLinkIcon } from "../components/icons"; import { canCreateLinkFromElements, defaultGetElementLinkFromSelection, getLinkIdAndTypeFromSelection, -} from "../element/elementLink"; +} from "@excalidraw/element/elementLink"; + +import { copyTextToSystemClipboard } from "../clipboard"; +import { copyIcon, elementLinkIcon } from "../components/icons"; import { t } from "../i18n"; import { getSelectedElements } from "../scene"; import { CaptureUpdateAction } from "../store"; diff --git a/packages/excalidraw/actions/actionElementLock.ts b/packages/excalidraw/actions/actionElementLock.ts index 57ca1ddedc..79d13c63ef 100644 --- a/packages/excalidraw/actions/actionElementLock.ts +++ b/packages/excalidraw/actions/actionElementLock.ts @@ -1,15 +1,18 @@ +import { KEYS, arrayToMap } from "@excalidraw/common"; + +import { newElementWith } from "@excalidraw/element/mutateElement"; + +import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { LockedIcon, UnlockedIcon } from "../components/icons"; -import { newElementWith } from "../element/mutateElement"; -import { isFrameLikeElement } from "../element/typeChecks"; -import { KEYS } from "../keys"; + import { getSelectedElements } from "../scene"; import { CaptureUpdateAction } from "../store"; -import { arrayToMap } from "../utils"; import { register } from "./register"; -import type { ExcalidrawElement } from "../element/types"; - const shouldLock = (elements: readonly ExcalidrawElement[]) => elements.every((el) => !el.locked); diff --git a/packages/excalidraw/actions/actionEmbeddable.ts b/packages/excalidraw/actions/actionEmbeddable.ts new file mode 100644 index 0000000000..5566522407 --- /dev/null +++ b/packages/excalidraw/actions/actionEmbeddable.ts @@ -0,0 +1,34 @@ +import { updateActiveTool } from "@excalidraw/common"; + +import { setCursorForShape } from "../cursor"; +import { CaptureUpdateAction } from "../store"; + +import { register } from "./register"; + +export const actionSetEmbeddableAsActiveTool = register({ + name: "setEmbeddableAsActiveTool", + trackEvent: { category: "toolbar" }, + target: "Tool", + label: "toolBar.embeddable", + perform: (elements, appState, _, app) => { + const nextActiveTool = updateActiveTool(appState, { + type: "embeddable", + }); + + setCursorForShape(app.canvas, { + ...appState, + activeTool: nextActiveTool, + }); + + return { + elements, + appState: { + ...appState, + activeTool: updateActiveTool(appState, { + type: "embeddable", + }), + }, + captureUpdate: CaptureUpdateAction.EVENTUALLY, + }; + }, +}); diff --git a/packages/excalidraw/actions/actionExport.tsx b/packages/excalidraw/actions/actionExport.tsx index c9d70fc46c..8fcaea21bb 100644 --- a/packages/excalidraw/actions/actionExport.tsx +++ b/packages/excalidraw/actions/actionExport.tsx @@ -1,3 +1,14 @@ +import { + KEYS, + DEFAULT_EXPORT_PADDING, + EXPORT_SCALES, + THEME, +} from "@excalidraw/common"; + +import { getNonDeletedElements } from "@excalidraw/element"; + +import type { Theme } from "@excalidraw/element/types"; + import { useDevice } from "../components/App"; import { CheckboxItem } from "../components/CheckboxItem"; import { DarkModeToggle } from "../components/DarkModeToggle"; @@ -5,14 +16,12 @@ import { ProjectName } from "../components/ProjectName"; import { ToolButton } from "../components/ToolButton"; import { Tooltip } from "../components/Tooltip"; import { ExportIcon, questionCircle, saveAs } from "../components/icons"; -import { DEFAULT_EXPORT_PADDING, EXPORT_SCALES, THEME } from "../constants"; import { loadFromJSON, saveAsJSON } from "../data"; import { isImageFileHandle } from "../data/blob"; import { nativeFileSystemSupported } from "../data/filesystem"; import { resaveAsImageWithScene } from "../data/resave"; -import { getNonDeletedElements } from "../element"; + import { t } from "../i18n"; -import { KEYS } from "../keys"; import { getSelectedElements, isSomeElementSelected } from "../scene"; import { getExportSize } from "../scene/export"; import { CaptureUpdateAction } from "../store"; @@ -21,8 +30,6 @@ import "../components/ToolIcon.scss"; import { register } from "./register"; -import type { Theme } from "../element/types"; - export const actionChangeProjectName = register({ name: "changeProjectName", label: "labels.fileTitle", diff --git a/packages/excalidraw/actions/actionFinalize.tsx b/packages/excalidraw/actions/actionFinalize.tsx index ac8a4e036d..9849616562 100644 --- a/packages/excalidraw/actions/actionFinalize.tsx +++ b/packages/excalidraw/actions/actionFinalize.tsx @@ -1,21 +1,26 @@ import { pointFrom } from "@excalidraw/math"; -import { ToolButton } from "../components/ToolButton"; -import { done } from "../components/icons"; -import { resetCursor } from "../cursor"; -import { isInvisiblySmallElement } from "../element"; import { maybeBindLinearElement, bindOrUnbindLinearElement, -} from "../element/binding"; -import { LinearElementEditor } from "../element/linearElementEditor"; -import { mutateElement } from "../element/mutateElement"; -import { isBindingElement, isLinearElement } from "../element/typeChecks"; +} from "@excalidraw/element/binding"; +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; +import { mutateElement } from "@excalidraw/element/mutateElement"; +import { + isBindingElement, + isLinearElement, +} from "@excalidraw/element/typeChecks"; + +import { KEYS, arrayToMap, updateActiveTool } from "@excalidraw/common"; +import { isPathALoop } from "@excalidraw/element/shapes"; + +import { isInvisiblySmallElement } from "@excalidraw/element/sizeHelpers"; + import { t } from "../i18n"; -import { KEYS } from "../keys"; -import { isPathALoop } from "../shapes"; +import { resetCursor } from "../cursor"; +import { done } from "../components/icons"; +import { ToolButton } from "../components/ToolButton"; import { CaptureUpdateAction } from "../store"; -import { arrayToMap, updateActiveTool } from "../utils"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionFlip.test.tsx b/packages/excalidraw/actions/actionFlip.test.tsx index e9953e02d4..23e4ffc123 100644 --- a/packages/excalidraw/actions/actionFlip.test.tsx +++ b/packages/excalidraw/actions/actionFlip.test.tsx @@ -1,5 +1,4 @@ import { pointFrom } from "@excalidraw/math"; -import React from "react"; import { Excalidraw } from "../index"; import { API } from "../tests/helpers/api"; diff --git a/packages/excalidraw/actions/actionFlip.ts b/packages/excalidraw/actions/actionFlip.ts index 6c91445a37..62be891cb7 100644 --- a/packages/excalidraw/actions/actionFlip.ts +++ b/packages/excalidraw/actions/actionFlip.ts @@ -1,26 +1,22 @@ -import { flipHorizontal, flipVertical } from "../components/icons"; -import { getNonDeletedElements } from "../element"; +import { getNonDeletedElements } from "@excalidraw/element"; import { bindOrUnbindLinearElements, isBindingEnabled, -} from "../element/binding"; -import { getCommonBoundingBox } from "../element/bounds"; -import { mutateElement, newElementWith } from "../element/mutateElement"; -import { resizeMultipleElements } from "../element/resizeElements"; +} from "@excalidraw/element/binding"; +import { getCommonBoundingBox } from "@excalidraw/element/bounds"; +import { + mutateElement, + newElementWith, +} from "@excalidraw/element/mutateElement"; +import { deepCopyElement } from "@excalidraw/element/duplicate"; +import { resizeMultipleElements } from "@excalidraw/element/resizeElements"; import { isArrowElement, isElbowArrow, isLinearElement, -} from "../element/typeChecks"; -import { updateFrameMembershipOfSelectedElements } from "../frame"; -import { CODES, KEYS } from "../keys"; -import { getSelectedElements } from "../scene"; -import { CaptureUpdateAction } from "../store"; -import { arrayToMap } from "../utils"; - -import { deepCopyElement } from "../element/duplicate"; - -import { register } from "./register"; +} from "@excalidraw/element/typeChecks"; +import { updateFrameMembershipOfSelectedElements } from "@excalidraw/element/frame"; +import { CODES, KEYS, arrayToMap } from "@excalidraw/common"; import type { ExcalidrawArrowElement, @@ -28,7 +24,15 @@ import type { ExcalidrawElement, NonDeleted, NonDeletedSceneElementsMap, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import { getSelectedElements } from "../scene"; +import { CaptureUpdateAction } from "../store"; + +import { flipHorizontal, flipVertical } from "../components/icons"; + +import { register } from "./register"; + import type { AppClassProperties, AppState } from "../types"; export const actionFlipHorizontal = register({ diff --git a/packages/excalidraw/actions/actionFrame.ts b/packages/excalidraw/actions/actionFrame.ts index 198994b299..13d57b2a12 100644 --- a/packages/excalidraw/actions/actionFrame.ts +++ b/packages/excalidraw/actions/actionFrame.ts @@ -1,20 +1,28 @@ -import { frameToolIcon } from "../components/icons"; +import { getNonDeletedElements } from "@excalidraw/element"; +import { mutateElement } from "@excalidraw/element/mutateElement"; +import { newFrameElement } from "@excalidraw/element/newElement"; +import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; +import { + addElementsToFrame, + removeAllElementsFromFrame, +} from "@excalidraw/element/frame"; +import { getFrameChildren } from "@excalidraw/element/frame"; + +import { KEYS, updateActiveTool } from "@excalidraw/common"; + +import { getElementsInGroup } from "@excalidraw/element/groups"; + +import { getCommonBounds } from "@excalidraw/element/bounds"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { setCursorForShape } from "../cursor"; -import { getCommonBounds, getNonDeletedElements } from "../element"; -import { mutateElement } from "../element/mutateElement"; -import { newFrameElement } from "../element/newElement"; -import { isFrameLikeElement } from "../element/typeChecks"; -import { addElementsToFrame, removeAllElementsFromFrame } from "../frame"; -import { getFrameChildren } from "../frame"; -import { getElementsInGroup } from "../groups"; -import { KEYS } from "../keys"; +import { frameToolIcon } from "../components/icons"; import { getSelectedElements } from "../scene"; import { CaptureUpdateAction } from "../store"; -import { updateActiveTool } from "../utils"; import { register } from "./register"; -import type { ExcalidrawElement } from "../element/types"; import type { AppClassProperties, AppState, UIAppState } from "../types"; const isSingleFrameSelected = ( diff --git a/packages/excalidraw/actions/actionGroup.tsx b/packages/excalidraw/actions/actionGroup.tsx index ded2f5b72a..6b47ef969d 100644 --- a/packages/excalidraw/actions/actionGroup.tsx +++ b/packages/excalidraw/actions/actionGroup.tsx @@ -1,9 +1,9 @@ -import { ToolButton } from "../components/ToolButton"; -import { UngroupIcon, GroupIcon } from "../components/icons"; -import { getNonDeletedElements } from "../element"; -import { newElementWith } from "../element/mutateElement"; -import { isBoundToContainer } from "../element/typeChecks"; -import { syncMovedIndices } from "../fractionalIndex"; +import { getNonDeletedElements } from "@excalidraw/element"; + +import { newElementWith } from "@excalidraw/element/mutateElement"; + +import { isBoundToContainer } from "@excalidraw/element/typeChecks"; + import { frameAndChildrenSelectedTogether, getElementsInResizingFrame, @@ -12,7 +12,10 @@ import { groupByFrameLikes, removeElementsFromFrame, replaceAllElementsInFrame, -} from "../frame"; +} from "@excalidraw/element/frame"; + +import { KEYS, randomId, arrayToMap, getShortcutKey } from "@excalidraw/common"; + import { getSelectedGroupIds, selectGroup, @@ -21,21 +24,26 @@ import { addToGroup, removeFromSelectedGroups, isElementInGroup, -} from "../groups"; -import { t } from "../i18n"; -import { KEYS } from "../keys"; -import { randomId } from "../random"; -import { isSomeElementSelected } from "../scene"; -import { CaptureUpdateAction } from "../store"; -import { arrayToMap, getShortcutKey } from "../utils"; +} from "@excalidraw/element/groups"; -import { register } from "./register"; +import { syncMovedIndices } from "@excalidraw/element/fractionalIndex"; import type { ExcalidrawElement, ExcalidrawTextElement, OrderedExcalidrawElement, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import { ToolButton } from "../components/ToolButton"; +import { UngroupIcon, GroupIcon } from "../components/icons"; + +import { t } from "../i18n"; + +import { isSomeElementSelected } from "../scene"; +import { CaptureUpdateAction } from "../store"; + +import { register } from "./register"; + import type { AppClassProperties, AppState } from "../types"; const allElementsInSameGroup = (elements: readonly ExcalidrawElement[]) => { diff --git a/packages/excalidraw/actions/actionHistory.tsx b/packages/excalidraw/actions/actionHistory.tsx index da4f802191..a0dfb85df8 100644 --- a/packages/excalidraw/actions/actionHistory.tsx +++ b/packages/excalidraw/actions/actionHistory.tsx @@ -1,14 +1,14 @@ +import { isWindows, KEYS, matchKey, arrayToMap } from "@excalidraw/common"; + +import type { SceneElementsMap } from "@excalidraw/element/types"; + import { ToolButton } from "../components/ToolButton"; import { UndoIcon, RedoIcon } from "../components/icons"; -import { isWindows } from "../constants"; import { HistoryChangedEvent } from "../history"; import { useEmitter } from "../hooks/useEmitter"; import { t } from "../i18n"; -import { KEYS, matchKey } from "../keys"; import { CaptureUpdateAction } from "../store"; -import { arrayToMap } from "../utils"; -import type { SceneElementsMap } from "../element/types"; import type { History } from "../history"; import type { Store } from "../store"; import type { AppClassProperties, AppState } from "../types"; diff --git a/packages/excalidraw/actions/actionLinearEditor.tsx b/packages/excalidraw/actions/actionLinearEditor.tsx index f17f0e5653..56e327bd2e 100644 --- a/packages/excalidraw/actions/actionLinearEditor.tsx +++ b/packages/excalidraw/actions/actionLinearEditor.tsx @@ -1,15 +1,18 @@ +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; + +import { isElbowArrow, isLinearElement } from "@excalidraw/element/typeChecks"; + +import type { ExcalidrawLinearElement } from "@excalidraw/element/types"; + import { DEFAULT_CATEGORIES } from "../components/CommandPalette/CommandPalette"; import { ToolButton } from "../components/ToolButton"; import { lineEditorIcon } from "../components/icons"; -import { LinearElementEditor } from "../element/linearElementEditor"; -import { isElbowArrow, isLinearElement } from "../element/typeChecks"; + import { t } from "../i18n"; import { CaptureUpdateAction } from "../store"; import { register } from "./register"; -import type { ExcalidrawLinearElement } from "../element/types"; - export const actionToggleLinearEditor = register({ name: "toggleLinearEditor", category: DEFAULT_CATEGORIES.elements, diff --git a/packages/excalidraw/actions/actionLink.tsx b/packages/excalidraw/actions/actionLink.tsx index 91d01b7a6f..71426267d1 100644 --- a/packages/excalidraw/actions/actionLink.tsx +++ b/packages/excalidraw/actions/actionLink.tsx @@ -1,12 +1,14 @@ +import { isEmbeddableElement } from "@excalidraw/element/typeChecks"; + +import { KEYS, getShortcutKey } from "@excalidraw/common"; + import { ToolButton } from "../components/ToolButton"; import { getContextMenuLabel } from "../components/hyperlink/Hyperlink"; import { LinkIcon } from "../components/icons"; -import { isEmbeddableElement } from "../element/typeChecks"; import { t } from "../i18n"; -import { KEYS } from "../keys"; + import { getSelectedElements } from "../scene"; import { CaptureUpdateAction } from "../store"; -import { getShortcutKey } from "../utils"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionMenu.tsx b/packages/excalidraw/actions/actionMenu.tsx index 15b763cb90..67863e0208 100644 --- a/packages/excalidraw/actions/actionMenu.tsx +++ b/packages/excalidraw/actions/actionMenu.tsx @@ -1,8 +1,13 @@ +import { KEYS } from "@excalidraw/common"; + +import { getNonDeletedElements } from "@excalidraw/element"; + +import { showSelectedShapeActions } from "@excalidraw/element/showSelectedShapeActions"; + import { ToolButton } from "../components/ToolButton"; import { HamburgerMenuIcon, HelpIconThin, palette } from "../components/icons"; -import { showSelectedShapeActions, getNonDeletedElements } from "../element"; import { t } from "../i18n"; -import { KEYS } from "../keys"; + import { CaptureUpdateAction } from "../store"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionProperties.test.tsx b/packages/excalidraw/actions/actionProperties.test.tsx index c5467bb94d..38419ce827 100644 --- a/packages/excalidraw/actions/actionProperties.test.tsx +++ b/packages/excalidraw/actions/actionProperties.test.tsx @@ -1,8 +1,12 @@ import { queryByTestId } from "@testing-library/react"; -import React from "react"; -import { COLOR_PALETTE, DEFAULT_ELEMENT_BACKGROUND_PICKS } from "../colors"; -import { FONT_FAMILY, STROKE_WIDTH } from "../constants"; +import { + COLOR_PALETTE, + DEFAULT_ELEMENT_BACKGROUND_PICKS, + FONT_FAMILY, + STROKE_WIDTH, +} from "@excalidraw/common"; + import { Excalidraw } from "../index"; import { API } from "../tests/helpers/api"; import { UI } from "../tests/helpers/ui"; diff --git a/packages/excalidraw/actions/actionProperties.tsx b/packages/excalidraw/actions/actionProperties.tsx index 5a75906676..5a309b6775 100644 --- a/packages/excalidraw/actions/actionProperties.tsx +++ b/packages/excalidraw/actions/actionProperties.tsx @@ -1,15 +1,77 @@ import { pointFrom } from "@excalidraw/math"; import { useEffect, useMemo, useRef, useState } from "react"; -import type { LocalPoint } from "@excalidraw/math"; - -import { trackEvent } from "../analytics"; import { DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE, DEFAULT_ELEMENT_BACKGROUND_PICKS, DEFAULT_ELEMENT_STROKE_COLOR_PALETTE, DEFAULT_ELEMENT_STROKE_PICKS, -} from "../colors"; + ARROW_TYPE, + DEFAULT_FONT_FAMILY, + DEFAULT_FONT_SIZE, + FONT_FAMILY, + ROUNDNESS, + STROKE_WIDTH, + VERTICAL_ALIGN, + KEYS, + randomInteger, + arrayToMap, + getFontFamilyString, + getShortcutKey, + tupleToCoors, + getLineHeight, +} from "@excalidraw/common"; + +import { getNonDeletedElements } from "@excalidraw/element"; + +import { + bindLinearElement, + bindPointToSnapToElementOutline, + calculateFixedPointForElbowArrowBinding, + getHoveredElementForBinding, + updateBoundElements, +} from "@excalidraw/element/binding"; + +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; + +import { + mutateElement, + newElementWith, +} from "@excalidraw/element/mutateElement"; + +import { + getBoundTextElement, + redrawTextBoundingBox, +} from "@excalidraw/element/textElement"; + +import { + isArrowElement, + isBoundToContainer, + isElbowArrow, + isLinearElement, + isTextElement, + isUsingAdaptiveRadius, +} from "@excalidraw/element/typeChecks"; + +import { hasStrokeColor } from "@excalidraw/element/comparisons"; + +import { updateElbowArrowPoints } from "@excalidraw/element/elbowArrow"; + +import type { LocalPoint } from "@excalidraw/math"; + +import type { + Arrowhead, + ExcalidrawBindableElement, + ExcalidrawElement, + ExcalidrawLinearElement, + ExcalidrawTextElement, + FontFamilyValues, + TextAlign, + VerticalAlign, + NonDeletedSceneElementsMap, +} from "@excalidraw/element/types"; + +import { trackEvent } from "../analytics"; import { ButtonIconSelect } from "../components/ButtonIconSelect"; import { ColorPicker } from "../components/ColorPicker/ColorPicker"; import { FontPicker } from "../components/FontPicker/FontPicker"; @@ -60,41 +122,9 @@ import { ArrowheadCrowfootOneIcon, ArrowheadCrowfootOneOrManyIcon, } from "../components/icons"; -import { - ARROW_TYPE, - DEFAULT_FONT_FAMILY, - DEFAULT_FONT_SIZE, - FONT_FAMILY, - ROUNDNESS, - STROKE_WIDTH, - VERTICAL_ALIGN, -} from "../constants"; -import { - getNonDeletedElements, - isTextElement, - redrawTextBoundingBox, -} from "../element"; -import { - bindLinearElement, - bindPointToSnapToElementOutline, - calculateFixedPointForElbowArrowBinding, - getHoveredElementForBinding, - updateBoundElements, -} from "../element/binding"; -import { LinearElementEditor } from "../element/linearElementEditor"; -import { mutateElement, newElementWith } from "../element/mutateElement"; -import { getBoundTextElement } from "../element/textElement"; -import { - isArrowElement, - isBoundToContainer, - isElbowArrow, - isLinearElement, - isUsingAdaptiveRadius, -} from "../element/typeChecks"; -import { Fonts, getLineHeight } from "../fonts"; + +import { Fonts } from "../fonts"; import { getLanguage, t } from "../i18n"; -import { KEYS } from "../keys"; -import { randomInteger } from "../random"; import { canHaveArrowheads, getCommonAttributeOfSelectedElements, @@ -102,30 +132,10 @@ import { getTargetElements, isSomeElementSelected, } from "../scene"; -import { hasStrokeColor } from "../scene/comparisons"; import { CaptureUpdateAction } from "../store"; -import { - arrayToMap, - getFontFamilyString, - getShortcutKey, - tupleToCoors, -} from "../utils"; - -import { updateElbowArrowPoints } from "../element/elbowArrow"; import { register } from "./register"; -import type { - Arrowhead, - ExcalidrawBindableElement, - ExcalidrawElement, - ExcalidrawLinearElement, - ExcalidrawTextElement, - FontFamilyValues, - TextAlign, - VerticalAlign, - NonDeletedSceneElementsMap, -} from "../element/types"; import type { CaptureUpdateActionType } from "../store"; import type { AppClassProperties, AppState, Primitive } from "../types"; diff --git a/packages/excalidraw/actions/actionSelectAll.ts b/packages/excalidraw/actions/actionSelectAll.ts index 5f6d7eabc5..d7775774ae 100644 --- a/packages/excalidraw/actions/actionSelectAll.ts +++ b/packages/excalidraw/actions/actionSelectAll.ts @@ -1,14 +1,18 @@ -import { selectAllIcon } from "../components/icons"; -import { getNonDeletedElements, isTextElement } from "../element"; -import { LinearElementEditor } from "../element/linearElementEditor"; -import { isLinearElement } from "../element/typeChecks"; -import { selectGroupsForSelectedElements } from "../groups"; -import { KEYS } from "../keys"; +import { getNonDeletedElements } from "@excalidraw/element"; +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; +import { isLinearElement, isTextElement } from "@excalidraw/element/typeChecks"; + +import { KEYS } from "@excalidraw/common"; + +import { selectGroupsForSelectedElements } from "@excalidraw/element/groups"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { CaptureUpdateAction } from "../store"; -import { register } from "./register"; +import { selectAllIcon } from "../components/icons"; -import type { ExcalidrawElement } from "../element/types"; +import { register } from "./register"; export const actionSelectAll = register({ name: "selectAll", diff --git a/packages/excalidraw/actions/actionStyles.ts b/packages/excalidraw/actions/actionStyles.ts index ea517c4422..ed3c91e304 100644 --- a/packages/excalidraw/actions/actionStyles.ts +++ b/packages/excalidraw/actions/actionStyles.ts @@ -1,33 +1,39 @@ -import { paintIcon } from "../components/icons"; import { DEFAULT_FONT_SIZE, DEFAULT_FONT_FAMILY, DEFAULT_TEXT_ALIGN, -} from "../constants"; -import { - isTextElement, - isExcalidrawElement, - redrawTextBoundingBox, -} from "../element"; -import { newElementWith } from "../element/mutateElement"; -import { getBoundTextElement } from "../element/textElement"; + CODES, + KEYS, + getLineHeight, +} from "@excalidraw/common"; + +import { newElementWith } from "@excalidraw/element/mutateElement"; + import { hasBoundTextElement, canApplyRoundnessTypeToElement, getDefaultRoundnessTypeForElement, isFrameLikeElement, isArrowElement, -} from "../element/typeChecks"; -import { getLineHeight } from "../fonts"; + isExcalidrawElement, + isTextElement, +} from "@excalidraw/element/typeChecks"; + +import { + getBoundTextElement, + redrawTextBoundingBox, +} from "@excalidraw/element/textElement"; + +import type { ExcalidrawTextElement } from "@excalidraw/element/types"; + +import { paintIcon } from "../components/icons"; + import { t } from "../i18n"; -import { CODES, KEYS } from "../keys"; import { getSelectedElements } from "../scene"; import { CaptureUpdateAction } from "../store"; import { register } from "./register"; -import type { ExcalidrawTextElement } from "../element/types"; - // `copiedStyles` is exported only for tests. export let copiedStyles: string = "{}"; diff --git a/packages/excalidraw/actions/actionTextAutoResize.ts b/packages/excalidraw/actions/actionTextAutoResize.ts index b9ad7783f0..4a36cab408 100644 --- a/packages/excalidraw/actions/actionTextAutoResize.ts +++ b/packages/excalidraw/actions/actionTextAutoResize.ts @@ -1,9 +1,12 @@ -import { isTextElement } from "../element"; -import { newElementWith } from "../element/mutateElement"; -import { measureText } from "../element/textMeasurements"; +import { getFontString } from "@excalidraw/common"; + +import { newElementWith } from "@excalidraw/element/mutateElement"; +import { measureText } from "@excalidraw/element/textMeasurements"; + +import { isTextElement } from "@excalidraw/element/typeChecks"; + import { getSelectedElements } from "../scene"; import { CaptureUpdateAction } from "../store"; -import { getFontString } from "../utils"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionToggleGridMode.tsx b/packages/excalidraw/actions/actionToggleGridMode.tsx index 98360e8430..9415051f38 100644 --- a/packages/excalidraw/actions/actionToggleGridMode.tsx +++ b/packages/excalidraw/actions/actionToggleGridMode.tsx @@ -1,5 +1,6 @@ +import { CODES, KEYS } from "@excalidraw/common"; + import { gridIcon } from "../components/icons"; -import { CODES, KEYS } from "../keys"; import { CaptureUpdateAction } from "../store"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionToggleObjectsSnapMode.tsx b/packages/excalidraw/actions/actionToggleObjectsSnapMode.tsx index d511241326..ba092bff8b 100644 --- a/packages/excalidraw/actions/actionToggleObjectsSnapMode.tsx +++ b/packages/excalidraw/actions/actionToggleObjectsSnapMode.tsx @@ -1,5 +1,6 @@ +import { CODES, KEYS } from "@excalidraw/common"; + import { magnetIcon } from "../components/icons"; -import { CODES, KEYS } from "../keys"; import { CaptureUpdateAction } from "../store"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionToggleSearchMenu.ts b/packages/excalidraw/actions/actionToggleSearchMenu.ts index 75d9074c84..ce384fc665 100644 --- a/packages/excalidraw/actions/actionToggleSearchMenu.ts +++ b/packages/excalidraw/actions/actionToggleSearchMenu.ts @@ -1,6 +1,11 @@ +import { + KEYS, + CANVAS_SEARCH_TAB, + CLASSES, + DEFAULT_SIDEBAR, +} from "@excalidraw/common"; + import { searchIcon } from "../components/icons"; -import { CANVAS_SEARCH_TAB, CLASSES, DEFAULT_SIDEBAR } from "../constants"; -import { KEYS } from "../keys"; import { CaptureUpdateAction } from "../store"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionToggleStats.tsx b/packages/excalidraw/actions/actionToggleStats.tsx index d0cdc64a37..93fd6395ba 100644 --- a/packages/excalidraw/actions/actionToggleStats.tsx +++ b/packages/excalidraw/actions/actionToggleStats.tsx @@ -1,5 +1,6 @@ +import { CODES, KEYS } from "@excalidraw/common"; + import { abacusIcon } from "../components/icons"; -import { CODES, KEYS } from "../keys"; import { CaptureUpdateAction } from "../store"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionToggleViewMode.tsx b/packages/excalidraw/actions/actionToggleViewMode.tsx index 0551352638..81faa9ee61 100644 --- a/packages/excalidraw/actions/actionToggleViewMode.tsx +++ b/packages/excalidraw/actions/actionToggleViewMode.tsx @@ -1,5 +1,6 @@ +import { CODES, KEYS } from "@excalidraw/common"; + import { eyeIcon } from "../components/icons"; -import { CODES, KEYS } from "../keys"; import { CaptureUpdateAction } from "../store"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionToggleZenMode.tsx b/packages/excalidraw/actions/actionToggleZenMode.tsx index 31c72bf95c..4d45b32046 100644 --- a/packages/excalidraw/actions/actionToggleZenMode.tsx +++ b/packages/excalidraw/actions/actionToggleZenMode.tsx @@ -1,5 +1,6 @@ +import { CODES, KEYS } from "@excalidraw/common"; + import { coffeeIcon } from "../components/icons"; -import { CODES, KEYS } from "../keys"; import { CaptureUpdateAction } from "../store"; import { register } from "./register"; diff --git a/packages/excalidraw/actions/actionZindex.tsx b/packages/excalidraw/actions/actionZindex.tsx index 82d3d77dac..8eb5a50f27 100644 --- a/packages/excalidraw/actions/actionZindex.tsx +++ b/packages/excalidraw/actions/actionZindex.tsx @@ -1,20 +1,20 @@ +import { KEYS, CODES, getShortcutKey, isDarwin } from "@excalidraw/common"; + +import { + moveOneLeft, + moveOneRight, + moveAllLeft, + moveAllRight, +} from "@excalidraw/element/zindex"; + import { BringForwardIcon, BringToFrontIcon, SendBackwardIcon, SendToBackIcon, } from "../components/icons"; -import { isDarwin } from "../constants"; import { t } from "../i18n"; -import { KEYS, CODES } from "../keys"; import { CaptureUpdateAction } from "../store"; -import { getShortcutKey } from "../utils"; -import { - moveOneLeft, - moveOneRight, - moveAllLeft, - moveAllRight, -} from "../zindex"; import { register } from "./register"; @@ -24,9 +24,9 @@ export const actionSendBackward = register({ keywords: ["move down", "zindex", "layer"], icon: SendBackwardIcon, trackEvent: { category: "element" }, - perform: (elements, appState) => { + perform: (elements, appState, value, app) => { return { - elements: moveOneLeft(elements, appState), + elements: moveOneLeft(elements, appState, app.scene), appState, captureUpdate: CaptureUpdateAction.IMMEDIATELY, }; @@ -54,9 +54,9 @@ export const actionBringForward = register({ keywords: ["move up", "zindex", "layer"], icon: BringForwardIcon, trackEvent: { category: "element" }, - perform: (elements, appState) => { + perform: (elements, appState, value, app) => { return { - elements: moveOneRight(elements, appState), + elements: moveOneRight(elements, appState, app.scene), appState, captureUpdate: CaptureUpdateAction.IMMEDIATELY, }; diff --git a/packages/excalidraw/actions/index.ts b/packages/excalidraw/actions/index.ts index a556bfbeaf..f37747aebd 100644 --- a/packages/excalidraw/actions/index.ts +++ b/packages/excalidraw/actions/index.ts @@ -30,6 +30,8 @@ export { actionToggleTheme, } from "./actionCanvas"; +export { actionSetEmbeddableAsActiveTool } from "./actionEmbeddable"; + export { actionFinalize } from "./actionFinalize"; export { diff --git a/packages/excalidraw/actions/manager.tsx b/packages/excalidraw/actions/manager.tsx index d3609640e4..171bb5df71 100644 --- a/packages/excalidraw/actions/manager.tsx +++ b/packages/excalidraw/actions/manager.tsx @@ -1,12 +1,14 @@ import React from "react"; -import { trackEvent } from "../analytics"; -import { isPromiseLike } from "../utils"; +import { isPromiseLike } from "@excalidraw/common"; import type { ExcalidrawElement, OrderedExcalidrawElement, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import { trackEvent } from "../analytics"; + import type { AppClassProperties, AppState } from "../types"; import type { Action, diff --git a/packages/excalidraw/actions/shortcuts.ts b/packages/excalidraw/actions/shortcuts.ts index 89a7c5ae24..1a13f1703c 100644 --- a/packages/excalidraw/actions/shortcuts.ts +++ b/packages/excalidraw/actions/shortcuts.ts @@ -1,8 +1,9 @@ -import { isDarwin } from "../constants"; -import { t } from "../i18n"; -import { getShortcutKey } from "../utils"; +import { isDarwin, getShortcutKey } from "@excalidraw/common"; + +import type { SubtypeOf } from "@excalidraw/common/utility-types"; + +import { t } from "../i18n"; -import type { SubtypeOf } from "../utility-types"; import type { ActionName } from "./types"; export type ShortcutName = diff --git a/packages/excalidraw/actions/types.ts b/packages/excalidraw/actions/types.ts index c30f53f5ea..152b9a0c7e 100644 --- a/packages/excalidraw/actions/types.ts +++ b/packages/excalidraw/actions/types.ts @@ -1,7 +1,8 @@ import type { ExcalidrawElement, OrderedExcalidrawElement, -} from "../element/types"; +} from "@excalidraw/element/types"; + import type { CaptureUpdateActionType } from "../store"; import type { AppClassProperties, diff --git a/packages/excalidraw/analytics.ts b/packages/excalidraw/analytics.ts index edcd07b585..a1d31e4db3 100644 --- a/packages/excalidraw/analytics.ts +++ b/packages/excalidraw/analytics.ts @@ -1,6 +1,6 @@ // place here categories that you want to track. We want to track just a -import { isDevEnv } from "./utils"; +import { isDevEnv } from "@excalidraw/common"; // small subset of categories at a given time. const ALLOWED_CATEGORIES_TO_TRACK = new Set(["command_palette", "export"]); diff --git a/packages/excalidraw/animated-trail.ts b/packages/excalidraw/animated-trail.ts index a204607719..286eff6f34 100644 --- a/packages/excalidraw/animated-trail.ts +++ b/packages/excalidraw/animated-trail.ts @@ -1,9 +1,12 @@ import { LaserPointer } from "@excalidraw/laser-pointer"; -import type { LaserPointerOptions } from "@excalidraw/laser-pointer"; +import { + SVG_NS, + getSvgPathFromStroke, + sceneCoordsToViewportCoords, +} from "@excalidraw/common"; -import { SVG_NS } from "./constants"; -import { getSvgPathFromStroke, sceneCoordsToViewportCoords } from "./utils"; +import type { LaserPointerOptions } from "@excalidraw/laser-pointer"; import type { AnimationFrameHandler } from "./animation-frame-handler"; import type App from "./components/App"; diff --git a/packages/excalidraw/appState.ts b/packages/excalidraw/appState.ts index acda8468b0..434392ce74 100644 --- a/packages/excalidraw/appState.ts +++ b/packages/excalidraw/appState.ts @@ -1,5 +1,5 @@ -import { COLOR_PALETTE } from "./colors"; import { + COLOR_PALETTE, ARROW_TYPE, DEFAULT_ELEMENT_PROPS, DEFAULT_FONT_FAMILY, @@ -10,7 +10,7 @@ import { STATS_PANELS, THEME, DEFAULT_GRID_STEP, -} from "./constants"; +} from "@excalidraw/common"; import type { AppState, NormalizedZoomValue } from "./types"; diff --git a/packages/excalidraw/change.ts b/packages/excalidraw/change.ts index 492b7f79ec..28eaf994fc 100644 --- a/packages/excalidraw/change.ts +++ b/packages/excalidraw/change.ts @@ -1,25 +1,3 @@ -import { - BoundElement, - BindableElement, - bindingProperties, - updateBoundElements, -} from "./element/binding"; -import { LinearElementEditor } from "./element/linearElementEditor"; -import { mutateElement, newElementWith } from "./element/mutateElement"; -import { - getBoundTextElementId, - redrawTextBoundingBox, -} from "./element/textElement"; -import { - hasBoundTextElement, - isBindableElement, - isBoundToContainer, - isImageElement, - isTextElement, -} from "./element/typeChecks"; -import { orderByFractionalIndex, syncMovedIndices } from "./fractionalIndex"; -import { getNonDeletedGroupIds } from "./groups"; -import { getObservedAppState } from "./store"; import { arrayToMap, arrayToObject, @@ -28,10 +6,41 @@ import { isShallowEqual, isTestEnv, toBrandedType, -} from "./utils"; +} from "@excalidraw/common"; +import { + BoundElement, + BindableElement, + bindingProperties, + updateBoundElements, +} from "@excalidraw/element/binding"; +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; +import { + mutateElement, + newElementWith, +} from "@excalidraw/element/mutateElement"; +import { + getBoundTextElementId, + redrawTextBoundingBox, +} from "@excalidraw/element/textElement"; +import { + hasBoundTextElement, + isBindableElement, + isBoundToContainer, + isImageElement, + isTextElement, +} from "@excalidraw/element/typeChecks"; + +import { getNonDeletedGroupIds } from "@excalidraw/element/groups"; + +import { + orderByFractionalIndex, + syncMovedIndices, +} from "@excalidraw/element/fractionalIndex"; + +import type { BindableProp, BindingProp } from "@excalidraw/element/binding"; + +import type { ElementUpdate } from "@excalidraw/element/mutateElement"; -import type { BindableProp, BindingProp } from "./element/binding"; -import type { ElementUpdate } from "./element/mutateElement"; import type { ExcalidrawElement, ExcalidrawImageElement, @@ -41,14 +50,18 @@ import type { Ordered, OrderedExcalidrawElement, SceneElementsMap, -} from "./element/types"; +} from "@excalidraw/element/types"; + +import type { SubtypeOf, ValueOf } from "@excalidraw/common/utility-types"; + +import { getObservedAppState } from "./store"; + import type { AppState, ObservedAppState, ObservedElementsAppState, ObservedStandaloneAppState, } from "./types"; -import type { SubtypeOf, ValueOf } from "./utility-types"; /** * Represents the difference between two objects of the same type. diff --git a/packages/excalidraw/charts.ts b/packages/excalidraw/charts.ts index 20fa8e87a5..7a221d5473 100644 --- a/packages/excalidraw/charts.ts +++ b/packages/excalidraw/charts.ts @@ -1,23 +1,25 @@ import { pointFrom } from "@excalidraw/math"; -import type { Radians } from "@excalidraw/math"; - import { COLOR_PALETTE, DEFAULT_CHART_COLOR_INDEX, getAllColorsSpecificShade, -} from "./colors"; -import { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, VERTICAL_ALIGN, -} from "./constants"; -import { newElement, newLinearElement, newTextElement } from "./element"; -import { randomId } from "./random"; + randomId, + isDevEnv, +} from "@excalidraw/common"; -import { isDevEnv } from "./utils"; +import { + newTextElement, + newLinearElement, + newElement, +} from "@excalidraw/element/newElement"; -import type { NonDeletedExcalidrawElement } from "./element/types"; +import type { Radians } from "@excalidraw/math"; + +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; export type ChartElements = readonly NonDeletedExcalidrawElement[]; diff --git a/packages/excalidraw/clients.ts b/packages/excalidraw/clients.ts index 6cf4613a8b..9467b13620 100644 --- a/packages/excalidraw/clients.ts +++ b/packages/excalidraw/clients.ts @@ -4,7 +4,8 @@ import { COLOR_WHITE, THEME, UserIdleState, -} from "./constants"; +} from "@excalidraw/common"; + import { roundRect } from "./renderer/roundRect"; import type { InteractiveCanvasRenderConfig } from "./scene/types"; diff --git a/packages/excalidraw/clipboard.ts b/packages/excalidraw/clipboard.ts index 397c350ffc..40e4f8b96d 100644 --- a/packages/excalidraw/clipboard.ts +++ b/packages/excalidraw/clipboard.ts @@ -1,26 +1,32 @@ -import { tryParseSpreadsheet, VALID_SPREADSHEET } from "./charts"; import { ALLOWED_PASTE_MIME_TYPES, EXPORT_DATA_TYPES, MIME_TYPES, -} from "./constants"; -import { createFile, isSupportedImageFileType } from "./data/blob"; -import { mutateElement } from "./element/mutateElement"; + arrayToMap, + isMemberOf, + isPromiseLike, +} from "@excalidraw/common"; + +import { mutateElement } from "@excalidraw/element/mutateElement"; +import { deepCopyElement } from "@excalidraw/element/duplicate"; import { isFrameLikeElement, isInitializedImageElement, -} from "./element/typeChecks"; -import { ExcalidrawError } from "./errors"; -import { getContainingFrame } from "./frame"; -import { arrayToMap, isMemberOf, isPromiseLike } from "./utils"; +} from "@excalidraw/element/typeChecks"; -import { deepCopyElement } from "./element/duplicate"; +import { getContainingFrame } from "@excalidraw/element/frame"; -import type { Spreadsheet } from "./charts"; import type { ExcalidrawElement, NonDeletedExcalidrawElement, -} from "./element/types"; +} from "@excalidraw/element/types"; + +import { ExcalidrawError } from "./errors"; +import { createFile, isSupportedImageFileType } from "./data/blob"; +import { tryParseSpreadsheet, VALID_SPREADSHEET } from "./charts"; + +import type { Spreadsheet } from "./charts"; + import type { BinaryFiles } from "./types"; type ElementsClipboard = { diff --git a/packages/excalidraw/components/Actions.tsx b/packages/excalidraw/components/Actions.tsx index c74c1ad852..b692048673 100644 --- a/packages/excalidraw/components/Actions.tsx +++ b/packages/excalidraw/components/Actions.tsx @@ -1,24 +1,41 @@ import clsx from "clsx"; import { useState } from "react"; -import { actionToggleZenMode } from "../actions"; +import { + CLASSES, + KEYS, + capitalizeString, + isTransparent, +} from "@excalidraw/common"; -import { KEYS } from "../keys"; -import { CLASSES } from "../constants"; -import { alignActionsPredicate } from "../actions/actionAlign"; -import { trackEvent } from "../analytics"; -import { useTunnels } from "../context/tunnels"; import { shouldAllowVerticalAlign, suppportsHorizontalAlign, -} from "../element/textElement"; +} from "@excalidraw/element/textElement"; + import { hasBoundTextElement, isElbowArrow, isImageElement, isLinearElement, isTextElement, -} from "../element/typeChecks"; +} from "@excalidraw/element/typeChecks"; + +import { hasStrokeColor, toolIsArrow } from "@excalidraw/element/comparisons"; + +import type { + ExcalidrawElement, + ExcalidrawElementType, + NonDeletedElementsMap, + NonDeletedSceneElementsMap, +} from "@excalidraw/element/types"; + +import { actionToggleZenMode } from "../actions"; + +import { alignActionsPredicate } from "../actions/actionAlign"; +import { trackEvent } from "../analytics"; +import { useTunnels } from "../context/tunnels"; + import { t } from "../i18n"; import { canChangeRoundness, @@ -28,9 +45,8 @@ import { hasStrokeStyle, hasStrokeWidth, } from "../scene"; -import { hasStrokeColor, toolIsArrow } from "../scene/comparisons"; -import { SHAPES } from "../shapes"; -import { capitalizeString, isTransparent } from "../utils"; + +import { SHAPES } from "./shapes"; import "./Actions.scss"; @@ -48,12 +64,6 @@ import { MagicIcon, } from "./icons"; -import type { - ExcalidrawElement, - ExcalidrawElementType, - NonDeletedElementsMap, - NonDeletedSceneElementsMap, -} from "../element/types"; import type { AppClassProperties, AppProps, UIAppState, Zoom } from "../types"; import type { ActionManager } from "../actions/manager"; diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index af8c13d7bb..d5fb55e1d5 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -1,3 +1,10 @@ +import clsx from "clsx"; +import throttle from "lodash.throttle"; +import React, { useContext } from "react"; +import { flushSync } from "react-dom"; +import rough from "roughjs/bin/rough"; +import { nanoid } from "nanoid"; + import { clamp, pointFrom, @@ -11,16 +18,318 @@ import { vectorNormalize, } from "@excalidraw/math"; import { isPointInShape } from "@excalidraw/utils/collision"; -import { getSelectionBoxShape } from "@excalidraw/utils/geometry/shape"; -import clsx from "clsx"; -import throttle from "lodash.throttle"; -import { nanoid } from "nanoid"; -import React, { useContext } from "react"; -import { flushSync } from "react-dom"; -import rough from "roughjs/bin/rough"; +import { getSelectionBoxShape } from "@excalidraw/utils/shape"; + +import { + COLOR_PALETTE, + CODES, + shouldResizeFromCenter, + shouldMaintainAspectRatio, + shouldRotateWithDiscreteAngle, + isArrowKey, + KEYS, + APP_NAME, + CURSOR_TYPE, + DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT, + DEFAULT_VERTICAL_ALIGN, + DRAGGING_THRESHOLD, + ELEMENT_SHIFT_TRANSLATE_AMOUNT, + ELEMENT_TRANSLATE_AMOUNT, + EVENT, + FRAME_STYLE, + IMAGE_MIME_TYPES, + IMAGE_RENDER_TIMEOUT, + isBrave, + LINE_CONFIRM_THRESHOLD, + MAX_ALLOWED_FILE_BYTES, + MIME_TYPES, + MQ_MAX_HEIGHT_LANDSCAPE, + MQ_MAX_WIDTH_LANDSCAPE, + MQ_MAX_WIDTH_PORTRAIT, + MQ_RIGHT_SIDEBAR_MIN_WIDTH, + POINTER_BUTTON, + ROUNDNESS, + SCROLL_TIMEOUT, + TAP_TWICE_TIMEOUT, + TEXT_TO_CENTER_SNAP_THRESHOLD, + THEME, + THEME_FILTER, + TOUCH_CTX_MENU_TIMEOUT, + VERTICAL_ALIGN, + YOUTUBE_STATES, + ZOOM_STEP, + POINTER_EVENTS, + TOOL_TYPE, + isIOS, + supportsResizeObserver, + DEFAULT_COLLISION_THRESHOLD, + DEFAULT_TEXT_ALIGN, + ARROW_TYPE, + DEFAULT_REDUCED_GLOBAL_ALPHA, + isSafari, + isLocalLink, + normalizeLink, + toValidURL, + getGridPoint, + getLineHeight, + debounce, + distance, + getFontString, + getNearestScrollableContainer, + isInputLike, + isToolIcon, + isWritableElement, + sceneCoordsToViewportCoords, + tupleToCoors, + viewportCoordsToSceneCoords, + wrapEvent, + updateObject, + updateActiveTool, + getShortcutKey, + isTransparent, + easeToValuesRAF, + muteFSAbortError, + isTestEnv, + isDevEnv, + easeOut, + updateStable, + addEventListener, + normalizeEOL, + getDateTime, + isShallowEqual, + arrayToMap, + type EXPORT_IMAGE_TYPES, +} from "@excalidraw/common"; + +import { + getCommonBounds, + getElementAbsoluteCoords, +} from "@excalidraw/element/bounds"; + +import { + bindOrUnbindLinearElement, + bindOrUnbindLinearElements, + fixBindingsAfterDeletion, + getHoveredElementForBinding, + isBindingEnabled, + isLinearElementSimpleAndAlreadyBound, + maybeBindLinearElement, + shouldEnableBindingForPointerEvent, + updateBoundElements, + getSuggestedBindingsForArrows, +} from "@excalidraw/element/binding"; + +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; + +import { + mutateElement, + newElementWith, +} from "@excalidraw/element/mutateElement"; + +import { + newFrameElement, + newFreeDrawElement, + newEmbeddableElement, + newMagicFrameElement, + newIframeElement, + newArrowElement, + newElement, + newImageElement, + newLinearElement, + newTextElement, + refreshTextDimensions, +} from "@excalidraw/element/newElement"; + +import { + deepCopyElement, + duplicateElements, +} from "@excalidraw/element/duplicate"; + +import { + hasBoundTextElement, + isArrowElement, + isBindingElement, + isBindingElementType, + isBoundToContainer, + isFrameLikeElement, + isImageElement, + isEmbeddableElement, + isInitializedImageElement, + isLinearElement, + isLinearElementType, + isUsingAdaptiveRadius, + isIframeElement, + isIframeLikeElement, + isMagicFrameElement, + isTextBindableContainer, + isElbowArrow, + isFlowchartNodeElement, + isBindableElement, + isTextElement, +} from "@excalidraw/element/typeChecks"; + +import { + getLockedLinearCursorAlignSize, + getNormalizedDimensions, + isElementCompletelyInViewport, + isElementInViewport, + isInvisiblySmallElement, +} from "@excalidraw/element/sizeHelpers"; + +import { + getBoundTextShape, + getCornerRadius, + getElementShape, + isPathALoop, +} from "@excalidraw/element/shapes"; + +import { + createSrcDoc, + embeddableURLValidator, + maybeParseEmbedSrc, + getEmbedLink, +} from "@excalidraw/element/embeddable"; + +import { + getInitializedImageElements, + loadHTMLImageElement, + normalizeSVG, + updateImageCache as _updateImageCache, +} from "@excalidraw/element/image"; + +import { + getBoundTextElement, + getContainerCenter, + getContainerElement, + isValidTextContainer, + redrawTextBoundingBox, +} from "@excalidraw/element/textElement"; + +import { shouldShowBoundingBox } from "@excalidraw/element/transformHandles"; + +import { + getFrameChildren, + isCursorInFrame, + addElementsToFrame, + replaceAllElementsInFrame, + removeElementsFromFrame, + getElementsInResizingFrame, + getElementsInNewFrame, + getContainingFrame, + elementOverlapsWithFrame, + updateFrameMembershipOfSelectedElements, + isElementInFrame, + getFrameLikeTitle, + getElementsOverlappingFrame, + filterElementsEligibleAsFrameChildren, +} from "@excalidraw/element/frame"; + +import { + hitElementBoundText, + hitElementBoundingBoxOnly, + hitElementItself, +} from "@excalidraw/element/collision"; + +import { getVisibleSceneBounds } from "@excalidraw/element/bounds"; + +import { + FlowChartCreator, + FlowChartNavigator, + getLinkDirectionFromKey, +} from "@excalidraw/element/flowchart"; + +import { cropElement } from "@excalidraw/element/cropElement"; + +import { wrapText } from "@excalidraw/element/textWrapping"; + +import { + isElementLink, + parseElementLinkFromURL, +} from "@excalidraw/element/elementLink"; + +import { + isMeasureTextSupported, + normalizeText, + measureText, + getLineHeightInPx, + getApproxMinLineWidth, + getApproxMinLineHeight, + getMinTextElementWidth, +} from "@excalidraw/element/textMeasurements"; + +import { ShapeCache } from "@excalidraw/element/ShapeCache"; + +import { getRenderOpacity } from "@excalidraw/element/renderElement"; + +import { + editGroupForSelectedElement, + getElementsInGroup, + getSelectedGroupIdForElement, + getSelectedGroupIds, + isElementInGroup, + isSelectedViaGroup, + selectGroupsForSelectedElements, +} from "@excalidraw/element/groups"; + +import { + syncInvalidIndices, + syncMovedIndices, +} from "@excalidraw/element/fractionalIndex"; + +import { + excludeElementsInFramesFromSelection, + makeNextSelectedElementIds, +} from "@excalidraw/element/selection"; + +import { + getResizeOffsetXY, + getResizeArrowDirection, + transformElements, +} from "@excalidraw/element/resizeElements"; + +import { + getCursorForResizingElement, + getElementWithTransformHandleType, + getTransformHandleTypeFromCoords, +} from "@excalidraw/element/resizeTest"; + +import { + dragNewElement, + dragSelectedElements, + getDragOffsetXY, +} from "@excalidraw/element/dragElements"; + +import { isNonDeletedElement } from "@excalidraw/element"; import type { LocalPoint, Radians } from "@excalidraw/math"; +import type { + ExcalidrawBindableElement, + ExcalidrawElement, + ExcalidrawFreeDrawElement, + ExcalidrawGenericElement, + ExcalidrawLinearElement, + ExcalidrawTextElement, + NonDeleted, + InitializedExcalidrawImageElement, + ExcalidrawImageElement, + FileId, + NonDeletedExcalidrawElement, + ExcalidrawTextContainer, + ExcalidrawFrameLikeElement, + ExcalidrawMagicFrameElement, + ExcalidrawIframeLikeElement, + IframeData, + ExcalidrawIframeElement, + ExcalidrawEmbeddableElement, + Ordered, + MagicGenerationData, + ExcalidrawNonSelectionElement, + ExcalidrawArrowElement, +} from "@excalidraw/element/types"; + +import type { ValueOf } from "@excalidraw/common/utility-types"; + import { actionAddToLibrary, actionBringForward, @@ -77,143 +386,13 @@ import { isHandToolActive, } from "../appState"; import { copyTextToSystemClipboard, parseClipboard } from "../clipboard"; -import { - APP_NAME, - CURSOR_TYPE, - DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT, - DEFAULT_VERTICAL_ALIGN, - DRAGGING_THRESHOLD, - ELEMENT_SHIFT_TRANSLATE_AMOUNT, - ELEMENT_TRANSLATE_AMOUNT, - EVENT, - FRAME_STYLE, - IMAGE_MIME_TYPES, - IMAGE_RENDER_TIMEOUT, - isBrave, - LINE_CONFIRM_THRESHOLD, - MAX_ALLOWED_FILE_BYTES, - MIME_TYPES, - MQ_MAX_HEIGHT_LANDSCAPE, - MQ_MAX_WIDTH_LANDSCAPE, - MQ_MAX_WIDTH_PORTRAIT, - MQ_RIGHT_SIDEBAR_MIN_WIDTH, - POINTER_BUTTON, - ROUNDNESS, - SCROLL_TIMEOUT, - TAP_TWICE_TIMEOUT, - TEXT_TO_CENTER_SNAP_THRESHOLD, - THEME, - THEME_FILTER, - TOUCH_CTX_MENU_TIMEOUT, - VERTICAL_ALIGN, - YOUTUBE_STATES, - ZOOM_STEP, - POINTER_EVENTS, - TOOL_TYPE, - isIOS, - supportsResizeObserver, - DEFAULT_COLLISION_THRESHOLD, - DEFAULT_TEXT_ALIGN, - ARROW_TYPE, - DEFAULT_REDUCED_GLOBAL_ALPHA, - isSafari, - type EXPORT_IMAGE_TYPES, -} from "../constants"; import { exportCanvas, loadFromBlob } from "../data"; import Library, { distributeLibraryItemsOnSquareGrid } from "../data/library"; import { restore, restoreElements } from "../data/restore"; -import { - dragNewElement, - dragSelectedElements, - getCommonBounds, - getCursorForResizingElement, - getDragOffsetXY, - getElementWithTransformHandleType, - getNormalizedDimensions, - getResizeArrowDirection, - getResizeOffsetXY, - getLockedLinearCursorAlignSize, - getTransformHandleTypeFromCoords, - isInvisiblySmallElement, - isNonDeletedElement, - isTextElement, - newElement, - newLinearElement, - newTextElement, - newImageElement, - transformElements, - refreshTextDimensions, - redrawTextBoundingBox, - getElementAbsoluteCoords, -} from "../element"; -import { - bindOrUnbindLinearElement, - bindOrUnbindLinearElements, - fixBindingsAfterDeletion, - getHoveredElementForBinding, - isBindingEnabled, - isLinearElementSimpleAndAlreadyBound, - maybeBindLinearElement, - shouldEnableBindingForPointerEvent, - updateBoundElements, - getSuggestedBindingsForArrows, -} from "../element/binding"; -import { LinearElementEditor } from "../element/linearElementEditor"; -import { mutateElement, newElementWith } from "../element/mutateElement"; -import { deepCopyElement, duplicateElements } from "../element/duplicate"; -import { - newFrameElement, - newFreeDrawElement, - newEmbeddableElement, - newMagicFrameElement, - newIframeElement, - newArrowElement, -} from "../element/newElement"; -import { - hasBoundTextElement, - isArrowElement, - isBindingElement, - isBindingElementType, - isBoundToContainer, - isFrameLikeElement, - isImageElement, - isEmbeddableElement, - isInitializedImageElement, - isLinearElement, - isLinearElementType, - isUsingAdaptiveRadius, - isIframeElement, - isIframeLikeElement, - isMagicFrameElement, - isTextBindableContainer, - isElbowArrow, - isFlowchartNodeElement, - isBindableElement, -} from "../element/typeChecks"; import { getCenter, getDistance } from "../gesture"; -import { - editGroupForSelectedElement, - getElementsInGroup, - getSelectedGroupIdForElement, - getSelectedGroupIds, - isElementInGroup, - isSelectedViaGroup, - selectGroupsForSelectedElements, -} from "../groups"; import { History } from "../history"; import { defaultLang, getLanguage, languages, setLanguage, t } from "../i18n"; -import { - CODES, - shouldResizeFromCenter, - shouldMaintainAspectRatio, - shouldRotateWithDiscreteAngle, - isArrowKey, - KEYS, -} from "../keys"; -import { - isElementCompletelyInViewport, - isElementInViewport, -} from "../element/sizeHelpers"; + import { calculateScrollCenter, getElementsWithinSelection, @@ -224,47 +403,6 @@ import { } from "../scene"; import Scene from "../scene/Scene"; import { getStateForZoom } from "../scene/zoom"; -import { - findShapeByKey, - getBoundTextShape, - getCornerRadius, - getElementShape, - isPathALoop, -} from "../shapes"; -import { - debounce, - distance, - getFontString, - getNearestScrollableContainer, - isInputLike, - isToolIcon, - isWritableElement, - sceneCoordsToViewportCoords, - tupleToCoors, - viewportCoordsToSceneCoords, - wrapEvent, - updateObject, - updateActiveTool, - getShortcutKey, - isTransparent, - easeToValuesRAF, - muteFSAbortError, - isTestEnv, - easeOut, - updateStable, - addEventListener, - normalizeEOL, - getDateTime, - isShallowEqual, - arrayToMap, - isDevEnv, -} from "../utils"; -import { - createSrcDoc, - embeddableURLValidator, - maybeParseEmbedSrc, - getEmbedLink, -} from "../element/embeddable"; import { dataURLToFile, dataURLToString, @@ -281,47 +419,15 @@ import { resizeImageFile, SVGStringToFile, } from "../data/blob"; -import { - getInitializedImageElements, - loadHTMLImageElement, - normalizeSVG, - updateImageCache as _updateImageCache, -} from "../element/image"; + import { fileOpen } from "../data/filesystem"; -import { - getBoundTextElement, - getContainerCenter, - getContainerElement, - isValidTextContainer, -} from "../element/textElement"; import { showHyperlinkTooltip, hideHyperlinkToolip, Hyperlink, } from "../components/hyperlink/Hyperlink"; -import { isLocalLink, normalizeLink, toValidURL } from "../data/url"; -import { shouldShowBoundingBox } from "../element/transformHandles"; -import { Fonts, getLineHeight } from "../fonts"; -import { - getFrameChildren, - isCursorInFrame, - addElementsToFrame, - replaceAllElementsInFrame, - removeElementsFromFrame, - getElementsInResizingFrame, - getElementsInNewFrame, - getContainingFrame, - elementOverlapsWithFrame, - updateFrameMembershipOfSelectedElements, - isElementInFrame, - getFrameLikeTitle, - getElementsOverlappingFrame, - filterElementsEligibleAsFrameChildren, -} from "../frame"; -import { - excludeElementsInFramesFromSelection, - makeNextSelectedElementIds, -} from "../scene/selection"; + +import { Fonts } from "../fonts"; import { editorJotaiStore } from "../editor-jotai"; import { ImageSceneDataError } from "../errors"; import { @@ -335,11 +441,9 @@ import { getReferenceSnapPoints, SnapCache, isGridModeEnabled, - getGridPoint, } from "../snapping"; import { convertToExcalidrawElements } from "../data/transform"; import { Renderer } from "../scene/Renderer"; -import { ShapeCache } from "../scene/ShapeCache"; import { setEraserCursor, setCursor, @@ -347,40 +451,15 @@ import { setCursorForShape, } from "../cursor"; import { Emitter } from "../emitter"; -import { ElementCanvasButtons } from "../element/ElementCanvasButtons"; -import { COLOR_PALETTE } from "../colors"; +import { ElementCanvasButtons } from "../components/ElementCanvasButtons"; import { Store, CaptureUpdateAction } from "../store"; import { AnimatedTrail } from "../animated-trail"; import { LaserTrails } from "../laser-trails"; import { withBatchedUpdates, withBatchedUpdatesThrottled } from "../reactUtils"; -import { getRenderOpacity } from "../renderer/renderElement"; -import { - hitElementBoundText, - hitElementBoundingBoxOnly, - hitElementItself, -} from "../element/collision"; -import { textWysiwyg } from "../element/textWysiwyg"; +import { textWysiwyg } from "../wysiwyg/textWysiwyg"; import { isOverScrollBars } from "../scene/scrollbars"; -import { syncInvalidIndices, syncMovedIndices } from "../fractionalIndex"; -import { getVisibleSceneBounds } from "../element/bounds"; + import { isMaybeMermaidDefinition } from "../mermaid"; -import { - FlowChartCreator, - FlowChartNavigator, - getLinkDirectionFromKey, -} from "../element/flowchart"; -import { cropElement } from "../element/cropElement"; -import { wrapText } from "../element/textWrapping"; -import { isElementLink, parseElementLinkFromURL } from "../element/elementLink"; -import { - isMeasureTextSupported, - normalizeText, - measureText, - getLineHeightInPx, - getApproxMinLineWidth, - getApproxMinLineHeight, - getMinTextElementWidth, -} from "../element/textMeasurements"; import { activeConfirmDialogAtom } from "./ActiveConfirmDialog"; import BraveMeasureTextError from "./BraveMeasureTextError"; @@ -401,40 +480,19 @@ import { import { MagicIcon, copyIcon, fullscreenIcon } from "./icons"; import { Toast } from "./Toast"; -import type { Action, ActionResult } from "../actions/types"; +import { findShapeByKey } from "./shapes"; + +import type { + RenderInteractiveSceneCallback, + ScrollBars, +} from "../scene/types"; + import type { PastedMixedContent } from "../clipboard"; import type { ExportedElements } from "../data"; import type { ContextMenuItems } from "./ContextMenu"; import type { FileSystemHandle } from "../data/filesystem"; import type { ExcalidrawElementSkeleton } from "../data/transform"; -import type { - ExcalidrawBindableElement, - ExcalidrawElement, - ExcalidrawFreeDrawElement, - ExcalidrawGenericElement, - ExcalidrawLinearElement, - ExcalidrawTextElement, - NonDeleted, - InitializedExcalidrawImageElement, - ExcalidrawImageElement, - FileId, - NonDeletedExcalidrawElement, - ExcalidrawTextContainer, - ExcalidrawFrameLikeElement, - ExcalidrawMagicFrameElement, - ExcalidrawIframeLikeElement, - IframeData, - ExcalidrawIframeElement, - ExcalidrawEmbeddableElement, - Ordered, - MagicGenerationData, - ExcalidrawNonSelectionElement, - ExcalidrawArrowElement, -} from "../element/types"; -import type { - RenderInteractiveSceneCallback, - ScrollBars, -} from "../scene/types"; + import type { AppClassProperties, AppProps, @@ -463,8 +521,8 @@ import type { NullableGridSize, Offsets, } from "../types"; -import type { ValueOf } from "../utility-types"; import type { RoughCanvas } from "roughjs/bin/canvas"; +import type { Action, ActionResult } from "../actions/types"; const AppContext = React.createContext(null!); const AppPropsContext = React.createContext(null!); diff --git a/packages/excalidraw/components/Button.tsx b/packages/excalidraw/components/Button.tsx index 9512d607ff..acdd4afde7 100644 --- a/packages/excalidraw/components/Button.tsx +++ b/packages/excalidraw/components/Button.tsx @@ -1,7 +1,7 @@ import clsx from "clsx"; import React from "react"; -import { composeEventHandlers } from "../utils"; +import { composeEventHandlers } from "@excalidraw/common"; import "./Button.scss"; diff --git a/packages/excalidraw/components/ColorPicker/ColorInput.tsx b/packages/excalidraw/components/ColorPicker/ColorInput.tsx index dc7d572a34..a3f6722eb5 100644 --- a/packages/excalidraw/components/ColorPicker/ColorInput.tsx +++ b/packages/excalidraw/components/ColorPicker/ColorInput.tsx @@ -1,10 +1,10 @@ import clsx from "clsx"; import { useCallback, useEffect, useRef, useState } from "react"; +import { KEYS, getShortcutKey } from "@excalidraw/common"; + import { useAtom } from "../../editor-jotai"; import { t } from "../../i18n"; -import { KEYS } from "../../keys"; -import { getShortcutKey } from "../../utils"; import { useDevice } from "../App"; import { activeEyeDropperAtom } from "../EyeDropper"; import { eyeDropperIcon } from "../icons"; diff --git a/packages/excalidraw/components/ColorPicker/ColorPicker.tsx b/packages/excalidraw/components/ColorPicker/ColorPicker.tsx index 7f6ee8a85a..34f6c6d126 100644 --- a/packages/excalidraw/components/ColorPicker/ColorPicker.tsx +++ b/packages/excalidraw/components/ColorPicker/ColorPicker.tsx @@ -2,10 +2,14 @@ import * as Popover from "@radix-ui/react-popover"; import clsx from "clsx"; import { useRef } from "react"; -import { COLOR_PALETTE } from "../../colors"; +import { COLOR_PALETTE, isTransparent } from "@excalidraw/common"; + +import type { ColorTuple, ColorPaletteCustom } from "@excalidraw/common"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { useAtom } from "../../editor-jotai"; import { t } from "../../i18n"; -import { isTransparent } from "../../utils"; import { useExcalidrawContainer } from "../App"; import { ButtonSeparator } from "../ButtonSeparator"; import { activeEyeDropperAtom } from "../EyeDropper"; @@ -20,8 +24,7 @@ import { activeColorPickerSectionAtom } from "./colorPickerUtils"; import "./ColorPicker.scss"; import type { ColorPickerType } from "./colorPickerUtils"; -import type { ColorTuple, ColorPaletteCustom } from "../../colors"; -import type { ExcalidrawElement } from "../../element/types"; + import type { AppState } from "../../types"; const isValidColor = (color: string) => { diff --git a/packages/excalidraw/components/ColorPicker/Picker.tsx b/packages/excalidraw/components/ColorPicker/Picker.tsx index 9f311e9c1c..3c54c67695 100644 --- a/packages/excalidraw/components/ColorPicker/Picker.tsx +++ b/packages/excalidraw/components/ColorPicker/Picker.tsx @@ -1,13 +1,19 @@ import React, { useEffect, useState } from "react"; +import { EVENT } from "@excalidraw/common"; + import { DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX, DEFAULT_ELEMENT_STROKE_COLOR_INDEX, -} from "../../colors"; -import { EVENT } from "../../constants"; + KEYS, +} from "@excalidraw/common"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + +import type { ColorPaletteCustom } from "@excalidraw/common"; + import { useAtom } from "../../editor-jotai"; import { t } from "../../i18n"; -import { KEYS } from "../../keys"; import { CustomColorList } from "./CustomColorList"; import PickerColorList from "./PickerColorList"; @@ -22,8 +28,6 @@ import { import { colorPickerKeyNavHandler } from "./keyboardNavHandlers"; import type { ColorPickerType } from "./colorPickerUtils"; -import type { ColorPaletteCustom } from "../../colors"; -import type { ExcalidrawElement } from "../../element/types"; interface PickerProps { color: string; diff --git a/packages/excalidraw/components/ColorPicker/PickerColorList.tsx b/packages/excalidraw/components/ColorPicker/PickerColorList.tsx index b355228f17..50594a59e1 100644 --- a/packages/excalidraw/components/ColorPicker/PickerColorList.tsx +++ b/packages/excalidraw/components/ColorPicker/PickerColorList.tsx @@ -1,6 +1,8 @@ import clsx from "clsx"; import { useEffect, useRef } from "react"; +import type { ColorPaletteCustom } from "@excalidraw/common"; + import { useAtom } from "../../editor-jotai"; import { t } from "../../i18n"; @@ -11,7 +13,6 @@ import { getColorNameAndShadeFromColor, } from "./colorPickerUtils"; -import type { ColorPaletteCustom } from "../../colors"; import type { TranslationKeys } from "../../i18n"; interface PickerColorListProps { diff --git a/packages/excalidraw/components/ColorPicker/ShadeList.tsx b/packages/excalidraw/components/ColorPicker/ShadeList.tsx index 35d89ea803..aa2c25ea0d 100644 --- a/packages/excalidraw/components/ColorPicker/ShadeList.tsx +++ b/packages/excalidraw/components/ColorPicker/ShadeList.tsx @@ -1,6 +1,8 @@ import clsx from "clsx"; import { useEffect, useRef } from "react"; +import type { ColorPaletteCustom } from "@excalidraw/common"; + import { useAtom } from "../../editor-jotai"; import { t } from "../../i18n"; @@ -10,8 +12,6 @@ import { getColorNameAndShadeFromColor, } from "./colorPickerUtils"; -import type { ColorPaletteCustom } from "../../colors"; - interface ShadeListProps { hex: string; onChange: (color: string) => void; diff --git a/packages/excalidraw/components/ColorPicker/TopPicks.tsx b/packages/excalidraw/components/ColorPicker/TopPicks.tsx index 9bd8fdb9a2..6d18a95871 100644 --- a/packages/excalidraw/components/ColorPicker/TopPicks.tsx +++ b/packages/excalidraw/components/ColorPicker/TopPicks.tsx @@ -4,7 +4,7 @@ import { DEFAULT_CANVAS_BACKGROUND_PICKS, DEFAULT_ELEMENT_BACKGROUND_PICKS, DEFAULT_ELEMENT_STROKE_PICKS, -} from "../../colors"; +} from "@excalidraw/common"; import type { ColorPickerType } from "./colorPickerUtils"; diff --git a/packages/excalidraw/components/ColorPicker/colorPickerUtils.ts b/packages/excalidraw/components/ColorPicker/colorPickerUtils.ts index bbb4e587d4..4925a31451 100644 --- a/packages/excalidraw/components/ColorPicker/colorPickerUtils.ts +++ b/packages/excalidraw/components/ColorPicker/colorPickerUtils.ts @@ -1,8 +1,10 @@ -import { MAX_CUSTOM_COLORS_USED_IN_CANVAS } from "../../colors"; -import { atom } from "../../editor-jotai"; +import { MAX_CUSTOM_COLORS_USED_IN_CANVAS } from "@excalidraw/common"; -import type { ColorPickerColor, ColorPaletteCustom } from "../../colors"; -import type { ExcalidrawElement } from "../../element/types"; +import type { ExcalidrawElement } from "@excalidraw/element/types"; + +import type { ColorPickerColor, ColorPaletteCustom } from "@excalidraw/common"; + +import { atom } from "../../editor-jotai"; export const getColorNameAndShadeFromColor = ({ palette, diff --git a/packages/excalidraw/components/ColorPicker/keyboardNavHandlers.ts b/packages/excalidraw/components/ColorPicker/keyboardNavHandlers.ts index c4e321700a..3e27229bc4 100644 --- a/packages/excalidraw/components/ColorPicker/keyboardNavHandlers.ts +++ b/packages/excalidraw/components/ColorPicker/keyboardNavHandlers.ts @@ -1,5 +1,12 @@ -import { COLORS_PER_ROW, COLOR_PALETTE } from "../../colors"; -import { KEYS } from "../../keys"; +import { COLORS_PER_ROW, COLOR_PALETTE, KEYS } from "@excalidraw/common"; + +import type { + ColorPickerColor, + ColorPalette, + ColorPaletteCustom, +} from "@excalidraw/common"; + +import type { ValueOf } from "@excalidraw/common/utility-types"; import { colorPickerHotkeyBindings, @@ -7,12 +14,6 @@ import { } from "./colorPickerUtils"; import type { ActiveColorPickerSectionAtomType } from "./colorPickerUtils"; -import type { - ColorPickerColor, - ColorPalette, - ColorPaletteCustom, -} from "../../colors"; -import type { ValueOf } from "../../utility-types"; const arrowHandler = ( eventKey: string, diff --git a/packages/excalidraw/components/CommandPalette/CommandPalette.tsx b/packages/excalidraw/components/CommandPalette/CommandPalette.tsx index 7febb61c97..4391759d9b 100644 --- a/packages/excalidraw/components/CommandPalette/CommandPalette.tsx +++ b/packages/excalidraw/components/CommandPalette/CommandPalette.tsx @@ -2,6 +2,17 @@ import clsx from "clsx"; import fuzzy from "fuzzy"; import { useEffect, useRef, useState } from "react"; +import { + DEFAULT_SIDEBAR, + EVENT, + KEYS, + capitalizeString, + getShortcutKey, + isWritableElement, +} from "@excalidraw/common"; + +import type { MarkRequired } from "@excalidraw/common/utility-types"; + import { actionClearCanvas, actionLink, @@ -13,12 +24,10 @@ import { } from "../../actions/actionElementLink"; import { getShortcutFromShortcutName } from "../../actions/shortcuts"; import { trackEvent } from "../../analytics"; -import { DEFAULT_SIDEBAR, EVENT } from "../../constants"; import { useUIAppState } from "../../context/ui-appState"; import { deburr } from "../../deburr"; import { atom, useAtom, editorJotaiStore } from "../../editor-jotai"; import { t } from "../../i18n"; -import { KEYS } from "../../keys"; import { useApp, useAppProps, @@ -42,13 +51,7 @@ import { LibraryIcon, } from "../icons"; -import { - capitalizeString, - getShortcutKey, - isWritableElement, -} from "../../utils"; - -import { SHAPES } from "../../shapes"; +import { SHAPES } from "../shapes"; import { canChangeBackgroundColor, canChangeStrokeColor } from "../Actions"; import { useStableCallback } from "../../hooks/useStableCallback"; import { activeConfirmDialogAtom } from "../ActiveConfirmDialog"; @@ -60,7 +63,6 @@ import "./CommandPalette.scss"; import type { CommandPaletteItem } from "./types"; import type { AppProps, AppState, UIAppState } from "../../types"; -import type { MarkRequired } from "../../utility-types"; import type { ShortcutName } from "../../actions/shortcuts"; import type { TranslationKeys } from "../../i18n"; import type { Action } from "../../actions/types"; diff --git a/packages/excalidraw/components/DarkModeToggle.tsx b/packages/excalidraw/components/DarkModeToggle.tsx index f04712944c..474181ba4a 100644 --- a/packages/excalidraw/components/DarkModeToggle.tsx +++ b/packages/excalidraw/components/DarkModeToggle.tsx @@ -1,12 +1,13 @@ -import { THEME } from "../constants"; +import { THEME } from "@excalidraw/common"; + +import type { Theme } from "@excalidraw/element/types"; + import { t } from "../i18n"; import { ToolButton } from "./ToolButton"; import "./ToolIcon.scss"; -import type { Theme } from "../element/types"; - // We chose to use only explicit toggle and not a third option for system value, // but this could be added in the future. export const DarkModeToggle = (props: { diff --git a/packages/excalidraw/components/DefaultSidebar.test.tsx b/packages/excalidraw/components/DefaultSidebar.test.tsx index f8bc0dbbbb..1b3f1cac91 100644 --- a/packages/excalidraw/components/DefaultSidebar.test.tsx +++ b/packages/excalidraw/components/DefaultSidebar.test.tsx @@ -1,6 +1,7 @@ import React from "react"; -import { DEFAULT_SIDEBAR } from "../constants"; +import { DEFAULT_SIDEBAR } from "@excalidraw/common"; + import { DefaultSidebar } from "../index"; import { fireEvent, diff --git a/packages/excalidraw/components/DefaultSidebar.tsx b/packages/excalidraw/components/DefaultSidebar.tsx index cd9683c606..4f1aa91e82 100644 --- a/packages/excalidraw/components/DefaultSidebar.tsx +++ b/packages/excalidraw/components/DefaultSidebar.tsx @@ -4,10 +4,13 @@ import { CANVAS_SEARCH_TAB, DEFAULT_SIDEBAR, LIBRARY_SIDEBAR_TAB, -} from "../constants"; + composeEventHandlers, +} from "@excalidraw/common"; + +import type { MarkOptional, Merge } from "@excalidraw/common/utility-types"; + import { useTunnels } from "../context/tunnels"; import { useUIAppState } from "../context/ui-appState"; -import { composeEventHandlers } from "../utils"; import "../components/dropdownMenu/DropdownMenu.scss"; @@ -18,7 +21,6 @@ import { Sidebar } from "./Sidebar/Sidebar"; import { withInternalFallback } from "./hoc/withInternalFallback"; import { LibraryIcon, searchIcon } from "./icons"; -import type { MarkOptional, Merge } from "../utility-types"; import type { SidebarProps, SidebarTriggerProps } from "./Sidebar/common"; const DefaultSidebarTrigger = withInternalFallback( diff --git a/packages/excalidraw/components/Dialog.tsx b/packages/excalidraw/components/Dialog.tsx index cf6b1254a6..00ae2be0cb 100644 --- a/packages/excalidraw/components/Dialog.tsx +++ b/packages/excalidraw/components/Dialog.tsx @@ -1,11 +1,11 @@ import clsx from "clsx"; import React, { useEffect, useState } from "react"; +import { KEYS, queryFocusableElements } from "@excalidraw/common"; + import { useSetAtom } from "../editor-jotai"; import { useCallbackRefState } from "../hooks/useCallbackRefState"; import { t } from "../i18n"; -import { KEYS } from "../keys"; -import { queryFocusableElements } from "../utils"; import { useExcalidrawContainer, diff --git a/packages/excalidraw/element/ElementCanvasButtons.scss b/packages/excalidraw/components/ElementCanvasButtons.scss similarity index 100% rename from packages/excalidraw/element/ElementCanvasButtons.scss rename to packages/excalidraw/components/ElementCanvasButtons.scss diff --git a/packages/excalidraw/element/ElementCanvasButtons.tsx b/packages/excalidraw/components/ElementCanvasButtons.tsx similarity index 85% rename from packages/excalidraw/element/ElementCanvasButtons.tsx rename to packages/excalidraw/components/ElementCanvasButtons.tsx index e67e8d5bc9..424c4f3b44 100644 --- a/packages/excalidraw/element/ElementCanvasButtons.tsx +++ b/packages/excalidraw/components/ElementCanvasButtons.tsx @@ -1,14 +1,17 @@ +import { sceneCoordsToViewportCoords } from "@excalidraw/common"; +import { getElementAbsoluteCoords } from "@excalidraw/element/bounds"; + +import type { + ElementsMap, + NonDeletedExcalidrawElement, +} from "@excalidraw/element/types"; + import { useExcalidrawAppState } from "../components/App"; -import { sceneCoordsToViewportCoords } from "../utils"; import "./ElementCanvasButtons.scss"; -import { getElementAbsoluteCoords } from "."; - import type { AppState } from "../types"; -import type { ElementsMap, NonDeletedExcalidrawElement } from "./types"; - const CONTAINER_PADDING = 5; const getContainerCoords = ( diff --git a/packages/excalidraw/components/ElementLinkDialog.tsx b/packages/excalidraw/components/ElementLinkDialog.tsx index 7cf3296339..5a0b9107ba 100644 --- a/packages/excalidraw/components/ElementLinkDialog.tsx +++ b/packages/excalidraw/components/ElementLinkDialog.tsx @@ -1,13 +1,16 @@ import { useCallback, useEffect, useState } from "react"; -import { normalizeLink } from "../data/url"; +import { normalizeLink, KEYS } from "@excalidraw/common"; + import { defaultGetElementLinkFromSelection, getLinkIdAndTypeFromSelection, -} from "../element/elementLink"; -import { mutateElement } from "../element/mutateElement"; +} from "@excalidraw/element/elementLink"; +import { mutateElement } from "@excalidraw/element/mutateElement"; + +import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types"; + import { t } from "../i18n"; -import { KEYS } from "../keys"; import { getSelectedElements } from "../scene"; import DialogActionButton from "./DialogActionButton"; @@ -17,7 +20,6 @@ import { TrashIcon } from "./icons"; import "./ElementLinkDialog.scss"; -import type { ElementsMap, ExcalidrawElement } from "../element/types"; import type { AppProps, AppState, UIAppState } from "../types"; const ElementLinkDialog = ({ diff --git a/packages/excalidraw/components/EyeDropper.tsx b/packages/excalidraw/components/EyeDropper.tsx index 8c4a73e32c..f7f98123d5 100644 --- a/packages/excalidraw/components/EyeDropper.tsx +++ b/packages/excalidraw/components/EyeDropper.tsx @@ -1,22 +1,21 @@ import { useEffect, useRef } from "react"; import { createPortal } from "react-dom"; -import { rgbToHex } from "../colors"; -import { EVENT } from "../constants"; +import { EVENT, KEYS, rgbToHex } from "@excalidraw/common"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { useUIAppState } from "../context/ui-appState"; import { atom } from "../editor-jotai"; import { useCreatePortalContainer } from "../hooks/useCreatePortalContainer"; import { useOutsideClick } from "../hooks/useOutsideClick"; import { useStable } from "../hooks/useStable"; -import { KEYS } from "../keys"; import { getSelectedElements } from "../scene"; import { useApp, useExcalidrawContainer, useExcalidrawElements } from "./App"; import "./EyeDropper.scss"; -import type { ExcalidrawElement } from "../element/types"; - import type { ColorPickerType } from "./ColorPicker/colorPickerUtils"; export type EyeDropperProperties = { diff --git a/packages/excalidraw/components/FilledButton.tsx b/packages/excalidraw/components/FilledButton.tsx index 4e5b3e3ba2..53b30a0469 100644 --- a/packages/excalidraw/components/FilledButton.tsx +++ b/packages/excalidraw/components/FilledButton.tsx @@ -1,8 +1,9 @@ import clsx from "clsx"; import React, { forwardRef, useState } from "react"; +import { isPromiseLike } from "@excalidraw/common"; + import { AbortError } from "../errors"; -import { isPromiseLike } from "../utils"; import Spinner from "./Spinner"; import { tablerCheckIcon } from "./icons"; diff --git a/packages/excalidraw/components/FontPicker/FontPicker.tsx b/packages/excalidraw/components/FontPicker/FontPicker.tsx index 4018ad243c..546e1fa346 100644 --- a/packages/excalidraw/components/FontPicker/FontPicker.tsx +++ b/packages/excalidraw/components/FontPicker/FontPicker.tsx @@ -1,7 +1,10 @@ import * as Popover from "@radix-ui/react-popover"; import React, { useCallback, useMemo } from "react"; -import { FONT_FAMILY } from "../../constants"; +import { FONT_FAMILY } from "@excalidraw/common"; + +import type { FontFamilyValues } from "@excalidraw/element/types"; + import { t } from "../../i18n"; import { ButtonIconSelect } from "../ButtonIconSelect"; import { ButtonSeparator } from "../ButtonSeparator"; @@ -16,8 +19,6 @@ import { FontPickerTrigger } from "./FontPickerTrigger"; import "./FontPicker.scss"; -import type { FontFamilyValues } from "../../element/types"; - export const DEFAULT_FONTS = [ { value: FONT_FAMILY.Excalifont, diff --git a/packages/excalidraw/components/FontPicker/FontPickerList.tsx b/packages/excalidraw/components/FontPicker/FontPickerList.tsx index d93b08695c..2ec9e7d6d7 100644 --- a/packages/excalidraw/components/FontPicker/FontPickerList.tsx +++ b/packages/excalidraw/components/FontPicker/FontPickerList.tsx @@ -7,10 +7,19 @@ import React, { type KeyboardEventHandler, } from "react"; -import { type FontFamilyValues } from "../../element/types"; +import { type FontFamilyValues } from "@excalidraw/element/types"; + +import { + arrayToList, + debounce, + FONT_FAMILY, + getFontFamilyString, +} from "@excalidraw/common"; + +import type { ValueOf } from "@excalidraw/common/utility-types"; + import { Fonts } from "../../fonts"; import { t } from "../../i18n"; -import { arrayToList, debounce, getFontFamilyString } from "../../utils"; import { useApp, useAppProps, useExcalidrawContainer } from "../App"; import { PropertiesPopover } from "../PropertiesPopover"; import { QuickSearch } from "../QuickSearch"; @@ -20,11 +29,15 @@ import DropdownMenuItem, { DropDownMenuItemBadgeType, DropDownMenuItemBadge, } from "../dropdownMenu/DropdownMenuItem"; -import { FontFamilyNormalIcon } from "../icons"; +import { + FontFamilyCodeIcon, + FontFamilyHeadingIcon, + FontFamilyNormalIcon, + FreedrawIcon, +} from "../icons"; import { fontPickerKeyHandler } from "./keyboardNavHandlers"; -import type { ValueOf } from "../../utility-types"; import type { JSX } from "react"; export interface FontDescriptor { @@ -48,6 +61,24 @@ interface FontPickerListProps { onClose: () => void; } +const getFontFamilyIcon = (fontFamily: FontFamilyValues): JSX.Element => { + switch (fontFamily) { + case FONT_FAMILY.Excalifont: + case FONT_FAMILY.Virgil: + return FreedrawIcon; + case FONT_FAMILY.Nunito: + case FONT_FAMILY.Helvetica: + return FontFamilyNormalIcon; + case FONT_FAMILY["Lilita One"]: + return FontFamilyHeadingIcon; + case FONT_FAMILY["Comic Shanns"]: + case FONT_FAMILY.Cascadia: + return FontFamilyCodeIcon; + default: + return FontFamilyNormalIcon; + } +}; + export const FontPickerList = React.memo( ({ selectedFontFamily, @@ -73,7 +104,7 @@ export const FontPickerList = React.memo( .map(([familyId, { metadata, fontFaces }]) => { const fontDescriptor = { value: familyId, - icon: metadata.icon ?? FontFamilyNormalIcon, + icon: getFontFamilyIcon(familyId), text: fontFaces[0]?.fontFace?.family ?? "Unknown", }; diff --git a/packages/excalidraw/components/FontPicker/FontPickerTrigger.tsx b/packages/excalidraw/components/FontPicker/FontPickerTrigger.tsx index d83dda0fd6..6f3cc638a6 100644 --- a/packages/excalidraw/components/FontPicker/FontPickerTrigger.tsx +++ b/packages/excalidraw/components/FontPicker/FontPickerTrigger.tsx @@ -1,14 +1,14 @@ import * as Popover from "@radix-ui/react-popover"; import { useMemo } from "react"; +import type { FontFamilyValues } from "@excalidraw/element/types"; + import { t } from "../../i18n"; import { ButtonIcon } from "../ButtonIcon"; import { TextIcon } from "../icons"; import { isDefaultFont } from "./FontPicker"; -import type { FontFamilyValues } from "../../element/types"; - interface FontPickerTriggerProps { selectedFontFamily: FontFamilyValues | null; } diff --git a/packages/excalidraw/components/FontPicker/keyboardNavHandlers.ts b/packages/excalidraw/components/FontPicker/keyboardNavHandlers.ts index b0ecdf371f..16ffa7c45f 100644 --- a/packages/excalidraw/components/FontPicker/keyboardNavHandlers.ts +++ b/packages/excalidraw/components/FontPicker/keyboardNavHandlers.ts @@ -1,9 +1,9 @@ -import { KEYS } from "../../keys"; +import { KEYS } from "@excalidraw/common"; + +import type { Node } from "@excalidraw/common"; import { type FontDescriptor } from "./FontPickerList"; -import type { Node } from "../../utils"; - interface FontPickerKeyNavHandlerProps { event: React.KeyboardEvent; inputRef: React.RefObject; diff --git a/packages/excalidraw/components/HandButton.tsx b/packages/excalidraw/components/HandButton.tsx index 4bffb1000e..5ebfdf9d3f 100644 --- a/packages/excalidraw/components/HandButton.tsx +++ b/packages/excalidraw/components/HandButton.tsx @@ -1,6 +1,6 @@ import clsx from "clsx"; -import { KEYS } from "../keys"; +import { KEYS } from "@excalidraw/common"; import { ToolButton } from "./ToolButton"; import { handIcon } from "./icons"; diff --git a/packages/excalidraw/components/HelpDialog.tsx b/packages/excalidraw/components/HelpDialog.tsx index 19ecaa57e4..60fc403723 100644 --- a/packages/excalidraw/components/HelpDialog.tsx +++ b/packages/excalidraw/components/HelpDialog.tsx @@ -1,11 +1,12 @@ import React from "react"; +import { isDarwin, isFirefox, isWindows } from "@excalidraw/common"; + +import { KEYS, getShortcutKey } from "@excalidraw/common"; + import { getShortcutFromShortcutName } from "../actions/shortcuts"; import { probablySupportsClipboardBlob } from "../clipboard"; -import { isDarwin, isFirefox, isWindows } from "../constants"; import { t } from "../i18n"; -import { KEYS } from "../keys"; -import { getShortcutKey } from "../utils"; import { Dialog } from "./Dialog"; import { ExternalLinkIcon, GithubIcon, youtubeIcon } from "./icons"; diff --git a/packages/excalidraw/components/HintViewer.tsx b/packages/excalidraw/components/HintViewer.tsx index c285e361b7..6eb1a21867 100644 --- a/packages/excalidraw/components/HintViewer.tsx +++ b/packages/excalidraw/components/HintViewer.tsx @@ -1,18 +1,20 @@ -import { isEraserActive } from "../appState"; +import { CANVAS_SEARCH_TAB, DEFAULT_SIDEBAR } from "@excalidraw/common"; + import { isFlowchartNodeElement, isImageElement, isLinearElement, isTextBindableContainer, isTextElement, -} from "../element/typeChecks"; +} from "@excalidraw/element/typeChecks"; + +import { getShortcutKey } from "@excalidraw/common"; + +import { isNodeInFlowchart } from "@excalidraw/element/flowchart"; + import { t } from "../i18n"; - -import { getShortcutKey } from "../utils"; - -import { isNodeInFlowchart } from "../element/flowchart"; +import { isEraserActive } from "../appState"; import { isGridModeEnabled } from "../snapping"; -import { CANVAS_SEARCH_TAB, DEFAULT_SIDEBAR } from "../constants"; import "./HintViewer.scss"; diff --git a/packages/excalidraw/components/IconPicker.tsx b/packages/excalidraw/components/IconPicker.tsx index b91d37c239..5630ae8d7a 100644 --- a/packages/excalidraw/components/IconPicker.tsx +++ b/packages/excalidraw/components/IconPicker.tsx @@ -2,9 +2,10 @@ import * as Popover from "@radix-ui/react-popover"; import clsx from "clsx"; import React, { useEffect } from "react"; +import { isArrowKey, KEYS } from "@excalidraw/common"; + import { atom, useAtom } from "../editor-jotai"; import { getLanguage, t } from "../i18n"; -import { isArrowKey, KEYS } from "../keys"; import Collapsible from "./Stats/Collapsible"; import { useDevice } from "./App"; diff --git a/packages/excalidraw/components/ImageExportDialog.tsx b/packages/excalidraw/components/ImageExportDialog.tsx index 0d19f5b5dd..e8e0b70f49 100644 --- a/packages/excalidraw/components/ImageExportDialog.tsx +++ b/packages/excalidraw/components/ImageExportDialog.tsx @@ -1,6 +1,16 @@ import { exportToCanvas } from "@excalidraw/utils/export"; import React, { useEffect, useRef, useState } from "react"; +import { + DEFAULT_EXPORT_PADDING, + EXPORT_IMAGE_TYPES, + isFirefox, + EXPORT_SCALES, + cloneJSON, +} from "@excalidraw/common"; + +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; + import { actionExportWithDarkMode, actionChangeExportBackground, @@ -9,12 +19,6 @@ import { actionChangeProjectName, } from "../actions/actionExport"; import { probablySupportsClipboardBlob } from "../clipboard"; -import { - DEFAULT_EXPORT_PADDING, - EXPORT_IMAGE_TYPES, - isFirefox, - EXPORT_SCALES, -} from "../constants"; import { prepareElementsForExport } from "../data"; import { canvasToBlob } from "../data/blob"; import { nativeFileSystemSupported } from "../data/filesystem"; @@ -22,7 +26,6 @@ import { useCopyStatus } from "../hooks/useCopiedIndicator"; import { t } from "../i18n"; import { isSomeElementSelected } from "../scene"; -import { cloneJSON } from "../utils"; import { copyIcon, downloadIcon, helpIcon } from "./icons"; import { Dialog } from "./Dialog"; @@ -34,7 +37,7 @@ import { FilledButton } from "./FilledButton"; import "./ImageExportDialog.scss"; import type { ActionManager } from "../actions/manager"; -import type { NonDeletedExcalidrawElement } from "../element/types"; + import type { AppClassProperties, BinaryFiles, UIAppState } from "../types"; const supportsContextFilters = diff --git a/packages/excalidraw/components/InitializeApp.tsx b/packages/excalidraw/components/InitializeApp.tsx index efc83a55b8..1e5dda6dcf 100644 --- a/packages/excalidraw/components/InitializeApp.tsx +++ b/packages/excalidraw/components/InitializeApp.tsx @@ -1,10 +1,11 @@ import React, { useEffect, useState } from "react"; +import type { Theme } from "@excalidraw/element/types"; + import { defaultLang, languages, setLanguage } from "../i18n"; import { LoadingMessage } from "./LoadingMessage"; -import type { Theme } from "../element/types"; import type { Language } from "../i18n"; interface Props { diff --git a/packages/excalidraw/components/JSONExportDialog.tsx b/packages/excalidraw/components/JSONExportDialog.tsx index ae203d3e4f..4dfedc6922 100644 --- a/packages/excalidraw/components/JSONExportDialog.tsx +++ b/packages/excalidraw/components/JSONExportDialog.tsx @@ -1,11 +1,14 @@ import React from "react"; +import { getFrame } from "@excalidraw/common"; + +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; + import { actionSaveFileToDisk } from "../actions/actionExport"; import { trackEvent } from "../analytics"; import { nativeFileSystemSupported } from "../data/filesystem"; import { t } from "../i18n"; -import { getFrame } from "../utils"; import { Card } from "./Card"; import { Dialog } from "./Dialog"; @@ -15,7 +18,7 @@ import { exportToFileIcon, LinkIcon } from "./icons"; import "./ExportDialog.scss"; import type { ActionManager } from "../actions/manager"; -import type { NonDeletedExcalidrawElement } from "../element/types"; + import type { ExportOpts, BinaryFiles, UIAppState } from "../types"; export type ExportCB = ( diff --git a/packages/excalidraw/components/LayerUI.tsx b/packages/excalidraw/components/LayerUI.tsx index 83ac7ae9cc..b5491dedd7 100644 --- a/packages/excalidraw/components/LayerUI.tsx +++ b/packages/excalidraw/components/LayerUI.tsx @@ -1,20 +1,32 @@ import clsx from "clsx"; import React from "react"; -import { mutateElement } from "../element/mutateElement"; -import { ShapeCache } from "../scene/ShapeCache"; +import { + CLASSES, + DEFAULT_SIDEBAR, + TOOL_TYPE, + capitalizeString, + isShallowEqual, +} from "@excalidraw/common"; + +import { mutateElement } from "@excalidraw/element/mutateElement"; + +import { showSelectedShapeActions } from "@excalidraw/element/showSelectedShapeActions"; + +import { ShapeCache } from "@excalidraw/element/ShapeCache"; + +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; + import Scene from "../scene/Scene"; import { actionToggleStats } from "../actions"; import { trackEvent } from "../analytics"; import { isHandToolActive } from "../appState"; -import { CLASSES, DEFAULT_SIDEBAR, TOOL_TYPE } from "../constants"; import { TunnelsContext, useInitializeTunnels } from "../context/tunnels"; import { UIAppStateContext } from "../context/ui-appState"; import { useAtom, useAtomValue } from "../editor-jotai"; -import { showSelectedShapeActions } from "../element"; + import { t } from "../i18n"; import { calculateScrollCenter } from "../scene"; -import { capitalizeString, isShallowEqual } from "../utils"; import { SelectedShapeActions, ShapesSwitcher } from "./Actions"; import { LoadingMessage } from "./LoadingMessage"; @@ -51,7 +63,7 @@ import "./LayerUI.scss"; import "./Toolbar.scss"; import type { ActionManager } from "../actions/manager"; -import type { NonDeletedExcalidrawElement } from "../element/types"; + import type { Language } from "../i18n"; import type { AppProps, diff --git a/packages/excalidraw/components/LibraryMenu.tsx b/packages/excalidraw/components/LibraryMenu.tsx index 03c476e47c..62bd235c26 100644 --- a/packages/excalidraw/components/LibraryMenu.tsx +++ b/packages/excalidraw/components/LibraryMenu.tsx @@ -7,8 +7,18 @@ import React, { useRef, } from "react"; +import { + LIBRARY_DISABLED_TYPES, + randomId, + isShallowEqual, +} from "@excalidraw/common"; + +import type { + ExcalidrawElement, + NonDeletedExcalidrawElement, +} from "@excalidraw/element/types"; + import { trackEvent } from "../analytics"; -import { LIBRARY_DISABLED_TYPES } from "../constants"; import { useUIAppState } from "../context/ui-appState"; import { distributeLibraryItemsOnSquareGrid, @@ -16,9 +26,8 @@ import { } from "../data/library"; import { atom, useAtom } from "../editor-jotai"; import { t } from "../i18n"; -import { randomId } from "../random"; + import { getSelectedElements } from "../scene"; -import { isShallowEqual } from "../utils"; import { useApp, @@ -32,10 +41,6 @@ import Spinner from "./Spinner"; import "./LibraryMenu.scss"; -import type { - ExcalidrawElement, - NonDeletedExcalidrawElement, -} from "../element/types"; import type { LibraryItems, LibraryItem, diff --git a/packages/excalidraw/components/LibraryMenuBrowseButton.tsx b/packages/excalidraw/components/LibraryMenuBrowseButton.tsx index 2b2623ed1f..86bd4e2ad9 100644 --- a/packages/excalidraw/components/LibraryMenuBrowseButton.tsx +++ b/packages/excalidraw/components/LibraryMenuBrowseButton.tsx @@ -1,4 +1,5 @@ -import { VERSIONS } from "../constants"; +import { VERSIONS } from "@excalidraw/common"; + import { t } from "../i18n"; import type { ExcalidrawProps, UIAppState } from "../types"; diff --git a/packages/excalidraw/components/LibraryMenuHeaderContent.tsx b/packages/excalidraw/components/LibraryMenuHeaderContent.tsx index cc6c942ae0..5b003effa1 100644 --- a/packages/excalidraw/components/LibraryMenuHeaderContent.tsx +++ b/packages/excalidraw/components/LibraryMenuHeaderContent.tsx @@ -1,6 +1,8 @@ import clsx from "clsx"; import { useCallback, useState } from "react"; +import { muteFSAbortError } from "@excalidraw/common"; + import { useUIAppState } from "../context/ui-appState"; import { fileOpen } from "../data/filesystem"; import { saveLibraryAsJSON } from "../data/json"; @@ -8,7 +10,6 @@ import { libraryItemsAtom } from "../data/library"; import { useAtom } from "../editor-jotai"; import { useLibraryCache } from "../hooks/useLibraryItemSvg"; import { t } from "../i18n"; -import { muteFSAbortError } from "../utils"; import { useApp, useExcalidrawSetAppState } from "./App"; import ConfirmDialog from "./ConfirmDialog"; diff --git a/packages/excalidraw/components/LibraryMenuItems.tsx b/packages/excalidraw/components/LibraryMenuItems.tsx index 3e32021e0f..f70315953d 100644 --- a/packages/excalidraw/components/LibraryMenuItems.tsx +++ b/packages/excalidraw/components/LibraryMenuItems.tsx @@ -6,14 +6,14 @@ import React, { useState, } from "react"; -import { MIME_TYPES } from "../constants"; +import { MIME_TYPES, arrayToMap } from "@excalidraw/common"; + +import { duplicateElements } from "@excalidraw/element/duplicate"; + import { serializeLibraryAsJSON } from "../data/json"; import { useLibraryCache } from "../hooks/useLibraryItemSvg"; import { useScrollPosition } from "../hooks/useScrollPosition"; import { t } from "../i18n"; -import { arrayToMap } from "../utils"; - -import { duplicateElements } from "../element/duplicate"; import { LibraryMenuControlButtons } from "./LibraryMenuControlButtons"; import { LibraryDropdownMenu } from "./LibraryMenuHeaderContent"; diff --git a/packages/excalidraw/components/LibraryMenuSection.tsx b/packages/excalidraw/components/LibraryMenuSection.tsx index 5f7de2b093..d98b413fbb 100644 --- a/packages/excalidraw/components/LibraryMenuSection.tsx +++ b/packages/excalidraw/components/LibraryMenuSection.tsx @@ -1,10 +1,11 @@ import React, { memo, useEffect, useState } from "react"; +import type { ExcalidrawElement, NonDeleted } from "@excalidraw/element/types"; + import { useTransition } from "../hooks/useTransition"; import { EmptyLibraryUnit, LibraryUnit } from "./LibraryUnit"; -import type { ExcalidrawElement, NonDeleted } from "../element/types"; import type { SvgCache } from "../hooks/useLibraryItemSvg"; import type { LibraryItem } from "../types"; import type { ReactNode } from "react"; diff --git a/packages/excalidraw/components/LoadingMessage.tsx b/packages/excalidraw/components/LoadingMessage.tsx index bdcc5a3413..c971b37ee9 100644 --- a/packages/excalidraw/components/LoadingMessage.tsx +++ b/packages/excalidraw/components/LoadingMessage.tsx @@ -1,13 +1,14 @@ import clsx from "clsx"; import { useState, useEffect } from "react"; -import { THEME } from "../constants"; +import { THEME } from "@excalidraw/common"; + +import type { Theme } from "@excalidraw/element/types"; + import { t } from "../i18n"; import Spinner from "./Spinner"; -import type { Theme } from "../element/types"; - export const LoadingMessage: React.FC<{ delay?: number; theme?: Theme }> = ({ delay, theme, diff --git a/packages/excalidraw/components/MobileMenu.tsx b/packages/excalidraw/components/MobileMenu.tsx index 08a20174c8..6e75b5992c 100644 --- a/packages/excalidraw/components/MobileMenu.tsx +++ b/packages/excalidraw/components/MobileMenu.tsx @@ -1,8 +1,11 @@ import React from "react"; +import { showSelectedShapeActions } from "@excalidraw/element/showSelectedShapeActions"; + +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; + import { isHandToolActive } from "../appState"; import { useTunnels } from "../context/tunnels"; -import { showSelectedShapeActions } from "../element"; import { t } from "../i18n"; import { calculateScrollCenter } from "../scene"; import { SCROLLBAR_WIDTH, SCROLLBAR_MARGIN } from "../scene/scrollbars"; @@ -18,7 +21,6 @@ import { Section } from "./Section"; import Stack from "./Stack"; import type { ActionManager } from "../actions/manager"; -import type { NonDeletedExcalidrawElement } from "../element/types"; import type { AppClassProperties, AppProps, diff --git a/packages/excalidraw/components/Modal.tsx b/packages/excalidraw/components/Modal.tsx index a5ade9efa8..32f42986fa 100644 --- a/packages/excalidraw/components/Modal.tsx +++ b/packages/excalidraw/components/Modal.tsx @@ -2,8 +2,9 @@ import clsx from "clsx"; import { useRef } from "react"; import { createPortal } from "react-dom"; +import { KEYS } from "@excalidraw/common"; + import { useCreatePortalContainer } from "../hooks/useCreatePortalContainer"; -import { KEYS } from "../keys"; import "./Modal.scss"; diff --git a/packages/excalidraw/components/PasteChartDialog.tsx b/packages/excalidraw/components/PasteChartDialog.tsx index 58bd5a385b..2566017ac9 100644 --- a/packages/excalidraw/components/PasteChartDialog.tsx +++ b/packages/excalidraw/components/PasteChartDialog.tsx @@ -1,6 +1,8 @@ import oc from "open-color"; import React, { useLayoutEffect, useRef, useState } from "react"; +import type { ChartType } from "@excalidraw/element/types"; + import { trackEvent } from "../analytics"; import { renderSpreadsheet } from "../charts"; import { t } from "../i18n"; @@ -12,7 +14,6 @@ import { Dialog } from "./Dialog"; import "./PasteChartDialog.scss"; import type { ChartElements, Spreadsheet } from "../charts"; -import type { ChartType } from "../element/types"; import type { UIAppState } from "../types"; type OnInsertChart = (chartType: ChartType, elements: ChartElements) => void; diff --git a/packages/excalidraw/components/Popover.tsx b/packages/excalidraw/components/Popover.tsx index 2bd72b20b4..4864b37d16 100644 --- a/packages/excalidraw/components/Popover.tsx +++ b/packages/excalidraw/components/Popover.tsx @@ -1,8 +1,7 @@ import React, { useLayoutEffect, useRef, useEffect } from "react"; import { unstable_batchedUpdates } from "react-dom"; -import { KEYS } from "../keys"; -import { queryFocusableElements } from "../utils"; +import { KEYS, queryFocusableElements } from "@excalidraw/common"; import "./Popover.scss"; diff --git a/packages/excalidraw/components/ProjectName.tsx b/packages/excalidraw/components/ProjectName.tsx index 0d60ddd66c..ad50c7fd54 100644 --- a/packages/excalidraw/components/ProjectName.tsx +++ b/packages/excalidraw/components/ProjectName.tsx @@ -1,7 +1,6 @@ import React, { useState } from "react"; -import { focusNearestParent } from "../utils"; -import { KEYS } from "../keys"; +import { focusNearestParent, KEYS } from "@excalidraw/common"; import { useExcalidrawContainer } from "./App"; diff --git a/packages/excalidraw/components/PropertiesPopover.tsx b/packages/excalidraw/components/PropertiesPopover.tsx index a30f1374d6..d8372ea27b 100644 --- a/packages/excalidraw/components/PropertiesPopover.tsx +++ b/packages/excalidraw/components/PropertiesPopover.tsx @@ -2,7 +2,7 @@ import * as Popover from "@radix-ui/react-popover"; import clsx from "clsx"; import React, { type ReactNode } from "react"; -import { isInteractive } from "../utils"; +import { isInteractive } from "@excalidraw/common"; import { useDevice } from "./App"; import { Island } from "./Island"; diff --git a/packages/excalidraw/components/PublishLibrary.tsx b/packages/excalidraw/components/PublishLibrary.tsx index 8a7188b633..c1db912961 100644 --- a/packages/excalidraw/components/PublishLibrary.tsx +++ b/packages/excalidraw/components/PublishLibrary.tsx @@ -8,11 +8,12 @@ import { EXPORT_SOURCE, MIME_TYPES, VERSIONS, -} from "../constants"; + chunk, +} from "@excalidraw/common"; + import { EditorLocalStorage } from "../data/EditorLocalStorage"; import { canvasToBlob, resizeImageFile } from "../data/blob"; import { t } from "../i18n"; -import { chunk } from "../utils"; import { Dialog } from "./Dialog"; import DialogActionButton from "./DialogActionButton"; diff --git a/packages/excalidraw/components/SearchMenu.tsx b/packages/excalidraw/components/SearchMenu.tsx index 70d3f4f270..3e0b31a699 100644 --- a/packages/excalidraw/components/SearchMenu.tsx +++ b/packages/excalidraw/components/SearchMenu.tsx @@ -3,17 +3,28 @@ import clsx from "clsx"; import debounce from "lodash.debounce"; import { Fragment, memo, useEffect, useRef, useState } from "react"; -import { CLASSES, EVENT } from "../constants"; -import { atom, useAtom } from "../editor-jotai"; -import { isTextElement, newTextElement } from "../element"; -import { isElementCompletelyInViewport } from "../element/sizeHelpers"; +import { CLASSES, EVENT } from "@excalidraw/common"; + +import { isElementCompletelyInViewport } from "@excalidraw/element/sizeHelpers"; + +import { measureText } from "@excalidraw/element/textMeasurements"; + +import { + KEYS, + randomInteger, + addEventListener, + getFontString, +} from "@excalidraw/common"; + +import { newTextElement } from "@excalidraw/element/newElement"; +import { isTextElement } from "@excalidraw/element/typeChecks"; + +import type { ExcalidrawTextElement } from "@excalidraw/element/types"; + +import { atom, useAtom } from "../editor-jotai"; -import { measureText } from "../element/textMeasurements"; import { useStable } from "../hooks/useStable"; import { t } from "../i18n"; -import { KEYS } from "../keys"; -import { randomInteger } from "../random"; -import { addEventListener, getFontString } from "../utils"; import { useApp, useExcalidrawSetAppState } from "./App"; import { Button } from "./Button"; @@ -22,7 +33,6 @@ import { collapseDownIcon, upIcon, searchIcon } from "./icons"; import "./SearchMenu.scss"; -import type { ExcalidrawTextElement } from "../element/types"; import type { AppClassProperties } from "../types"; const searchQueryAtom = atom(""); diff --git a/packages/excalidraw/components/Sidebar/Sidebar.test.tsx b/packages/excalidraw/components/Sidebar/Sidebar.test.tsx index 39a1cbc631..dd52fdb117 100644 --- a/packages/excalidraw/components/Sidebar/Sidebar.test.tsx +++ b/packages/excalidraw/components/Sidebar/Sidebar.test.tsx @@ -1,7 +1,8 @@ import React from "react"; import { vi } from "vitest"; -import { DEFAULT_SIDEBAR } from "../../constants"; +import { DEFAULT_SIDEBAR } from "@excalidraw/common"; + import { Excalidraw, Sidebar } from "../../index"; import { act, diff --git a/packages/excalidraw/components/Sidebar/Sidebar.tsx b/packages/excalidraw/components/Sidebar/Sidebar.tsx index a702e9330d..d08ba5f597 100644 --- a/packages/excalidraw/components/Sidebar/Sidebar.tsx +++ b/packages/excalidraw/components/Sidebar/Sidebar.tsx @@ -9,12 +9,11 @@ import React, { useCallback, } from "react"; -import { EVENT } from "../../constants"; +import { EVENT, isDevEnv, KEYS, updateObject } from "@excalidraw/common"; + import { useUIAppState } from "../../context/ui-appState"; import { atom, useSetAtom } from "../../editor-jotai"; import { useOutsideClick } from "../../hooks/useOutsideClick"; -import { KEYS } from "../../keys"; -import { isDevEnv, updateObject } from "../../utils"; import { useDevice, useExcalidrawSetAppState } from "../App"; import { Island } from "../Island"; diff --git a/packages/excalidraw/components/Stats/Angle.tsx b/packages/excalidraw/components/Stats/Angle.tsx index 10c76d5198..67693551f6 100644 --- a/packages/excalidraw/components/Stats/Angle.tsx +++ b/packages/excalidraw/components/Stats/Angle.tsx @@ -1,17 +1,20 @@ import { degreesToRadians, radiansToDegrees } from "@excalidraw/math"; +import { mutateElement } from "@excalidraw/element/mutateElement"; + +import { getBoundTextElement } from "@excalidraw/element/textElement"; +import { isArrowElement, isElbowArrow } from "@excalidraw/element/typeChecks"; + import type { Degrees } from "@excalidraw/math"; -import { mutateElement } from "../../element/mutateElement"; -import { getBoundTextElement } from "../../element/textElement"; -import { isArrowElement, isElbowArrow } from "../../element/typeChecks"; +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { angleIcon } from "../icons"; import DragInput from "./DragInput"; import { getStepSizedValue, isPropertyEditable, updateBindings } from "./utils"; import type { DragInputCallbackType } from "./DragInput"; -import type { ExcalidrawElement } from "../../element/types"; import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; diff --git a/packages/excalidraw/components/Stats/Dimension.tsx b/packages/excalidraw/components/Stats/Dimension.tsx index f58c06acc9..142abc4074 100644 --- a/packages/excalidraw/components/Stats/Dimension.tsx +++ b/packages/excalidraw/components/Stats/Dimension.tsx @@ -1,19 +1,20 @@ import { clamp, round } from "@excalidraw/math"; -import { MIN_WIDTH_OR_HEIGHT } from "../../constants"; +import { MIN_WIDTH_OR_HEIGHT } from "@excalidraw/common"; import { MINIMAL_CROP_SIZE, getUncroppedWidthAndHeight, -} from "../../element/cropElement"; -import { mutateElement } from "../../element/mutateElement"; -import { resizeSingleElement } from "../../element/resizeElements"; -import { isImageElement } from "../../element/typeChecks"; +} from "@excalidraw/element/cropElement"; +import { mutateElement } from "@excalidraw/element/mutateElement"; +import { resizeSingleElement } from "@excalidraw/element/resizeElements"; +import { isImageElement } from "@excalidraw/element/typeChecks"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; import DragInput from "./DragInput"; import { getStepSizedValue, isPropertyEditable } from "./utils"; import type { DragInputCallbackType } from "./DragInput"; -import type { ExcalidrawElement } from "../../element/types"; import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; diff --git a/packages/excalidraw/components/Stats/DragInput.tsx b/packages/excalidraw/components/Stats/DragInput.tsx index 4ee8c75808..b4795308d8 100644 --- a/packages/excalidraw/components/Stats/DragInput.tsx +++ b/packages/excalidraw/components/Stats/DragInput.tsx @@ -1,12 +1,13 @@ import clsx from "clsx"; import { useEffect, useRef, useState } from "react"; -import { deepCopyElement } from "@excalidraw/excalidraw/element/duplicate"; +import { EVENT, KEYS, cloneJSON } from "@excalidraw/common"; + +import { deepCopyElement } from "@excalidraw/element/duplicate"; + +import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types"; -import { EVENT } from "../../constants"; -import { KEYS } from "../../keys"; import { CaptureUpdateAction } from "../../store"; -import { cloneJSON } from "../../utils"; import { useApp } from "../App"; import { InlineIcon } from "../InlineIcon"; @@ -15,7 +16,6 @@ import { SMALLEST_DELTA } from "./utils"; import "./DragInput.scss"; import type { StatsInputProperty } from "./utils"; -import type { ElementsMap, ExcalidrawElement } from "../../element/types"; import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; diff --git a/packages/excalidraw/components/Stats/FontSize.tsx b/packages/excalidraw/components/Stats/FontSize.tsx index 4fbdab833d..90bdee5648 100644 --- a/packages/excalidraw/components/Stats/FontSize.tsx +++ b/packages/excalidraw/components/Stats/FontSize.tsx @@ -1,17 +1,24 @@ -import { isTextElement, redrawTextBoundingBox } from "../../element"; -import { mutateElement } from "../../element/mutateElement"; -import { getBoundTextElement } from "../../element/textElement"; -import { hasBoundTextElement } from "../../element/typeChecks"; +import { mutateElement } from "@excalidraw/element/mutateElement"; +import { + getBoundTextElement, + redrawTextBoundingBox, +} from "@excalidraw/element/textElement"; +import { + hasBoundTextElement, + isTextElement, +} from "@excalidraw/element/typeChecks"; + +import type { + ExcalidrawElement, + ExcalidrawTextElement, +} from "@excalidraw/element/types"; + import { fontSizeIcon } from "../icons"; import StatsDragInput from "./DragInput"; import { getStepSizedValue } from "./utils"; import type { DragInputCallbackType } from "./DragInput"; -import type { - ExcalidrawElement, - ExcalidrawTextElement, -} from "../../element/types"; import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; diff --git a/packages/excalidraw/components/Stats/MultiAngle.tsx b/packages/excalidraw/components/Stats/MultiAngle.tsx index ec314c1839..3cabd19c03 100644 --- a/packages/excalidraw/components/Stats/MultiAngle.tsx +++ b/packages/excalidraw/components/Stats/MultiAngle.tsx @@ -1,18 +1,22 @@ import { degreesToRadians, radiansToDegrees } from "@excalidraw/math"; +import { mutateElement } from "@excalidraw/element/mutateElement"; + +import { getBoundTextElement } from "@excalidraw/element/textElement"; +import { isArrowElement } from "@excalidraw/element/typeChecks"; + +import { isInGroup } from "@excalidraw/element/groups"; + import type { Degrees } from "@excalidraw/math"; -import { mutateElement } from "../../element/mutateElement"; -import { getBoundTextElement } from "../../element/textElement"; -import { isArrowElement } from "../../element/typeChecks"; -import { isInGroup } from "../../groups"; +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { angleIcon } from "../icons"; import DragInput from "./DragInput"; import { getStepSizedValue, isPropertyEditable } from "./utils"; import type { DragInputCallbackType } from "./DragInput"; -import type { ExcalidrawElement } from "../../element/types"; import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; diff --git a/packages/excalidraw/components/Stats/MultiDimension.tsx b/packages/excalidraw/components/Stats/MultiDimension.tsx index fb9cea9429..b482611afa 100644 --- a/packages/excalidraw/components/Stats/MultiDimension.tsx +++ b/packages/excalidraw/components/Stats/MultiDimension.tsx @@ -1,18 +1,27 @@ import { pointFrom, type GlobalPoint } from "@excalidraw/math"; import { useMemo } from "react"; -import { MIN_WIDTH_OR_HEIGHT } from "../../constants"; -import { getCommonBounds, isTextElement } from "../../element"; -import { updateBoundElements } from "../../element/binding"; -import { mutateElement } from "../../element/mutateElement"; +import { MIN_WIDTH_OR_HEIGHT } from "@excalidraw/common"; +import { updateBoundElements } from "@excalidraw/element/binding"; +import { mutateElement } from "@excalidraw/element/mutateElement"; import { rescalePointsInElement, resizeSingleElement, -} from "../../element/resizeElements"; +} from "@excalidraw/element/resizeElements"; import { getBoundTextElement, handleBindTextResize, -} from "../../element/textElement"; +} from "@excalidraw/element/textElement"; + +import { isTextElement } from "@excalidraw/element/typeChecks"; + +import { getCommonBounds } from "@excalidraw/utils"; + +import type { + ElementsMap, + ExcalidrawElement, + NonDeletedSceneElementsMap, +} from "@excalidraw/element/types"; import DragInput from "./DragInput"; import { getAtomicUnits, getStepSizedValue, isPropertyEditable } from "./utils"; @@ -20,11 +29,6 @@ import { getElementsInAtomicUnit } from "./utils"; import type { DragInputCallbackType } from "./DragInput"; import type { AtomicUnit } from "./utils"; -import type { - ElementsMap, - ExcalidrawElement, - NonDeletedSceneElementsMap, -} from "../../element/types"; import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; diff --git a/packages/excalidraw/components/Stats/MultiFontSize.tsx b/packages/excalidraw/components/Stats/MultiFontSize.tsx index 8335399efb..6bac4bd3cd 100644 --- a/packages/excalidraw/components/Stats/MultiFontSize.tsx +++ b/packages/excalidraw/components/Stats/MultiFontSize.tsx @@ -1,19 +1,27 @@ -import { isTextElement, redrawTextBoundingBox } from "../../element"; -import { mutateElement } from "../../element/mutateElement"; -import { getBoundTextElement } from "../../element/textElement"; -import { hasBoundTextElement } from "../../element/typeChecks"; -import { isInGroup } from "../../groups"; +import { mutateElement } from "@excalidraw/element/mutateElement"; +import { + getBoundTextElement, + redrawTextBoundingBox, +} from "@excalidraw/element/textElement"; +import { + hasBoundTextElement, + isTextElement, +} from "@excalidraw/element/typeChecks"; + +import { isInGroup } from "@excalidraw/element/groups"; + +import type { + ExcalidrawElement, + ExcalidrawTextElement, + NonDeletedSceneElementsMap, +} from "@excalidraw/element/types"; + import { fontSizeIcon } from "../icons"; import StatsDragInput from "./DragInput"; import { getStepSizedValue } from "./utils"; import type { DragInputCallbackType } from "./DragInput"; -import type { - ExcalidrawElement, - ExcalidrawTextElement, - NonDeletedSceneElementsMap, -} from "../../element/types"; import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; diff --git a/packages/excalidraw/components/Stats/MultiPosition.tsx b/packages/excalidraw/components/Stats/MultiPosition.tsx index a8fdacf292..98058efecd 100644 --- a/packages/excalidraw/components/Stats/MultiPosition.tsx +++ b/packages/excalidraw/components/Stats/MultiPosition.tsx @@ -1,7 +1,16 @@ import { pointFrom, pointRotateRads } from "@excalidraw/math"; import { useMemo } from "react"; -import { getCommonBounds, isTextElement } from "../../element"; +import { isTextElement } from "@excalidraw/element/typeChecks"; + +import { getCommonBounds } from "@excalidraw/element/bounds"; + +import type { + ElementsMap, + ExcalidrawElement, + NonDeletedExcalidrawElement, + NonDeletedSceneElementsMap, +} from "@excalidraw/element/types"; import StatsDragInput from "./DragInput"; import { getAtomicUnits, getStepSizedValue, isPropertyEditable } from "./utils"; @@ -9,12 +18,6 @@ import { getElementsInAtomicUnit, moveElement } from "./utils"; import type { DragInputCallbackType } from "./DragInput"; import type { AtomicUnit } from "./utils"; -import type { - ElementsMap, - ExcalidrawElement, - NonDeletedExcalidrawElement, - NonDeletedSceneElementsMap, -} from "../../element/types"; import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; diff --git a/packages/excalidraw/components/Stats/Position.tsx b/packages/excalidraw/components/Stats/Position.tsx index 08d0a88308..bf6dfd1613 100644 --- a/packages/excalidraw/components/Stats/Position.tsx +++ b/packages/excalidraw/components/Stats/Position.tsx @@ -3,15 +3,16 @@ import { clamp, pointFrom, pointRotateRads, round } from "@excalidraw/math"; import { getFlipAdjustedCropPosition, getUncroppedWidthAndHeight, -} from "../../element/cropElement"; -import { mutateElement } from "../../element/mutateElement"; -import { isImageElement } from "../../element/typeChecks"; +} from "@excalidraw/element/cropElement"; +import { mutateElement } from "@excalidraw/element/mutateElement"; +import { isImageElement } from "@excalidraw/element/typeChecks"; + +import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types"; import StatsDragInput from "./DragInput"; import { getStepSizedValue, moveElement } from "./utils"; import type { DragInputCallbackType } from "./DragInput"; -import type { ElementsMap, ExcalidrawElement } from "../../element/types"; import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; diff --git a/packages/excalidraw/components/Stats/index.tsx b/packages/excalidraw/components/Stats/index.tsx index 56764fefb3..889f789717 100644 --- a/packages/excalidraw/components/Stats/index.tsx +++ b/packages/excalidraw/components/Stats/index.tsx @@ -3,12 +3,17 @@ import clsx from "clsx"; import throttle from "lodash.throttle"; import { useEffect, useMemo, useState, memo } from "react"; -import { STATS_PANELS } from "../../constants"; -import { getCommonBounds } from "../../element/bounds"; -import { getUncroppedWidthAndHeight } from "../../element/cropElement"; -import { isElbowArrow, isImageElement } from "../../element/typeChecks"; -import { frameAndChildrenSelectedTogether } from "../../frame"; -import { elementsAreInSameGroup } from "../../groups"; +import { STATS_PANELS } from "@excalidraw/common"; +import { getCommonBounds } from "@excalidraw/element/bounds"; +import { getUncroppedWidthAndHeight } from "@excalidraw/element/cropElement"; +import { isElbowArrow, isImageElement } from "@excalidraw/element/typeChecks"; + +import { frameAndChildrenSelectedTogether } from "@excalidraw/element/frame"; + +import { elementsAreInSameGroup } from "@excalidraw/element/groups"; + +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; + import { t } from "../../i18n"; import { isGridModeEnabled } from "../../snapping"; import { useExcalidrawAppState, useExcalidrawSetAppState } from "../App"; @@ -29,7 +34,6 @@ import { getAtomicUnits } from "./utils"; import "./Stats.scss"; -import type { NonDeletedExcalidrawElement } from "../../element/types"; import type { AppClassProperties, AppState, diff --git a/packages/excalidraw/components/Stats/stats.test.tsx b/packages/excalidraw/components/Stats/stats.test.tsx index b1fe0d6859..fc94da0564 100644 --- a/packages/excalidraw/components/Stats/stats.test.tsx +++ b/packages/excalidraw/components/Stats/stats.test.tsx @@ -3,14 +3,23 @@ import { act, fireEvent, queryByTestId } from "@testing-library/react"; import React from "react"; import { vi } from "vitest"; +import { setDateTimeForTests, reseed } from "@excalidraw/common"; + +import { isInGroup } from "@excalidraw/element/groups"; + +import { isTextElement } from "@excalidraw/element/typeChecks"; + import type { Degrees } from "@excalidraw/math"; -import { Excalidraw, mutateElement } from "../.."; +import type { + ExcalidrawElement, + ExcalidrawLinearElement, + ExcalidrawTextElement, +} from "@excalidraw/element/types"; + +import { Excalidraw, getCommonBounds, mutateElement } from "../.."; import { actionGroup } from "../../actions"; -import { getCommonBounds, isTextElement } from "../../element"; -import { isInGroup } from "../../groups"; import { t } from "../../i18n"; -import { reseed } from "../../random"; import * as StaticScene from "../../renderer/staticScene"; import { API } from "../../tests/helpers/api"; import { Keyboard, Pointer, UI } from "../../tests/helpers/ui"; @@ -21,16 +30,9 @@ import { render, restoreOriginalGetBoundingClientRect, } from "../../tests/test-utils"; -import { setDateTimeForTests } from "../../utils"; import { getStepSizedValue } from "./utils"; -import type { - ExcalidrawElement, - ExcalidrawLinearElement, - ExcalidrawTextElement, -} from "../../element/types"; - const { h } = window; const mouse = new Pointer("mouse"); const renderStaticScene = vi.spyOn(StaticScene, "renderStaticScene"); diff --git a/packages/excalidraw/components/Stats/utils.ts b/packages/excalidraw/components/Stats/utils.ts index 219e02fa55..dbb47a2346 100644 --- a/packages/excalidraw/components/Stats/utils.ts +++ b/packages/excalidraw/components/Stats/utils.ts @@ -1,30 +1,32 @@ import { pointFrom, pointRotateRads } from "@excalidraw/math"; -import type { Radians } from "@excalidraw/math"; - import { bindOrUnbindLinearElements, updateBoundElements, -} from "../../element/binding"; -import { mutateElement } from "../../element/mutateElement"; -import { getBoundTextElement } from "../../element/textElement"; +} from "@excalidraw/element/binding"; +import { mutateElement } from "@excalidraw/element/mutateElement"; +import { getBoundTextElement } from "@excalidraw/element/textElement"; import { isFrameLikeElement, isLinearElement, isTextElement, -} from "../../element/typeChecks"; +} from "@excalidraw/element/typeChecks"; + import { getSelectedGroupIds, getElementsInGroup, isInGroup, -} from "../../groups"; +} from "@excalidraw/element/groups"; + +import type { Radians } from "@excalidraw/math"; import type { ElementsMap, ExcalidrawElement, NonDeletedExcalidrawElement, NonDeletedSceneElementsMap, -} from "../../element/types"; +} from "@excalidraw/element/types"; + import type Scene from "../../scene/Scene"; import type { AppState } from "../../types"; diff --git a/packages/excalidraw/components/TTDDialog/MermaidToExcalidraw.tsx b/packages/excalidraw/components/TTDDialog/MermaidToExcalidraw.tsx index b8cd48dfad..8a4f92840b 100644 --- a/packages/excalidraw/components/TTDDialog/MermaidToExcalidraw.tsx +++ b/packages/excalidraw/components/TTDDialog/MermaidToExcalidraw.tsx @@ -1,11 +1,13 @@ import { useState, useRef, useEffect, useDeferredValue } from "react"; +import { EDITOR_LS_KEYS, debounce, isDevEnv } from "@excalidraw/common"; + +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; + import { useApp } from "../App"; import { ArrowRightIcon } from "../icons"; -import { EDITOR_LS_KEYS } from "../../constants"; import { EditorLocalStorage } from "../../data/EditorLocalStorage"; import { t } from "../../i18n"; -import { debounce, isDevEnv } from "../../utils"; import Trans from "../Trans"; import { TTDDialogInput } from "./TTDDialogInput"; @@ -23,7 +25,6 @@ import "./MermaidToExcalidraw.scss"; import type { BinaryFiles } from "../../types"; import type { MermaidToExcalidrawLibProps } from "./common"; -import type { NonDeletedExcalidrawElement } from "../../element/types"; const MERMAID_EXAMPLE = "flowchart TD\n A[Christmas] -->|Get money| B(Go shopping)\n B --> C{Let me think}\n C -->|One| D[Laptop]\n C -->|Two| E[iPhone]\n C -->|Three| F[Car]"; diff --git a/packages/excalidraw/components/TTDDialog/TTDDialog.tsx b/packages/excalidraw/components/TTDDialog/TTDDialog.tsx index 3b9b868f78..68d230d245 100644 --- a/packages/excalidraw/components/TTDDialog/TTDDialog.tsx +++ b/packages/excalidraw/components/TTDDialog/TTDDialog.tsx @@ -1,6 +1,9 @@ -import { isFiniteNumber } from "@excalidraw/math"; import { useEffect, useRef, useState } from "react"; +import { isFiniteNumber } from "@excalidraw/math"; + +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; + import { trackEvent } from "../../analytics"; import { useUIAppState } from "../../context/ui-appState"; import { atom, useAtom } from "../../editor-jotai"; @@ -32,7 +35,7 @@ import "./TTDDialog.scss"; import type { ChangeEventHandler } from "react"; import type { MermaidToExcalidrawLibProps } from "./common"; -import type { NonDeletedExcalidrawElement } from "../../element/types"; + import type { BinaryFiles } from "../../types"; const MIN_PROMPT_LENGTH = 3; diff --git a/packages/excalidraw/components/TTDDialog/TTDDialogInput.tsx b/packages/excalidraw/components/TTDDialog/TTDDialogInput.tsx index 8e349643e3..9bd80b681c 100644 --- a/packages/excalidraw/components/TTDDialog/TTDDialogInput.tsx +++ b/packages/excalidraw/components/TTDDialog/TTDDialogInput.tsx @@ -1,7 +1,6 @@ import { useEffect, useRef } from "react"; -import { EVENT } from "../../constants"; -import { KEYS } from "../../keys"; +import { EVENT, KEYS } from "@excalidraw/common"; import type { ChangeEventHandler } from "react"; diff --git a/packages/excalidraw/components/TTDDialog/TTDDialogSubmitShortcut.tsx b/packages/excalidraw/components/TTDDialog/TTDDialogSubmitShortcut.tsx index a8831e3a0b..05cad640b8 100644 --- a/packages/excalidraw/components/TTDDialog/TTDDialogSubmitShortcut.tsx +++ b/packages/excalidraw/components/TTDDialog/TTDDialogSubmitShortcut.tsx @@ -1,4 +1,4 @@ -import { getShortcutKey } from "../../utils"; +import { getShortcutKey } from "@excalidraw/common"; export const TTDDialogSubmitShortcut = () => { return ( diff --git a/packages/excalidraw/components/TTDDialog/TTDDialogTabs.tsx b/packages/excalidraw/components/TTDDialog/TTDDialogTabs.tsx index 1c9075e7d6..fe41281062 100644 --- a/packages/excalidraw/components/TTDDialog/TTDDialogTabs.tsx +++ b/packages/excalidraw/components/TTDDialog/TTDDialogTabs.tsx @@ -1,7 +1,8 @@ import * as RadixTabs from "@radix-ui/react-tabs"; import { useRef } from "react"; -import { isMemberOf } from "../../utils"; +import { isMemberOf } from "@excalidraw/common"; + import { useExcalidrawSetAppState } from "../App"; import type { ReactNode } from "react"; diff --git a/packages/excalidraw/components/TTDDialog/common.ts b/packages/excalidraw/components/TTDDialog/common.ts index 89c342c653..2e59565cfa 100644 --- a/packages/excalidraw/components/TTDDialog/common.ts +++ b/packages/excalidraw/components/TTDDialog/common.ts @@ -1,13 +1,15 @@ +import { DEFAULT_EXPORT_PADDING, EDITOR_LS_KEYS } from "@excalidraw/common"; + import type { MermaidConfig } from "@excalidraw/mermaid-to-excalidraw"; import type { MermaidToExcalidrawResult } from "@excalidraw/mermaid-to-excalidraw/dist/interfaces"; -import { DEFAULT_EXPORT_PADDING, EDITOR_LS_KEYS } from "../../constants"; +import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; + import { EditorLocalStorage } from "../../data/EditorLocalStorage"; import { canvasToBlob } from "../../data/blob"; import { t } from "../../i18n"; import { convertToExcalidrawElements, exportToCanvas } from "../../index"; -import type { NonDeletedExcalidrawElement } from "../../element/types"; import type { AppClassProperties, BinaryFiles } from "../../types"; const resetPreview = ({ diff --git a/packages/excalidraw/components/ToolButton.tsx b/packages/excalidraw/components/ToolButton.tsx index fb76731b02..f833a6d1f0 100644 --- a/packages/excalidraw/components/ToolButton.tsx +++ b/packages/excalidraw/components/ToolButton.tsx @@ -1,15 +1,17 @@ import clsx from "clsx"; import React, { useEffect, useRef, useState } from "react"; +import { isPromiseLike } from "@excalidraw/common"; + +import type { PointerType } from "@excalidraw/element/types"; + import { AbortError } from "../errors"; -import { isPromiseLike } from "../utils"; import "./ToolIcon.scss"; import Spinner from "./Spinner"; import { useExcalidrawContainer } from "./App"; -import type { PointerType } from "../element/types"; import type { CSSProperties } from "react"; export type ToolButtonSize = "small" | "medium"; diff --git a/packages/excalidraw/components/UserList.scss b/packages/excalidraw/components/UserList.scss index fdcadef7e6..025f4d16ec 100644 --- a/packages/excalidraw/components/UserList.scss +++ b/packages/excalidraw/components/UserList.scss @@ -1,4 +1,4 @@ -@import "../css/variables.module"; +@import "../css/variables.module.scss"; .excalidraw { --avatar-size: 1.75rem; diff --git a/packages/excalidraw/components/UserList.tsx b/packages/excalidraw/components/UserList.tsx index 6c74411a1c..8112893292 100644 --- a/packages/excalidraw/components/UserList.tsx +++ b/packages/excalidraw/components/UserList.tsx @@ -2,9 +2,11 @@ import * as Popover from "@radix-ui/react-popover"; import clsx from "clsx"; import React, { useLayoutEffect } from "react"; -import { supportsResizeObserver } from "../constants"; +import { supportsResizeObserver, isShallowEqual } from "@excalidraw/common"; + +import type { MarkRequired } from "@excalidraw/common/utility-types"; + import { t } from "../i18n"; -import { isShallowEqual } from "../utils"; import { useExcalidrawActionManager } from "./App"; import { Island } from "./Island"; @@ -16,7 +18,6 @@ import "./UserList.scss"; import type { ActionManager } from "../actions/manager"; import type { Collaborator, SocketId } from "../types"; -import type { MarkRequired } from "../utility-types"; export type GoToCollaboratorComponentProps = { socketId: SocketId; diff --git a/packages/excalidraw/components/canvases/InteractiveCanvas.tsx b/packages/excalidraw/components/canvases/InteractiveCanvas.tsx index 8388e5e6cc..1f4f574333 100644 --- a/packages/excalidraw/components/canvases/InteractiveCanvas.tsx +++ b/packages/excalidraw/components/canvases/InteractiveCanvas.tsx @@ -1,15 +1,20 @@ import React, { useEffect, useRef } from "react"; -import { CURSOR_TYPE } from "../../constants"; -import { t } from "../../i18n"; -import { isRenderThrottlingEnabled } from "../../reactUtils"; -import { renderInteractiveScene } from "../../renderer/interactiveScene"; -import { isShallowEqual, sceneCoordsToViewportCoords } from "../../utils"; +import { + CURSOR_TYPE, + isShallowEqual, + sceneCoordsToViewportCoords, +} from "@excalidraw/common"; import type { NonDeletedExcalidrawElement, NonDeletedSceneElementsMap, -} from "../../element/types"; +} from "@excalidraw/element/types"; + +import { t } from "../../i18n"; +import { isRenderThrottlingEnabled } from "../../reactUtils"; +import { renderInteractiveScene } from "../../renderer/interactiveScene"; + import type { InteractiveCanvasRenderConfig, RenderableElementsMap, diff --git a/packages/excalidraw/components/canvases/NewElementCanvas.tsx b/packages/excalidraw/components/canvases/NewElementCanvas.tsx index 524d6af34d..4310f1bd1a 100644 --- a/packages/excalidraw/components/canvases/NewElementCanvas.tsx +++ b/packages/excalidraw/components/canvases/NewElementCanvas.tsx @@ -1,9 +1,10 @@ import { useEffect, useRef } from "react"; +import type { NonDeletedSceneElementsMap } from "@excalidraw/element/types"; + import { isRenderThrottlingEnabled } from "../../reactUtils"; import { renderNewElementScene } from "../../renderer/renderNewElementScene"; -import type { NonDeletedSceneElementsMap } from "../../element/types"; import type { RenderableElementsMap, StaticCanvasRenderConfig, diff --git a/packages/excalidraw/components/canvases/StaticCanvas.tsx b/packages/excalidraw/components/canvases/StaticCanvas.tsx index 6e2df95373..b70c8ace6d 100644 --- a/packages/excalidraw/components/canvases/StaticCanvas.tsx +++ b/packages/excalidraw/components/canvases/StaticCanvas.tsx @@ -1,13 +1,15 @@ import React, { useEffect, useRef } from "react"; -import { isRenderThrottlingEnabled } from "../../reactUtils"; -import { renderStaticScene } from "../../renderer/staticScene"; -import { isShallowEqual } from "../../utils"; +import { isShallowEqual } from "@excalidraw/common"; import type { NonDeletedExcalidrawElement, NonDeletedSceneElementsMap, -} from "../../element/types"; +} from "@excalidraw/element/types"; + +import { isRenderThrottlingEnabled } from "../../reactUtils"; +import { renderStaticScene } from "../../renderer/staticScene"; + import type { RenderableElementsMap, StaticCanvasRenderConfig, diff --git a/packages/excalidraw/components/dropdownMenu/DropdownMenu.test.tsx b/packages/excalidraw/components/dropdownMenu/DropdownMenu.test.tsx index d4c0b7a8d0..5be65b1001 100644 --- a/packages/excalidraw/components/dropdownMenu/DropdownMenu.test.tsx +++ b/packages/excalidraw/components/dropdownMenu/DropdownMenu.test.tsx @@ -1,7 +1,8 @@ import React from "react"; +import { KEYS } from "@excalidraw/common"; + import { Excalidraw } from "../../index"; -import { KEYS } from "../../keys"; import { Keyboard } from "../../tests/helpers/ui"; import { render, diff --git a/packages/excalidraw/components/dropdownMenu/DropdownMenuContent.tsx b/packages/excalidraw/components/dropdownMenu/DropdownMenuContent.tsx index 24a0a4d27e..de6fc31c18 100644 --- a/packages/excalidraw/components/dropdownMenu/DropdownMenuContent.tsx +++ b/packages/excalidraw/components/dropdownMenu/DropdownMenuContent.tsx @@ -1,10 +1,10 @@ import clsx from "clsx"; import React, { useEffect, useRef } from "react"; -import { EVENT } from "../../constants"; +import { EVENT, KEYS } from "@excalidraw/common"; + import { useOutsideClick } from "../../hooks/useOutsideClick"; import { useStable } from "../../hooks/useStable"; -import { KEYS } from "../../keys"; import { useDevice } from "../App"; import { Island } from "../Island"; import Stack from "../Stack"; diff --git a/packages/excalidraw/components/dropdownMenu/DropdownMenuItem.tsx b/packages/excalidraw/components/dropdownMenu/DropdownMenuItem.tsx index fc19bd1bfc..59c5dd2f84 100644 --- a/packages/excalidraw/components/dropdownMenu/DropdownMenuItem.tsx +++ b/packages/excalidraw/components/dropdownMenu/DropdownMenuItem.tsx @@ -1,6 +1,9 @@ import React, { useEffect, useRef } from "react"; -import { THEME } from "../../constants"; +import { THEME } from "@excalidraw/common"; + +import type { ValueOf } from "@excalidraw/common/utility-types"; + import { useExcalidrawAppState } from "../App"; import MenuItemContent from "./DropdownMenuItemContent"; @@ -9,7 +12,6 @@ import { useHandleDropdownMenuItemClick, } from "./common"; -import type { ValueOf } from "../../utility-types"; import type { JSX } from "react"; const DropdownMenuItem = ({ diff --git a/packages/excalidraw/components/dropdownMenu/common.ts b/packages/excalidraw/components/dropdownMenu/common.ts index 312b78aaea..feca5c4060 100644 --- a/packages/excalidraw/components/dropdownMenu/common.ts +++ b/packages/excalidraw/components/dropdownMenu/common.ts @@ -1,7 +1,6 @@ import React, { useContext } from "react"; -import { EVENT } from "../../constants"; -import { composeEventHandlers } from "../../utils"; +import { EVENT, composeEventHandlers } from "@excalidraw/common"; export const DropdownMenuContentPropsContext = React.createContext<{ onSelect?: (event: Event) => void; diff --git a/packages/excalidraw/components/hyperlink/Hyperlink.tsx b/packages/excalidraw/components/hyperlink/Hyperlink.tsx index 88983aeab4..9a386a1635 100644 --- a/packages/excalidraw/components/hyperlink/Hyperlink.tsx +++ b/packages/excalidraw/components/hyperlink/Hyperlink.tsx @@ -8,37 +8,51 @@ import { useState, } from "react"; -import { trackEvent } from "../../analytics"; -import { getTooltipDiv, updateTooltipPosition } from "../../components/Tooltip"; -import { EVENT, HYPERLINK_TOOLTIP_DELAY } from "../../constants"; -import { isLocalLink, normalizeLink } from "../../data/url"; -import { getElementAbsoluteCoords } from "../../element/bounds"; -import { hitElementBoundingBox } from "../../element/collision"; -import { isElementLink } from "../../element/elementLink"; -import { getEmbedLink, embeddableURLValidator } from "../../element/embeddable"; -import { mutateElement } from "../../element/mutateElement"; -import { t } from "../../i18n"; +import { EVENT, HYPERLINK_TOOLTIP_DELAY, KEYS } from "@excalidraw/common"; + +import { getElementAbsoluteCoords } from "@excalidraw/element/bounds"; + +import { hitElementBoundingBox } from "@excalidraw/element/collision"; + +import { isElementLink } from "@excalidraw/element/elementLink"; + +import { + getEmbedLink, + embeddableURLValidator, +} from "@excalidraw/element/embeddable"; + +import { mutateElement } from "@excalidraw/element/mutateElement"; + import { sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, wrapEvent, -} from "../../utils"; -import { useAppProps, useDevice, useExcalidrawAppState } from "../App"; -import { ToolButton } from "../ToolButton"; -import { FreedrawIcon, TrashIcon, elementLinkIcon } from "../icons"; -import { KEYS } from "../../keys"; -import { getSelectedElements } from "../../scene"; -import { isEmbeddableElement } from "../../element/typeChecks"; + isLocalLink, + normalizeLink, +} from "@excalidraw/common"; -import { getLinkHandleFromCoords } from "./helpers"; - -import "./Hyperlink.scss"; +import { isEmbeddableElement } from "@excalidraw/element/typeChecks"; import type { ElementsMap, ExcalidrawEmbeddableElement, NonDeletedExcalidrawElement, -} from "../../element/types"; +} from "@excalidraw/element/types"; + +import { trackEvent } from "../../analytics"; +import { getTooltipDiv, updateTooltipPosition } from "../../components/Tooltip"; + +import { t } from "../../i18n"; + +import { useAppProps, useDevice, useExcalidrawAppState } from "../App"; +import { ToolButton } from "../ToolButton"; +import { FreedrawIcon, TrashIcon, elementLinkIcon } from "../icons"; +import { getSelectedElements } from "../../scene"; + +import { getLinkHandleFromCoords } from "./helpers"; + +import "./Hyperlink.scss"; + import type { AppState, ExcalidrawProps, UIAppState } from "../../types"; const POPUP_WIDTH = 380; diff --git a/packages/excalidraw/components/hyperlink/helpers.ts b/packages/excalidraw/components/hyperlink/helpers.ts index 3d39e2ebeb..d1345db983 100644 --- a/packages/excalidraw/components/hyperlink/helpers.ts +++ b/packages/excalidraw/components/hyperlink/helpers.ts @@ -1,17 +1,19 @@ import { pointFrom, pointRotateRads } from "@excalidraw/math"; +import { MIME_TYPES } from "@excalidraw/common"; +import { getElementAbsoluteCoords } from "@excalidraw/element/bounds"; +import { hitElementBoundingBox } from "@excalidraw/element/collision"; + +import { DEFAULT_LINK_SIZE } from "@excalidraw/element/renderElement"; + import type { GlobalPoint, Radians } from "@excalidraw/math"; -import { MIME_TYPES } from "../../constants"; -import { getElementAbsoluteCoords } from "../../element/bounds"; -import { hitElementBoundingBox } from "../../element/collision"; -import { DEFAULT_LINK_SIZE } from "../../renderer/renderElement"; - -import type { Bounds } from "../../element/bounds"; +import type { Bounds } from "@excalidraw/element/bounds"; import type { ElementsMap, NonDeletedExcalidrawElement, -} from "../../element/types"; +} from "@excalidraw/element/types"; + import type { AppState, UIAppState } from "../../types"; export const EXTERNAL_LINK_IMG = document.createElement("img"); diff --git a/packages/excalidraw/components/icons.tsx b/packages/excalidraw/components/icons.tsx index 03e6ca2bb7..c6d7f94732 100644 --- a/packages/excalidraw/components/icons.tsx +++ b/packages/excalidraw/components/icons.tsx @@ -10,9 +10,9 @@ import clsx from "clsx"; import oc from "open-color"; import React from "react"; -import { THEME } from "../constants"; +import { THEME } from "@excalidraw/common"; -import type { Theme } from "../element/types"; +import type { Theme } from "@excalidraw/element/types"; export const iconFillColor = (theme: Theme) => "var(--icon-fill-color)"; diff --git a/packages/excalidraw/components/main-menu/DefaultItems.tsx b/packages/excalidraw/components/main-menu/DefaultItems.tsx index c2307d521d..29a2761a10 100644 --- a/packages/excalidraw/components/main-menu/DefaultItems.tsx +++ b/packages/excalidraw/components/main-menu/DefaultItems.tsx @@ -1,5 +1,9 @@ import clsx from "clsx"; +import { THEME } from "@excalidraw/common"; + +import type { Theme } from "@excalidraw/element/types"; + import { actionClearCanvas, actionLoadScene, @@ -10,7 +14,6 @@ import { } from "../../actions"; import { getShortcutFromShortcutName } from "../../actions/shortcuts"; import { trackEvent } from "../../analytics"; -import { THEME } from "../../constants"; import { useUIAppState } from "../../context/ui-appState"; import { useSetAtom } from "../../editor-jotai"; import { useI18n } from "../../i18n"; @@ -44,8 +47,6 @@ import { import "./DefaultItems.scss"; -import type { Theme } from "../../element/types"; - export const LoadScene = () => { const { t } = useI18n(); const actionManager = useExcalidrawActionManager(); diff --git a/packages/excalidraw/components/main-menu/MainMenu.tsx b/packages/excalidraw/components/main-menu/MainMenu.tsx index 54f60a364c..7c2b5fb4a1 100644 --- a/packages/excalidraw/components/main-menu/MainMenu.tsx +++ b/packages/excalidraw/components/main-menu/MainMenu.tsx @@ -1,9 +1,10 @@ import React from "react"; +import { composeEventHandlers } from "@excalidraw/common"; + import { useTunnels } from "../../context/tunnels"; import { useUIAppState } from "../../context/ui-appState"; import { t } from "../../i18n"; -import { composeEventHandlers } from "../../utils"; import { useDevice, useExcalidrawSetAppState } from "../App"; import { UserList } from "../UserList"; import DropdownMenu from "../dropdownMenu/DropdownMenu"; diff --git a/packages/excalidraw/components/shapes.tsx b/packages/excalidraw/components/shapes.tsx new file mode 100644 index 0000000000..7411a9e252 --- /dev/null +++ b/packages/excalidraw/components/shapes.tsx @@ -0,0 +1,100 @@ +import { KEYS } from "@excalidraw/common"; + +import { + SelectionIcon, + RectangleIcon, + DiamondIcon, + EllipseIcon, + ArrowIcon, + LineIcon, + FreedrawIcon, + TextIcon, + ImageIcon, + EraserIcon, +} from "./icons"; + +export const SHAPES = [ + { + icon: SelectionIcon, + value: "selection", + key: KEYS.V, + numericKey: KEYS["1"], + fillable: true, + }, + { + icon: RectangleIcon, + value: "rectangle", + key: KEYS.R, + numericKey: KEYS["2"], + fillable: true, + }, + { + icon: DiamondIcon, + value: "diamond", + key: KEYS.D, + numericKey: KEYS["3"], + fillable: true, + }, + { + icon: EllipseIcon, + value: "ellipse", + key: KEYS.O, + numericKey: KEYS["4"], + fillable: true, + }, + { + icon: ArrowIcon, + value: "arrow", + key: KEYS.A, + numericKey: KEYS["5"], + fillable: true, + }, + { + icon: LineIcon, + value: "line", + key: KEYS.L, + numericKey: KEYS["6"], + fillable: true, + }, + { + icon: FreedrawIcon, + value: "freedraw", + key: [KEYS.P, KEYS.X], + numericKey: KEYS["7"], + fillable: false, + }, + { + icon: TextIcon, + value: "text", + key: KEYS.T, + numericKey: KEYS["8"], + fillable: false, + }, + { + icon: ImageIcon, + value: "image", + key: null, + numericKey: KEYS["9"], + fillable: false, + }, + { + icon: EraserIcon, + value: "eraser", + key: KEYS.E, + numericKey: KEYS["0"], + fillable: false, + }, +] as const; + +export const findShapeByKey = (key: string) => { + const shape = SHAPES.find((shape, index) => { + return ( + (shape.numericKey != null && key === shape.numericKey.toString()) || + (shape.key && + (typeof shape.key === "string" + ? shape.key === key + : (shape.key as readonly string[]).includes(key))) + ); + }); + return shape?.value || null; +}; diff --git a/packages/excalidraw/cursor.ts b/packages/excalidraw/cursor.ts index 1aa6e52d2b..7125ccedf3 100644 --- a/packages/excalidraw/cursor.ts +++ b/packages/excalidraw/cursor.ts @@ -1,7 +1,8 @@ import OpenColor from "open-color"; +import { CURSOR_TYPE, MIME_TYPES, THEME } from "@excalidraw/common"; + import { isHandToolActive, isEraserActive } from "./appState"; -import { CURSOR_TYPE, MIME_TYPES, THEME } from "./constants"; import type { AppState, DataURL } from "./types"; diff --git a/packages/excalidraw/data/EditorLocalStorage.ts b/packages/excalidraw/data/EditorLocalStorage.ts index bb6eeb478a..18d3053154 100644 --- a/packages/excalidraw/data/EditorLocalStorage.ts +++ b/packages/excalidraw/data/EditorLocalStorage.ts @@ -1,4 +1,5 @@ -import type { EDITOR_LS_KEYS } from "../constants"; +import type { EDITOR_LS_KEYS } from "@excalidraw/common"; + import type { JSONValue } from "../types"; export class EditorLocalStorage { diff --git a/packages/excalidraw/data/blob.ts b/packages/excalidraw/data/blob.ts index 54505068f6..3e5db7c29e 100644 --- a/packages/excalidraw/data/blob.ts +++ b/packages/excalidraw/data/blob.ts @@ -1,22 +1,31 @@ import { nanoid } from "nanoid"; +import { + IMAGE_MIME_TYPES, + MIME_TYPES, + bytesToHexString, + isPromiseLike, +} from "@excalidraw/common"; + +import { clearElementsForExport } from "@excalidraw/element"; + +import type { ValueOf } from "@excalidraw/common/utility-types"; +import type { ExcalidrawElement, FileId } from "@excalidraw/element/types"; + import { cleanAppStateForExport } from "../appState"; -import { IMAGE_MIME_TYPES, MIME_TYPES } from "../constants"; -import { clearElementsForExport } from "../element"; + import { CanvasError, ImageSceneDataError } from "../errors"; import { calculateScrollCenter } from "../scene"; import { decodeSvgBase64Payload } from "../scene/export"; -import { bytesToHexString, isPromiseLike } from "../utils"; import { base64ToString, stringToBase64, toByteString } from "./encode"; import { nativeFileSystemSupported } from "./filesystem"; import { isValidExcalidrawData, isValidLibrary } from "./json"; import { restore, restoreLibraryItems } from "./restore"; -import type { FileSystemHandle } from "./filesystem"; -import type { ExcalidrawElement, FileId } from "../element/types"; import type { AppState, DataURL, LibraryItem } from "../types"; -import type { ValueOf } from "../utility-types"; + +import type { FileSystemHandle } from "./filesystem"; import type { ImportedLibraryData } from "./types"; const parseFileContents = async (blob: Blob | File): Promise => { diff --git a/packages/excalidraw/data/encryption.ts b/packages/excalidraw/data/encryption.ts index a796d05b43..ee1a88f351 100644 --- a/packages/excalidraw/data/encryption.ts +++ b/packages/excalidraw/data/encryption.ts @@ -1,4 +1,4 @@ -import { ENCRYPTION_KEY_BITS } from "../constants"; +import { ENCRYPTION_KEY_BITS } from "@excalidraw/common"; import { blobToArrayBuffer } from "./blob"; diff --git a/packages/excalidraw/data/filesystem.ts b/packages/excalidraw/data/filesystem.ts index 0bdab68fd6..0f4ae745f9 100644 --- a/packages/excalidraw/data/filesystem.ts +++ b/packages/excalidraw/data/filesystem.ts @@ -4,9 +4,9 @@ import { supported as nativeFileSystemSupported, } from "browser-fs-access"; -import { EVENT, MIME_TYPES } from "../constants"; +import { EVENT, MIME_TYPES, debounce } from "@excalidraw/common"; + import { AbortError } from "../errors"; -import { debounce } from "../utils"; import type { FileSystemHandle } from "browser-fs-access"; diff --git a/packages/excalidraw/data/image.ts b/packages/excalidraw/data/image.ts index e54f7bab50..c9c84c95bb 100644 --- a/packages/excalidraw/data/image.ts +++ b/packages/excalidraw/data/image.ts @@ -2,7 +2,7 @@ import tEXt from "png-chunk-text"; import encodePng from "png-chunks-encode"; import decodePng from "png-chunks-extract"; -import { EXPORT_DATA_TYPES, MIME_TYPES } from "../constants"; +import { EXPORT_DATA_TYPES, MIME_TYPES } from "@excalidraw/common"; import { blobToArrayBuffer } from "./blob"; import { encode, decode } from "./encode"; diff --git a/packages/excalidraw/data/index.ts b/packages/excalidraw/data/index.ts index 013ac5b756..ac8147e854 100644 --- a/packages/excalidraw/data/index.ts +++ b/packages/excalidraw/data/index.ts @@ -1,32 +1,39 @@ -import { - copyBlobToClipboardAsPng, - copyTextToSystemClipboard, -} from "../clipboard"; import { DEFAULT_EXPORT_PADDING, DEFAULT_FILENAME, IMAGE_MIME_TYPES, isFirefox, MIME_TYPES, -} from "../constants"; -import { getNonDeletedElements } from "../element"; -import { isFrameLikeElement } from "../element/typeChecks"; -import { getElementsOverlappingFrame } from "../frame"; + cloneJSON, +} from "@excalidraw/common"; + +import { getNonDeletedElements } from "@excalidraw/element"; + +import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; + +import { getElementsOverlappingFrame } from "@excalidraw/element/frame"; + +import type { + ExcalidrawElement, + ExcalidrawFrameLikeElement, + NonDeletedExcalidrawElement, +} from "@excalidraw/element/types"; + +import { + copyBlobToClipboardAsPng, + copyTextToSystemClipboard, +} from "../clipboard"; + import { t } from "../i18n"; import { getSelectedElements, isSomeElementSelected } from "../scene"; import { exportToCanvas, exportToSvg } from "../scene/export"; -import { cloneJSON } from "../utils"; import { canvasToBlob } from "./blob"; import { fileSave } from "./filesystem"; import { serializeAsJSON } from "./json"; import type { FileSystemHandle } from "./filesystem"; -import type { - ExcalidrawElement, - ExcalidrawFrameLikeElement, - NonDeletedExcalidrawElement, -} from "../element/types"; + import type { ExportType } from "../scene/types"; import type { AppState, BinaryFiles } from "../types"; diff --git a/packages/excalidraw/data/json.ts b/packages/excalidraw/data/json.ts index c1cdd4f92d..527c9e56e2 100644 --- a/packages/excalidraw/data/json.ts +++ b/packages/excalidraw/data/json.ts @@ -1,17 +1,23 @@ -import { cleanAppStateForExport, clearAppStateForDatabase } from "../appState"; import { DEFAULT_FILENAME, EXPORT_DATA_TYPES, EXPORT_SOURCE, MIME_TYPES, VERSIONS, -} from "../constants"; -import { clearElementsForDatabase, clearElementsForExport } from "../element"; +} from "@excalidraw/common"; + +import { + clearElementsForDatabase, + clearElementsForExport, +} from "@excalidraw/element"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + +import { cleanAppStateForExport, clearAppStateForDatabase } from "../appState"; import { isImageFileHandle, loadFromBlob, normalizeFile } from "./blob"; import { fileOpen, fileSave } from "./filesystem"; -import type { ExcalidrawElement } from "../element/types"; import type { AppState, BinaryFiles, LibraryItems } from "../types"; import type { ExportedDataState, diff --git a/packages/excalidraw/data/library.ts b/packages/excalidraw/data/library.ts index 76424f54ae..74252657e7 100644 --- a/packages/excalidraw/data/library.ts +++ b/packages/excalidraw/data/library.ts @@ -7,29 +7,35 @@ import { EVENT, DEFAULT_SIDEBAR, LIBRARY_SIDEBAR_TAB, -} from "../constants"; -import { atom, editorJotaiStore } from "../editor-jotai"; -import { hashElementsVersion, hashString } from "../element"; -import { getCommonBoundingBox } from "../element/bounds"; -import { Emitter } from "../emitter"; -import { AbortError } from "../errors"; -import { libraryItemSvgsCache } from "../hooks/useLibraryItemSvg"; -import { t } from "../i18n"; -import { Queue } from "../queue"; -import { arrayToMap, cloneJSON, preventUnload, promiseTry, resolvablePromise, -} from "../utils"; + toValidURL, + Queue, +} from "@excalidraw/common"; + +import { hashElementsVersion, hashString } from "@excalidraw/element"; + +import { getCommonBoundingBox } from "@excalidraw/element/bounds"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + +import type { MaybePromise } from "@excalidraw/common/utility-types"; + +import { atom, editorJotaiStore } from "../editor-jotai"; + +import { Emitter } from "../emitter"; +import { AbortError } from "../errors"; +import { libraryItemSvgsCache } from "../hooks/useLibraryItemSvg"; +import { t } from "../i18n"; import { loadLibraryFromBlob } from "./blob"; import { restoreLibraryItems } from "./restore"; -import { toValidURL } from "./url"; import type App from "../components/App"; -import type { ExcalidrawElement } from "../element/types"; + import type { LibraryItems, LibraryItem, @@ -37,7 +43,6 @@ import type { LibraryItemsSource, LibraryItems_anyVersion, } from "../types"; -import type { MaybePromise } from "../utility-types"; /** * format: hostname or hostname/pathname diff --git a/packages/excalidraw/data/reconcile.ts b/packages/excalidraw/data/reconcile.ts index 06e4a560b2..a69ee2deed 100644 --- a/packages/excalidraw/data/reconcile.ts +++ b/packages/excalidraw/data/reconcile.ts @@ -1,15 +1,18 @@ import throttle from "lodash.throttle"; +import { arrayToMap, isDevEnv, isTestEnv } from "@excalidraw/common"; + import { orderByFractionalIndex, syncInvalidIndices, validateFractionalIndices, -} from "../fractionalIndex"; -import { arrayToMap, isDevEnv, isTestEnv } from "../utils"; +} from "@excalidraw/element/fractionalIndex"; + +import type { OrderedExcalidrawElement } from "@excalidraw/element/types"; + +import type { MakeBrand } from "@excalidraw/common/utility-types"; -import type { OrderedExcalidrawElement } from "../element/types"; import type { AppState } from "../types"; -import type { MakeBrand } from "../utility-types"; export type ReconciledExcalidrawElement = OrderedExcalidrawElement & MakeBrand<"ReconciledElement">; diff --git a/packages/excalidraw/data/resave.ts b/packages/excalidraw/data/resave.ts index 2c448429aa..188041d691 100644 --- a/packages/excalidraw/data/resave.ts +++ b/packages/excalidraw/data/resave.ts @@ -1,8 +1,9 @@ +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { getFileHandleType, isImageFileHandleType } from "./blob"; import { exportCanvas, prepareElementsForExport } from "."; -import type { ExcalidrawElement } from "../element/types"; import type { AppState, BinaryFiles } from "../types"; export const resaveAsImageWithScene = async ( diff --git a/packages/excalidraw/data/restore.ts b/packages/excalidraw/data/restore.ts index df1a646212..d1002e61f3 100644 --- a/packages/excalidraw/data/restore.ts +++ b/packages/excalidraw/data/restore.ts @@ -1,8 +1,5 @@ import { isFiniteNumber, pointFrom } from "@excalidraw/math"; -import type { LocalPoint, Radians } from "@excalidraw/math"; - -import { getDefaultAppState } from "../appState"; import { DEFAULT_FONT_FAMILY, DEFAULT_TEXT_ALIGN, @@ -13,22 +10,24 @@ import { DEFAULT_ELEMENT_PROPS, DEFAULT_GRID_SIZE, DEFAULT_GRID_STEP, -} from "../constants"; -import { - getNonDeletedElements, - getNormalizedDimensions, - isInvisiblySmallElement, - refreshTextDimensions, -} from "../element"; -import { normalizeFixedPoint } from "../element/binding"; + randomId, + getUpdatedTimestamp, + updateActiveTool, + arrayToMap, + getSizeFromPoints, + normalizeLink, + getLineHeight, +} from "@excalidraw/common"; +import { getNonDeletedElements } from "@excalidraw/element"; +import { normalizeFixedPoint } from "@excalidraw/element/binding"; import { updateElbowArrowPoints, validateElbowPoints, -} from "../element/elbowArrow"; -import { LinearElementEditor } from "../element/linearElementEditor"; -import { bumpVersion } from "../element/mutateElement"; -import { getContainerElement } from "../element/textElement"; -import { detectLineHeight } from "../element/textMeasurements"; +} from "@excalidraw/element/elbowArrow"; +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; +import { bumpVersion } from "@excalidraw/element/mutateElement"; +import { getContainerElement } from "@excalidraw/element/textElement"; +import { detectLineHeight } from "@excalidraw/element/textMeasurements"; import { isArrowElement, isElbowArrow, @@ -36,20 +35,17 @@ import { isLinearElement, isTextElement, isUsingAdaptiveRadius, -} from "../element/typeChecks"; -import { getLineHeight } from "../fonts"; -import { syncInvalidIndices } from "../fractionalIndex"; -import { randomId } from "../random"; -import { - getNormalizedGridSize, - getNormalizedGridStep, - getNormalizedZoom, -} from "../scene"; -import { getUpdatedTimestamp, updateActiveTool } from "../utils"; -import { arrayToMap } from "../utils"; -import { getSizeFromPoints } from "../points"; +} from "@excalidraw/element/typeChecks"; -import { normalizeLink } from "./url"; +import { syncInvalidIndices } from "@excalidraw/element/fractionalIndex"; + +import { refreshTextDimensions } from "@excalidraw/element/newElement"; + +import { getNormalizedDimensions } from "@excalidraw/element/sizeHelpers"; + +import { isInvisiblySmallElement } from "@excalidraw/element/sizeHelpers"; + +import type { LocalPoint, Radians } from "@excalidraw/math"; import type { ExcalidrawArrowElement, @@ -65,9 +61,19 @@ import type { OrderedExcalidrawElement, PointBinding, StrokeRoundness, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import type { MarkOptional, Mutable } from "@excalidraw/common/utility-types"; + +import { getDefaultAppState } from "../appState"; + +import { + getNormalizedGridSize, + getNormalizedGridStep, + getNormalizedZoom, +} from "../scene"; + import type { AppState, BinaryFiles, LibraryItem } from "../types"; -import type { MarkOptional, Mutable } from "../utility-types"; import type { ImportedDataState, LegacyAppState } from "./types"; type RestoredAppState = Omit< diff --git a/packages/excalidraw/data/transform.test.ts b/packages/excalidraw/data/transform.test.ts index 94f7b6c822..27643e7e1e 100644 --- a/packages/excalidraw/data/transform.test.ts +++ b/packages/excalidraw/data/transform.test.ts @@ -1,10 +1,11 @@ import { pointFrom } from "@excalidraw/math"; import { vi } from "vitest"; +import type { ExcalidrawArrowElement } from "@excalidraw/element/types"; + import { convertToExcalidrawElements } from "./transform"; import type { ExcalidrawElementSkeleton } from "./transform"; -import type { ExcalidrawArrowElement } from "../element/types"; const opts = { regenerateIds: false }; diff --git a/packages/excalidraw/data/transform.ts b/packages/excalidraw/data/transform.ts index 704b63cb55..9def9f5fcc 100644 --- a/packages/excalidraw/data/transform.ts +++ b/packages/excalidraw/data/transform.ts @@ -5,37 +5,39 @@ import { DEFAULT_FONT_SIZE, TEXT_ALIGN, VERTICAL_ALIGN, -} from "../constants"; -import { - getCommonBounds, - newElement, - newLinearElement, - redrawTextBoundingBox, -} from "../element"; -import { bindLinearElement } from "../element/binding"; -import { - newArrowElement, - newFrameElement, - newImageElement, - newMagicFrameElement, - newTextElement, -} from "../element/newElement"; -import { measureText, normalizeText } from "../element/textMeasurements"; -import { isArrowElement } from "../element/typeChecks"; -import { getLineHeight } from "../fonts"; -import { syncInvalidIndices } from "../fractionalIndex"; -import { getSizeFromPoints } from "../points"; -import { randomId } from "../random"; -import { + getSizeFromPoints, + randomId, arrayToMap, assertNever, cloneJSON, getFontString, isDevEnv, toBrandedType, -} from "../utils"; + getLineHeight, +} from "@excalidraw/common"; + +import { bindLinearElement } from "@excalidraw/element/binding"; +import { + newArrowElement, + newElement, + newFrameElement, + newImageElement, + newLinearElement, + newMagicFrameElement, + newTextElement, +} from "@excalidraw/element/newElement"; +import { + measureText, + normalizeText, +} from "@excalidraw/element/textMeasurements"; +import { isArrowElement } from "@excalidraw/element/typeChecks"; + +import { syncInvalidIndices } from "@excalidraw/element/fractionalIndex"; + +import { redrawTextBoundingBox } from "@excalidraw/element/textElement"; + +import type { ElementConstructorOpts } from "@excalidraw/element/newElement"; -import type { ElementConstructorOpts } from "../element/newElement"; import type { ElementsMap, ExcalidrawArrowElement, @@ -55,8 +57,11 @@ import type { NonDeletedSceneElementsMap, TextAlign, VerticalAlign, -} from "../element/types"; -import type { MarkOptional } from "../utility-types"; +} from "@excalidraw/element/types"; + +import type { MarkOptional } from "@excalidraw/common/utility-types"; + +import { getCommonBounds } from ".."; export type ValidLinearElement = { type: "arrow" | "line"; diff --git a/packages/excalidraw/data/types.ts b/packages/excalidraw/data/types.ts index de3436137c..6878b81b18 100644 --- a/packages/excalidraw/data/types.ts +++ b/packages/excalidraw/data/types.ts @@ -1,6 +1,8 @@ +import type { VERSIONS } from "@excalidraw/common"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import type { cleanAppStateForExport } from "../appState"; -import type { VERSIONS } from "../constants"; -import type { ExcalidrawElement } from "../element/types"; import type { AppState, BinaryFiles, diff --git a/packages/excalidraw/errors.ts b/packages/excalidraw/errors.ts index d6091b0e91..20fe694cd2 100644 --- a/packages/excalidraw/errors.ts +++ b/packages/excalidraw/errors.ts @@ -33,10 +33,6 @@ export class ImageSceneDataError extends Error { } } -export class InvalidFractionalIndexError extends Error { - public code = "ELEMENT_HAS_INVALID_INDEX" as const; -} - type WorkerErrorCodes = "WORKER_URL_NOT_DEFINED" | "WORKER_IN_THE_MAIN_CHUNK"; export class WorkerUrlNotDefinedError extends Error { diff --git a/packages/excalidraw/fonts/Emoji/index.ts b/packages/excalidraw/fonts/Emoji/index.ts index 323d075cb2..09aea663d3 100644 --- a/packages/excalidraw/fonts/Emoji/index.ts +++ b/packages/excalidraw/fonts/Emoji/index.ts @@ -1,4 +1,5 @@ -import { LOCAL_FONT_PROTOCOL } from "../FontMetadata"; +import { LOCAL_FONT_PROTOCOL } from "@excalidraw/common"; + import { type ExcalidrawFontFaceDescriptor } from "../Fonts"; export const EmojiFontFaces: ExcalidrawFontFaceDescriptor[] = [ diff --git a/packages/excalidraw/fonts/ExcalidrawFontFace.ts b/packages/excalidraw/fonts/ExcalidrawFontFace.ts index 615fef20f9..46ea3d0180 100644 --- a/packages/excalidraw/fonts/ExcalidrawFontFace.ts +++ b/packages/excalidraw/fonts/ExcalidrawFontFace.ts @@ -1,7 +1,6 @@ -import { subsetWoff2GlyphsByCodepoints } from "../subset/subset-main"; -import { promiseTry } from "../utils"; +import { promiseTry, LOCAL_FONT_PROTOCOL } from "@excalidraw/common"; -import { LOCAL_FONT_PROTOCOL } from "./FontMetadata"; +import { subsetWoff2GlyphsByCodepoints } from "../subset/subset-main"; type DataURL = string; diff --git a/packages/excalidraw/fonts/Fonts.ts b/packages/excalidraw/fonts/Fonts.ts index c1b94bdefc..79b5ea1af7 100644 --- a/packages/excalidraw/fonts/Fonts.ts +++ b/packages/excalidraw/fonts/Fonts.ts @@ -4,20 +4,35 @@ import { CJK_HAND_DRAWN_FALLBACK_FONT, WINDOWS_EMOJI_FALLBACK_FONT, getFontFamilyFallbacks, -} from "../constants"; -import { isTextElement } from "../element"; -import { getContainerElement } from "../element/textElement"; -import { charWidth } from "../element/textMeasurements"; -import { containsCJK } from "../element/textWrapping"; -import { ShapeCache } from "../scene/ShapeCache"; -import { getFontString, PromisePool, promiseTry } from "../utils"; +} from "@excalidraw/common"; +import { getContainerElement } from "@excalidraw/element/textElement"; +import { charWidth } from "@excalidraw/element/textMeasurements"; +import { containsCJK } from "@excalidraw/element/textWrapping"; + +import { + FONT_METADATA, + type FontMetadata, + getFontString, + PromisePool, + promiseTry, +} from "@excalidraw/common"; + +import { ShapeCache } from "@excalidraw/element/ShapeCache"; + +import { isTextElement } from "@excalidraw/element/typeChecks"; + +import type { + ExcalidrawElement, + ExcalidrawTextElement, +} from "@excalidraw/element/types"; + +import type { ValueOf } from "@excalidraw/common/utility-types"; import { CascadiaFontFaces } from "./Cascadia"; import { ComicShannsFontFaces } from "./ComicShanns"; import { EmojiFontFaces } from "./Emoji"; import { ExcalidrawFontFace } from "./ExcalidrawFontFace"; import { ExcalifontFontFaces } from "./Excalifont"; -import { FONT_METADATA, type FontMetadata } from "./FontMetadata"; import { HelveticaFontFaces } from "./Helvetica"; import { LiberationFontFaces } from "./Liberation"; import { LilitaFontFaces } from "./Lilita"; @@ -25,13 +40,7 @@ import { NunitoFontFaces } from "./Nunito"; import { VirgilFontFaces } from "./Virgil"; import { XiaolaiFontFaces } from "./Xiaolai"; -import type { - ExcalidrawElement, - ExcalidrawTextElement, - FontFamilyValues, -} from "../element/types"; import type Scene from "../scene/Scene"; -import type { ValueOf } from "../utility-types"; export class Fonts { // it's ok to track fonts across multiple instances only once, so let's use @@ -454,37 +463,6 @@ export class Fonts { } } -/** - * Calculates vertical offset for a text with alphabetic baseline. - */ -export const getVerticalOffset = ( - fontFamily: ExcalidrawTextElement["fontFamily"], - fontSize: ExcalidrawTextElement["fontSize"], - lineHeightPx: number, -) => { - const { unitsPerEm, ascender, descender } = - Fonts.registered.get(fontFamily)?.metadata.metrics || - FONT_METADATA[FONT_FAMILY.Virgil].metrics; - - const fontSizeEm = fontSize / unitsPerEm; - const lineGap = - (lineHeightPx - fontSizeEm * ascender + fontSizeEm * descender) / 2; - - const verticalOffset = fontSizeEm * ascender + lineGap; - return verticalOffset; -}; - -/** - * Gets line height forr a selected family. - */ -export const getLineHeight = (fontFamily: FontFamilyValues) => { - const { lineHeight } = - Fonts.registered.get(fontFamily)?.metadata.metrics || - FONT_METADATA[FONT_FAMILY.Excalifont].metrics; - - return lineHeight as ExcalidrawTextElement["lineHeight"]; -}; - export interface ExcalidrawFontFaceDescriptor { uri: string; descriptors?: FontFaceDescriptors; diff --git a/packages/excalidraw/fonts/Helvetica/index.ts b/packages/excalidraw/fonts/Helvetica/index.ts index f13d151186..20a08e4643 100644 --- a/packages/excalidraw/fonts/Helvetica/index.ts +++ b/packages/excalidraw/fonts/Helvetica/index.ts @@ -1,4 +1,5 @@ -import { LOCAL_FONT_PROTOCOL } from "../FontMetadata"; +import { LOCAL_FONT_PROTOCOL } from "@excalidraw/common"; + import { type ExcalidrawFontFaceDescriptor } from "../Fonts"; export const HelveticaFontFaces: ExcalidrawFontFaceDescriptor[] = [ diff --git a/packages/excalidraw/fonts/Lilita/index.ts b/packages/excalidraw/fonts/Lilita/index.ts index 37a5d6a5e0..4641dcb0fe 100644 --- a/packages/excalidraw/fonts/Lilita/index.ts +++ b/packages/excalidraw/fonts/Lilita/index.ts @@ -1,4 +1,5 @@ -import { GOOGLE_FONTS_RANGES } from "../FontMetadata"; +import { GOOGLE_FONTS_RANGES } from "@excalidraw/common"; + import { type ExcalidrawFontFaceDescriptor } from "../Fonts"; import LilitaLatinExt from "./Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2"; diff --git a/packages/excalidraw/fonts/Nunito/index.ts b/packages/excalidraw/fonts/Nunito/index.ts index 3b092b0d6a..07fb757c86 100644 --- a/packages/excalidraw/fonts/Nunito/index.ts +++ b/packages/excalidraw/fonts/Nunito/index.ts @@ -1,4 +1,5 @@ -import { GOOGLE_FONTS_RANGES } from "../FontMetadata"; +import { GOOGLE_FONTS_RANGES } from "@excalidraw/common"; + import { type ExcalidrawFontFaceDescriptor } from "../Fonts"; import Cyrilic from "./Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2"; diff --git a/packages/excalidraw/global.d.ts b/packages/excalidraw/global.d.ts index 2072657160..e9b6c3f96c 100644 --- a/packages/excalidraw/global.d.ts +++ b/packages/excalidraw/global.d.ts @@ -2,9 +2,9 @@ interface Window { ClipboardItem: any; __EXCALIDRAW_SHA__: string | undefined; EXCALIDRAW_ASSET_PATH: string | string[] | undefined; - EXCALIDRAW_EXPORT_SOURCE: string; EXCALIDRAW_THROTTLE_RENDER: boolean | undefined; DEBUG_FRACTIONAL_INDICES: boolean | undefined; + EXCALIDRAW_EXPORT_SOURCE: string; gtag: Function; sa_event: Function; fathom: { trackEvent: Function }; diff --git a/packages/excalidraw/history.ts b/packages/excalidraw/history.ts index 48ea012bd4..0481c84113 100644 --- a/packages/excalidraw/history.ts +++ b/packages/excalidraw/history.ts @@ -1,7 +1,8 @@ +import type { SceneElementsMap } from "@excalidraw/element/types"; + import { Emitter } from "./emitter"; import type { AppStateChange, ElementsChange } from "./change"; -import type { SceneElementsMap } from "./element/types"; import type { Snapshot } from "./store"; import type { AppState } from "./types"; diff --git a/packages/excalidraw/hooks/useCreatePortalContainer.ts b/packages/excalidraw/hooks/useCreatePortalContainer.ts index b557d7e2f3..fb0d24bc3d 100644 --- a/packages/excalidraw/hooks/useCreatePortalContainer.ts +++ b/packages/excalidraw/hooks/useCreatePortalContainer.ts @@ -1,7 +1,8 @@ import { useState, useLayoutEffect } from "react"; +import { THEME } from "@excalidraw/common"; + import { useDevice, useExcalidrawContainer } from "../components/App"; -import { THEME } from "../constants"; import { useUIAppState } from "../context/ui-appState"; export const useCreatePortalContainer = (opts?: { diff --git a/packages/excalidraw/hooks/useLibraryItemSvg.ts b/packages/excalidraw/hooks/useLibraryItemSvg.ts index a79aab5c5b..ad423ab950 100644 --- a/packages/excalidraw/hooks/useLibraryItemSvg.ts +++ b/packages/excalidraw/hooks/useLibraryItemSvg.ts @@ -1,7 +1,8 @@ import { exportToSvg } from "@excalidraw/utils/export"; import { useEffect, useState } from "react"; -import { COLOR_PALETTE } from "../colors"; +import { COLOR_PALETTE } from "@excalidraw/common"; + import { atom, useAtom } from "../editor-jotai"; import type { LibraryItem } from "../types"; diff --git a/packages/excalidraw/hooks/useOutsideClick.ts b/packages/excalidraw/hooks/useOutsideClick.ts index 7ec2113c21..75d68f6e8b 100644 --- a/packages/excalidraw/hooks/useOutsideClick.ts +++ b/packages/excalidraw/hooks/useOutsideClick.ts @@ -1,6 +1,6 @@ import { useEffect } from "react"; -import { EVENT } from "../constants"; +import { EVENT } from "@excalidraw/common"; export function useOutsideClick( ref: React.RefObject, diff --git a/packages/excalidraw/i18n.ts b/packages/excalidraw/i18n.ts index 095b418dd7..3d39893f44 100644 --- a/packages/excalidraw/i18n.ts +++ b/packages/excalidraw/i18n.ts @@ -1,11 +1,11 @@ +import { isDevEnv } from "@excalidraw/common"; + +import type { NestedKeyOf } from "@excalidraw/common/utility-types"; + import { useAtomValue, editorJotaiStore, atom } from "./editor-jotai"; import fallbackLangData from "./locales/en.json"; import percentages from "./locales/percentages.json"; -import { isDevEnv } from "./utils"; - -import type { NestedKeyOf } from "./utility-types"; - const COMPLETION_THRESHOLD = 85; export interface Language { diff --git a/packages/excalidraw/index.tsx b/packages/excalidraw/index.tsx index f9f25b5303..5ea7467546 100644 --- a/packages/excalidraw/index.tsx +++ b/packages/excalidraw/index.tsx @@ -1,16 +1,16 @@ import React, { useEffect } from "react"; +import { DEFAULT_UI_OPTIONS, isShallowEqual } from "@excalidraw/common"; + import App from "./components/App"; import { InitializeApp } from "./components/InitializeApp"; import Footer from "./components/footer/FooterCenter"; import LiveCollaborationTrigger from "./components/live-collaboration/LiveCollaborationTrigger"; import MainMenu from "./components/main-menu/MainMenu"; import WelcomeScreen from "./components/welcome-screen/WelcomeScreen"; -import { DEFAULT_UI_OPTIONS } from "./constants"; import { defaultLang } from "./i18n"; import { EditorJotaiProvider, editorJotaiStore } from "./editor-jotai"; import polyfill from "./polyfill"; -import { isShallowEqual } from "./utils"; import "./css/app.scss"; import "./css/styles.scss"; @@ -215,10 +215,12 @@ export { getSceneVersion, hashElementsVersion, hashString, - isInvisiblySmallElement, getNonDeletedElements, - getTextFromElements, -} from "./element"; +} from "@excalidraw/element"; + +export { getTextFromElements } from "@excalidraw/element/textElement"; +export { isInvisiblySmallElement } from "@excalidraw/element/sizeHelpers"; + export { defaultLang, useI18n, languages } from "./i18n"; export { restore, @@ -242,9 +244,9 @@ export { loadSceneOrLibraryFromBlob, loadLibraryFromBlob, } from "./data/blob"; -export { getFreeDrawSvgPath } from "./renderer/renderElement"; +export { getFreeDrawSvgPath } from "@excalidraw/element/renderElement"; export { mergeLibraryItems, getLibraryItemsHash } from "./data/library"; -export { isLinearElement } from "./element/typeChecks"; +export { isLinearElement } from "@excalidraw/element/typeChecks"; export { FONT_FAMILY, @@ -253,13 +255,14 @@ export { ROUNDNESS, DEFAULT_LASER_COLOR, UserIdleState, -} from "./constants"; + normalizeLink, +} from "@excalidraw/common"; export { mutateElement, newElementWith, bumpVersion, -} from "./element/mutateElement"; +} from "@excalidraw/element/mutateElement"; export { CaptureUpdateAction } from "./store"; @@ -268,7 +271,7 @@ export { parseLibraryTokensFromUrl, useHandleLibrary } from "./data/library"; export { sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, -} from "./utils"; +} from "@excalidraw/common"; export { Sidebar } from "./components/Sidebar/Sidebar"; export { Button } from "./components/Button"; @@ -283,10 +286,12 @@ export { DefaultSidebar } from "./components/DefaultSidebar"; export { TTDDialog } from "./components/TTDDialog/TTDDialog"; export { TTDDialogTrigger } from "./components/TTDDialog/TTDDialogTrigger"; -export { normalizeLink } from "./data/url"; export { zoomToFitBounds } from "./actions/actionCanvas"; export { convertToExcalidrawElements } from "./data/transform"; -export { getCommonBounds, getVisibleSceneBounds } from "./element/bounds"; +export { + getCommonBounds, + getVisibleSceneBounds, +} from "@excalidraw/element/bounds"; export { elementsOverlappingBBox, @@ -296,6 +301,6 @@ export { export { DiagramToCodePlugin } from "./components/DiagramToCodePlugin/DiagramToCodePlugin"; export { getDataURL } from "./data/blob"; -export { isElementLink } from "./element/elementLink"; +export { isElementLink } from "@excalidraw/element/elementLink"; -export { setCustomTextMetricsProvider } from "./element/textMeasurements"; +export { setCustomTextMetricsProvider } from "@excalidraw/element/textMeasurements"; diff --git a/packages/excalidraw/laser-trails.ts b/packages/excalidraw/laser-trails.ts index 06e6b573a9..7956ae5d29 100644 --- a/packages/excalidraw/laser-trails.ts +++ b/packages/excalidraw/laser-trails.ts @@ -1,9 +1,9 @@ +import { DEFAULT_LASER_COLOR, easeOut } from "@excalidraw/common"; + import type { LaserPointerOptions } from "@excalidraw/laser-pointer"; import { AnimatedTrail } from "./animated-trail"; import { getClientColor } from "./clients"; -import { DEFAULT_LASER_COLOR } from "./constants"; -import { easeOut } from "./utils"; import type { Trail } from "./animated-trail"; import type { AnimationFrameHandler } from "./animation-frame-handler"; diff --git a/packages/excalidraw/package.json b/packages/excalidraw/package.json index a545ed7f78..9bf1ee223b 100644 --- a/packages/excalidraw/package.json +++ b/packages/excalidraw/package.json @@ -69,8 +69,6 @@ "canvas-roundrect-polyfill": "0.0.1", "clsx": "1.1.1", "cross-env": "7.0.3", - "es6-promise-pool": "2.5.0", - "fractional-indexing": "3.2.0", "fuzzy": "0.1.3", "image-blob-reduce": "3.0.1", "jotai": "2.11.0", @@ -78,14 +76,11 @@ "lodash.throttle": "4.1.1", "lodash.debounce": "4.0.8", "nanoid": "3.3.3", - "open-color": "1.9.1", "pako": "2.0.3", - "perfect-freehand": "1.2.0", "pica": "7.1.1", "png-chunk-text": "1.0.0", "png-chunks-encode": "1.0.0", "png-chunks-extract": "1.0.0", - "points-on-curve": "1.0.1", "pwacompat": "2.0.17", "roughjs": "4.6.4", "sass": "1.51.0", diff --git a/packages/excalidraw/reactUtils.ts b/packages/excalidraw/reactUtils.ts index 5bc4663951..a779fcfccf 100644 --- a/packages/excalidraw/reactUtils.ts +++ b/packages/excalidraw/reactUtils.ts @@ -5,7 +5,7 @@ import { version as ReactVersion } from "react"; import { unstable_batchedUpdates } from "react-dom"; -import { throttleRAF } from "./utils"; +import { throttleRAF } from "@excalidraw/common"; export const withBatchedUpdates = < TFunction extends ((event: any) => void) | (() => void), diff --git a/packages/excalidraw/renderer/helpers.ts b/packages/excalidraw/renderer/helpers.ts index 05097f95bd..765ef42944 100644 --- a/packages/excalidraw/renderer/helpers.ts +++ b/packages/excalidraw/renderer/helpers.ts @@ -1,4 +1,4 @@ -import { THEME, THEME_FILTER } from "../constants"; +import { THEME, THEME_FILTER } from "@excalidraw/common"; import type { StaticCanvasRenderConfig } from "../scene/types"; import type { StaticCanvasAppState, AppState } from "../types"; diff --git a/packages/excalidraw/renderer/interactiveScene.ts b/packages/excalidraw/renderer/interactiveScene.ts index b0971f9f21..3000c206c3 100644 --- a/packages/excalidraw/renderer/interactiveScene.ts +++ b/packages/excalidraw/renderer/interactiveScene.ts @@ -1,72 +1,66 @@ +import oc from "open-color"; import { pointFrom, type GlobalPoint, type LocalPoint, type Radians, } from "@excalidraw/math"; -import oc from "open-color"; -import { getClientColor, renderRemoteCursors } from "../clients"; import { DEFAULT_TRANSFORM_HANDLE_SPACING, FRAME_STYLE, THEME, -} from "../constants"; -import { - getElementAbsoluteCoords, - getTransformHandlesFromCoords, - getTransformHandles, - getCommonBounds, -} from "../element"; + arrayToMap, + invariant, + throttleRAF, +} from "@excalidraw/common"; + import { BINDING_HIGHLIGHT_OFFSET, BINDING_HIGHLIGHT_THICKNESS, maxBindingGap, -} from "../element/binding"; -import { LinearElementEditor } from "../element/linearElementEditor"; +} from "@excalidraw/element/binding"; +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { getOmitSidesForDevice, + getTransformHandles, + getTransformHandlesFromCoords, shouldShowBoundingBox, -} from "../element/transformHandles"; +} from "@excalidraw/element/transformHandles"; import { isElbowArrow, isFrameLikeElement, isImageElement, isLinearElement, isTextElement, -} from "../element/typeChecks"; +} from "@excalidraw/element/typeChecks"; + +import { getCornerRadius } from "@excalidraw/element/shapes"; + +import { renderSelectionElement } from "@excalidraw/element/renderElement"; + import { isSelectedViaGroup, getSelectedGroupIds, getElementsInGroup, selectGroupsFromGivenElements, -} from "../groups"; -import { renderSelectionElement } from "../renderer/renderElement"; -import { renderSnaps } from "../renderer/renderSnaps"; -import { roundRect } from "../renderer/roundRect"; -import { - getScrollBars, - SCROLLBAR_COLOR, - SCROLLBAR_WIDTH, -} from "../scene/scrollbars"; -import { getCornerRadius } from "../shapes"; -import { type InteractiveCanvasAppState } from "../types"; -import { arrayToMap, invariant, throttleRAF } from "../utils"; +} from "@excalidraw/element/groups"; import { - bootstrapCanvas, - fillCircle, - getNormalizedCanvasDimensions, -} from "./helpers"; + getCommonBounds, + getElementAbsoluteCoords, +} from "@excalidraw/element/bounds"; import type { SuggestedBinding, SuggestedPointBinding, -} from "../element/binding"; +} from "@excalidraw/element/binding"; + import type { TransformHandles, TransformHandleType, -} from "../element/transformHandles"; +} from "@excalidraw/element/transformHandles"; + import type { ElementsMap, ExcalidrawBindableElement, @@ -77,7 +71,25 @@ import type { ExcalidrawTextElement, GroupId, NonDeleted, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import { renderSnaps } from "../renderer/renderSnaps"; +import { roundRect } from "../renderer/roundRect"; +import { + getScrollBars, + SCROLLBAR_COLOR, + SCROLLBAR_WIDTH, +} from "../scene/scrollbars"; +import { type InteractiveCanvasAppState } from "../types"; + +import { getClientColor, renderRemoteCursors } from "../clients"; + +import { + bootstrapCanvas, + fillCircle, + getNormalizedCanvasDimensions, +} from "./helpers"; + import type { InteractiveCanvasRenderConfig, InteractiveSceneRenderConfig, diff --git a/packages/excalidraw/renderer/renderNewElementScene.ts b/packages/excalidraw/renderer/renderNewElementScene.ts index f80408366f..bbc14654a8 100644 --- a/packages/excalidraw/renderer/renderNewElementScene.ts +++ b/packages/excalidraw/renderer/renderNewElementScene.ts @@ -1,7 +1,8 @@ -import { throttleRAF } from "../utils"; +import { throttleRAF } from "@excalidraw/common"; + +import { renderElement } from "@excalidraw/element/renderElement"; import { bootstrapCanvas, getNormalizedCanvasDimensions } from "./helpers"; -import { renderElement } from "./renderElement"; import type { NewElementSceneRenderConfig } from "../scene/types"; diff --git a/packages/excalidraw/renderer/renderSnaps.ts b/packages/excalidraw/renderer/renderSnaps.ts index 8c26675ac8..dd131f7792 100644 --- a/packages/excalidraw/renderer/renderSnaps.ts +++ b/packages/excalidraw/renderer/renderSnaps.ts @@ -1,6 +1,6 @@ import { pointFrom, type GlobalPoint, type LocalPoint } from "@excalidraw/math"; -import { THEME } from "../constants"; +import { THEME } from "@excalidraw/common"; import type { PointSnapLine, PointerSnapLine } from "../snapping"; import type { InteractiveCanvasAppState } from "../types"; diff --git a/packages/excalidraw/renderer/staticScene.ts b/packages/excalidraw/renderer/staticScene.ts index 62aeed5b9d..16743ff91d 100644 --- a/packages/excalidraw/renderer/staticScene.ts +++ b/packages/excalidraw/renderer/staticScene.ts @@ -1,33 +1,36 @@ -import { - EXTERNAL_LINK_IMG, - ELEMENT_LINK_IMG, - getLinkHandleFromCoords, -} from "../components/hyperlink/helpers"; -import { FRAME_STYLE } from "../constants"; -import { getElementAbsoluteCoords } from "../element"; -import { isElementLink } from "../element/elementLink"; -import { createPlaceholderEmbeddableLabel } from "../element/embeddable"; -import { getBoundTextElement } from "../element/textElement"; +import { FRAME_STYLE, throttleRAF } from "@excalidraw/common"; +import { isElementLink } from "@excalidraw/element/elementLink"; +import { createPlaceholderEmbeddableLabel } from "@excalidraw/element/embeddable"; +import { getBoundTextElement } from "@excalidraw/element/textElement"; import { isEmbeddableElement, isIframeLikeElement, isTextElement, -} from "../element/typeChecks"; +} from "@excalidraw/element/typeChecks"; import { elementOverlapsWithFrame, getTargetFrame, shouldApplyFrameClip, -} from "../frame"; -import { renderElement } from "../renderer/renderElement"; -import { throttleRAF } from "../utils"; +} from "@excalidraw/element/frame"; -import { bootstrapCanvas, getNormalizedCanvasDimensions } from "./helpers"; +import { renderElement } from "@excalidraw/element/renderElement"; + +import { getElementAbsoluteCoords } from "@excalidraw/element/bounds"; import type { ElementsMap, ExcalidrawFrameLikeElement, NonDeletedExcalidrawElement, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import { + EXTERNAL_LINK_IMG, + ELEMENT_LINK_IMG, + getLinkHandleFromCoords, +} from "../components/hyperlink/helpers"; + +import { bootstrapCanvas, getNormalizedCanvasDimensions } from "./helpers"; + import type { StaticCanvasRenderConfig, StaticSceneRenderConfig, diff --git a/packages/excalidraw/renderer/staticSvgScene.ts b/packages/excalidraw/renderer/staticSvgScene.ts index 23a6890df5..0d3f5bad99 100644 --- a/packages/excalidraw/renderer/staticSvgScene.ts +++ b/packages/excalidraw/renderer/staticSvgScene.ts @@ -3,39 +3,50 @@ import { MAX_DECIMALS_FOR_SVG_EXPORT, MIME_TYPES, SVG_NS, -} from "../constants"; -import { normalizeLink, toValidURL } from "../data/url"; -import { getElementAbsoluteCoords, hashString } from "../element"; -import { getUncroppedWidthAndHeight } from "../element/cropElement"; + getFontFamilyString, + isRTL, + isTestEnv, + getVerticalOffset, +} from "@excalidraw/common"; +import { normalizeLink, toValidURL } from "@excalidraw/common"; +import { hashString } from "@excalidraw/element"; +import { getUncroppedWidthAndHeight } from "@excalidraw/element/cropElement"; import { createPlaceholderEmbeddableLabel, getEmbedLink, -} from "../element/embeddable"; -import { LinearElementEditor } from "../element/linearElementEditor"; +} from "@excalidraw/element/embeddable"; +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { getBoundTextElement, getContainerElement, -} from "../element/textElement"; -import { getLineHeightInPx } from "../element/textMeasurements"; +} from "@excalidraw/element/textElement"; +import { getLineHeightInPx } from "@excalidraw/element/textMeasurements"; import { isArrowElement, isIframeLikeElement, isInitializedImageElement, isTextElement, -} from "../element/typeChecks"; -import { getVerticalOffset } from "../fonts"; -import { getContainingFrame } from "../frame"; -import { ShapeCache } from "../scene/ShapeCache"; -import { getCornerRadius, isPathALoop } from "../shapes"; -import { getFontFamilyString, isRTL, isTestEnv } from "../utils"; +} from "@excalidraw/element/typeChecks"; -import { getFreeDrawSvgPath, IMAGE_INVERT_FILTER } from "./renderElement"; +import { getContainingFrame } from "@excalidraw/element/frame"; + +import { getCornerRadius, isPathALoop } from "@excalidraw/element/shapes"; + +import { ShapeCache } from "@excalidraw/element/ShapeCache"; + +import { + getFreeDrawSvgPath, + IMAGE_INVERT_FILTER, +} from "@excalidraw/element/renderElement"; + +import { getElementAbsoluteCoords } from "@excalidraw/element/bounds"; import type { ExcalidrawElement, ExcalidrawTextElementWithContainer, NonDeletedExcalidrawElement, -} from "../element/types"; +} from "@excalidraw/element/types"; + import type { RenderableElementsMap, SVGRenderConfig } from "../scene/types"; import type { AppState, BinaryFiles } from "../types"; import type { Drawable } from "roughjs/bin/core"; diff --git a/packages/excalidraw/scene/Renderer.ts b/packages/excalidraw/scene/Renderer.ts index 19a6c0b100..e22c997edf 100644 --- a/packages/excalidraw/scene/Renderer.ts +++ b/packages/excalidraw/scene/Renderer.ts @@ -1,16 +1,20 @@ -import { isElementInViewport } from "../element/sizeHelpers"; -import { isImageElement } from "../element/typeChecks"; -import { renderInteractiveSceneThrottled } from "../renderer/interactiveScene"; -import { renderStaticSceneThrottled } from "../renderer/staticScene"; -import { memoize, toBrandedType } from "../utils"; +import { isElementInViewport } from "@excalidraw/element/sizeHelpers"; +import { isImageElement } from "@excalidraw/element/typeChecks"; + +import { memoize, toBrandedType } from "@excalidraw/common"; -import type Scene from "./Scene"; -import type { RenderableElementsMap } from "./types"; import type { ExcalidrawElement, NonDeletedElementsMap, NonDeletedExcalidrawElement, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import { renderInteractiveSceneThrottled } from "../renderer/interactiveScene"; +import { renderStaticSceneThrottled } from "../renderer/staticScene"; + +import type Scene from "./Scene"; +import type { RenderableElementsMap } from "./types"; + import type { AppState } from "../types"; export class Renderer { diff --git a/packages/excalidraw/scene/Scene.ts b/packages/excalidraw/scene/Scene.ts index f990e45af9..dc66837fba 100644 --- a/packages/excalidraw/scene/Scene.ts +++ b/packages/excalidraw/scene/Scene.ts @@ -1,20 +1,25 @@ import throttle from "lodash.throttle"; -import { isNonDeletedElement } from "../element"; -import { isFrameLikeElement } from "../element/typeChecks"; +import { + randomInteger, + arrayToMap, + toBrandedType, + isDevEnv, + isTestEnv, +} from "@excalidraw/common"; +import { isNonDeletedElement } from "@excalidraw/element"; +import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; +import { getElementsInGroup } from "@excalidraw/element/groups"; + import { syncInvalidIndices, syncMovedIndices, validateFractionalIndices, -} from "../fractionalIndex"; -import { getElementsInGroup } from "../groups"; -import { randomInteger } from "../random"; -import { arrayToMap, isDevEnv, isTestEnv } from "../utils"; -import { toBrandedType } from "../utils"; +} from "@excalidraw/element/fractionalIndex"; -import { getSelectedElements } from "./selection"; +import { getSelectedElements } from "@excalidraw/element/selection"; -import type { LinearElementEditor } from "../element/linearElementEditor"; +import type { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import type { ExcalidrawElement, NonDeletedExcalidrawElement, @@ -25,9 +30,11 @@ import type { NonDeletedSceneElementsMap, OrderedExcalidrawElement, Ordered, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import type { Assert, SameType } from "@excalidraw/common/utility-types"; + import type { AppState } from "../types"; -import type { Assert, SameType } from "../utility-types"; type ElementIdKey = InstanceType["elementId"]; type ElementKey = ExcalidrawElement | ElementIdKey; diff --git a/packages/excalidraw/scene/export.ts b/packages/excalidraw/scene/export.ts index 8ca35de2c1..2299923542 100644 --- a/packages/excalidraw/scene/export.ts +++ b/packages/excalidraw/scene/export.ts @@ -1,6 +1,5 @@ import rough from "roughjs/bin/rough"; -import { getDefaultAppState } from "../appState"; import { DEFAULT_EXPORT_PADDING, FRAME_STYLE, @@ -10,39 +9,60 @@ import { THEME_FILTER, MIME_TYPES, EXPORT_DATA_TYPES, -} from "../constants"; -import { base64ToString, decode, encode, stringToBase64 } from "../data/encode"; -import { serializeAsJSON } from "../data/json"; -import { newTextElement } from "../element"; -import { getCommonBounds, getElementAbsoluteCoords } from "../element/bounds"; + arrayToMap, + distance, + getFontString, + toBrandedType, +} from "@excalidraw/common"; + +import { + getCommonBounds, + getElementAbsoluteCoords, +} from "@excalidraw/element/bounds"; + import { getInitializedImageElements, updateImageCache, -} from "../element/image"; -import { newElementWith } from "../element/mutateElement"; -import { isFrameLikeElement } from "../element/typeChecks"; -import { Fonts } from "../fonts"; -import { syncInvalidIndices } from "../fractionalIndex"; +} from "@excalidraw/element/image"; + +import { newElementWith } from "@excalidraw/element/mutateElement"; + +import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; + import { getElementsOverlappingFrame, getFrameLikeElements, getFrameLikeTitle, getRootElements, -} from "../frame"; -import { renderStaticScene } from "../renderer/staticScene"; -import { renderSceneToSvg } from "../renderer/staticSvgScene"; -import { type Mutable } from "../utility-types"; -import { arrayToMap, distance, getFontString, toBrandedType } from "../utils"; +} from "@excalidraw/element/frame"; + +import { syncInvalidIndices } from "@excalidraw/element/fractionalIndex"; + +import { type Mutable } from "@excalidraw/common/utility-types"; + +import { newTextElement } from "@excalidraw/element/newElement"; + +import type { Bounds } from "@excalidraw/element/bounds"; -import type { RenderableElementsMap } from "./types"; -import type { Bounds } from "../element/bounds"; import type { ExcalidrawElement, ExcalidrawFrameLikeElement, ExcalidrawTextElement, NonDeletedExcalidrawElement, NonDeletedSceneElementsMap, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import { getDefaultAppState } from "../appState"; +import { base64ToString, decode, encode, stringToBase64 } from "../data/encode"; +import { serializeAsJSON } from "../data/json"; + +import { Fonts } from "../fonts"; + +import { renderStaticScene } from "../renderer/staticScene"; +import { renderSceneToSvg } from "../renderer/staticSvgScene"; + +import type { RenderableElementsMap } from "./types"; + import type { AppState, BinaryFiles } from "../types"; const truncateText = (element: ExcalidrawTextElement, maxWidth: number) => { diff --git a/packages/excalidraw/scene/index.ts b/packages/excalidraw/scene/index.ts index 1c0b795f1d..6f39a7fe24 100644 --- a/packages/excalidraw/scene/index.ts +++ b/packages/excalidraw/scene/index.ts @@ -4,7 +4,7 @@ export { getCommonAttributeOfSelectedElements, getSelectedElements, getTargetElements, -} from "./selection"; +} from "@excalidraw/element/selection"; export { calculateScrollCenter } from "./scroll"; export { hasBackground, @@ -12,7 +12,7 @@ export { hasStrokeStyle, canHaveArrowheads, canChangeRoundness, -} from "./comparisons"; +} from "@excalidraw/element/comparisons"; export { getNormalizedZoom, getNormalizedGridSize, diff --git a/packages/excalidraw/scene/normalize.ts b/packages/excalidraw/scene/normalize.ts index 0c73c5a8a0..605ae2fa69 100644 --- a/packages/excalidraw/scene/normalize.ts +++ b/packages/excalidraw/scene/normalize.ts @@ -1,6 +1,6 @@ -import { clamp, round } from "@excalidraw/math"; +import { MAX_ZOOM, MIN_ZOOM } from "@excalidraw/common"; -import { MAX_ZOOM, MIN_ZOOM } from "../constants"; +import { clamp, round } from "@excalidraw/math"; import type { NormalizedZoomValue } from "../types"; diff --git a/packages/excalidraw/scene/scroll.ts b/packages/excalidraw/scene/scroll.ts index 989564eb0e..a99ad075f8 100644 --- a/packages/excalidraw/scene/scroll.ts +++ b/packages/excalidraw/scene/scroll.ts @@ -1,14 +1,15 @@ -import { - getCommonBounds, - getClosestElementBounds, - getVisibleElements, -} from "../element"; +import { getVisibleElements } from "@excalidraw/element"; import { sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, -} from "../utils"; +} from "@excalidraw/common"; + +import { getClosestElementBounds } from "@excalidraw/element/bounds"; + +import { getCommonBounds } from "@excalidraw/element/bounds"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; -import type { ExcalidrawElement } from "../element/types"; import type { AppState, Offsets, PointerCoords, Zoom } from "../types"; const isOutsideViewPort = (appState: AppState, cords: Array) => { diff --git a/packages/excalidraw/scene/scrollbars.ts b/packages/excalidraw/scene/scrollbars.ts index b44d79f2b8..4fa4349f2f 100644 --- a/packages/excalidraw/scene/scrollbars.ts +++ b/packages/excalidraw/scene/scrollbars.ts @@ -1,8 +1,11 @@ -import { getCommonBounds } from "../element"; -import { getLanguage } from "../i18n"; -import { getGlobalCSSVariable } from "../utils"; +import { getGlobalCSSVariable } from "@excalidraw/common"; + +import { getCommonBounds } from "@excalidraw/element/bounds"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + +import { getLanguage } from "../i18n"; -import type { ExcalidrawElement } from "../element/types"; import type { InteractiveCanvasAppState } from "../types"; import type { ScrollBars } from "./types"; diff --git a/packages/excalidraw/scene/types.ts b/packages/excalidraw/scene/types.ts index 3c198d1534..08b05a57de 100644 --- a/packages/excalidraw/scene/types.ts +++ b/packages/excalidraw/scene/types.ts @@ -1,10 +1,13 @@ -import type { UserIdleState } from "../constants"; +import type { UserIdleState } from "@excalidraw/common"; import type { ExcalidrawElement, NonDeletedElementsMap, NonDeletedExcalidrawElement, NonDeletedSceneElementsMap, -} from "../element/types"; +} from "@excalidraw/element/types"; + +import type { MakeBrand } from "@excalidraw/common/utility-types"; + import type { AppClassProperties, AppState, @@ -16,7 +19,6 @@ import type { Device, PendingExcalidrawElements, } from "../types"; -import type { MakeBrand } from "../utility-types"; import type { RoughCanvas } from "roughjs/bin/canvas"; import type { Drawable } from "roughjs/bin/core"; diff --git a/packages/excalidraw/snapping.ts b/packages/excalidraw/snapping.ts index 7c85f4112d..6ea23bd870 100644 --- a/packages/excalidraw/snapping.ts +++ b/packages/excalidraw/snapping.ts @@ -7,34 +7,38 @@ import { type GlobalPoint, } from "@excalidraw/math"; -import type { InclusiveRange } from "@excalidraw/math"; - -import { TOOL_TYPE } from "./constants"; +import { TOOL_TYPE, KEYS } from "@excalidraw/common"; import { getCommonBounds, getDraggedElementsBounds, getElementAbsoluteCoords, -} from "./element/bounds"; -import { isBoundToContainer, isFrameLikeElement } from "./element/typeChecks"; -import { getMaximumGroups } from "./groups"; -import { KEYS } from "./keys"; +} from "@excalidraw/element/bounds"; +import { + isBoundToContainer, + isFrameLikeElement, +} from "@excalidraw/element/typeChecks"; + +import { getMaximumGroups } from "@excalidraw/element/groups"; + import { getSelectedElements, getVisibleAndNonSelectedElements, -} from "./scene/selection"; +} from "@excalidraw/element/selection"; -import type { Bounds } from "./element/bounds"; -import type { MaybeTransformHandleType } from "./element/transformHandles"; +import type { InclusiveRange } from "@excalidraw/math"; + +import type { Bounds } from "@excalidraw/element/bounds"; +import type { MaybeTransformHandleType } from "@excalidraw/element/transformHandles"; import type { ElementsMap, ExcalidrawElement, NonDeletedExcalidrawElement, -} from "./element/types"; +} from "@excalidraw/element/types"; + import type { AppClassProperties, AppState, KeyboardModifiersObject, - NullableGridSize, } from "./types"; const SNAP_DISTANCE = 8; @@ -1411,18 +1415,3 @@ export const isActiveToolNonLinearSnappable = ( activeToolType === TOOL_TYPE.text ); }; - -// TODO: Rounding this point causes some shake when free drawing -export const getGridPoint = ( - x: number, - y: number, - gridSize: NullableGridSize, -): [number, number] => { - if (gridSize) { - return [ - Math.round(x / gridSize) * gridSize, - Math.round(y / gridSize) * gridSize, - ]; - } - return [x, y]; -}; diff --git a/packages/excalidraw/store.ts b/packages/excalidraw/store.ts index 83d670d43a..7a5590e54d 100644 --- a/packages/excalidraw/store.ts +++ b/packages/excalidraw/store.ts @@ -1,14 +1,19 @@ +import { isDevEnv, isShallowEqual, isTestEnv } from "@excalidraw/common"; + +import { deepCopyElement } from "@excalidraw/element/duplicate"; + +import { newElementWith } from "@excalidraw/element/mutateElement"; + +import type { OrderedExcalidrawElement } from "@excalidraw/element/types"; + +import type { ValueOf } from "@excalidraw/common/utility-types"; + import { getDefaultAppState } from "./appState"; import { AppStateChange, ElementsChange } from "./change"; -import { newElementWith } from "./element/mutateElement"; + import { Emitter } from "./emitter"; -import { isDevEnv, isShallowEqual, isTestEnv } from "./utils"; -import { deepCopyElement } from "./element/duplicate"; - -import type { OrderedExcalidrawElement } from "./element/types"; import type { AppState, ObservedAppState } from "./types"; -import type { ValueOf } from "./utility-types"; // hidden non-enumerable property for runtime checks const hiddenObservedAppStateProp = "__observedAppState"; diff --git a/packages/excalidraw/subset/subset-main.ts b/packages/excalidraw/subset/subset-main.ts index 5f39af99c0..d5e4ba7be8 100644 --- a/packages/excalidraw/subset/subset-main.ts +++ b/packages/excalidraw/subset/subset-main.ts @@ -1,5 +1,6 @@ +import { isServerEnv, promiseTry } from "@excalidraw/common"; + import { WorkerInTheMainChunkError, WorkerUrlNotDefinedError } from "../errors"; -import { isServerEnv, promiseTry } from "../utils"; import { WorkerPool } from "../workers"; import type { Commands } from "./subset-shared.chunk"; diff --git a/packages/excalidraw/tests/App.test.tsx b/packages/excalidraw/tests/App.test.tsx index 8b86477f9c..7a1790ceef 100644 --- a/packages/excalidraw/tests/App.test.tsx +++ b/packages/excalidraw/tests/App.test.tsx @@ -1,8 +1,9 @@ import React from "react"; import { vi } from "vitest"; +import { reseed } from "@excalidraw/common"; + import { Excalidraw } from "../index"; -import { reseed } from "../random"; import * as StaticScene from "../renderer/staticScene"; import { render, queryByTestId, unmountComponent } from "../tests/test-utils"; diff --git a/packages/excalidraw/tests/actionStyles.test.tsx b/packages/excalidraw/tests/actionStyles.test.tsx index 2e60000ad3..e81e9e4e40 100644 --- a/packages/excalidraw/tests/actionStyles.test.tsx +++ b/packages/excalidraw/tests/actionStyles.test.tsx @@ -1,8 +1,9 @@ import React from "react"; +import { CODES } from "@excalidraw/common"; + import { copiedStyles } from "../actions/actionStyles"; import { Excalidraw } from "../index"; -import { CODES } from "../keys"; import { API } from "../tests/helpers/api"; import { Keyboard, Pointer, UI } from "../tests/helpers/ui"; import { diff --git a/packages/excalidraw/tests/appState.test.tsx b/packages/excalidraw/tests/appState.test.tsx index e97c5f3be8..abb7ac1762 100644 --- a/packages/excalidraw/tests/appState.test.tsx +++ b/packages/excalidraw/tests/appState.test.tsx @@ -1,15 +1,16 @@ import React from "react"; +import { EXPORT_DATA_TYPES, MIME_TYPES } from "@excalidraw/common"; + +import type { ExcalidrawTextElement } from "@excalidraw/element/types"; + import { getDefaultAppState } from "../appState"; -import { EXPORT_DATA_TYPES, MIME_TYPES } from "../constants"; import { Excalidraw } from "../index"; import { API } from "./helpers/api"; import { Pointer, UI } from "./helpers/ui"; import { fireEvent, queryByTestId, render, waitFor } from "./test-utils"; -import type { ExcalidrawTextElement } from "../element/types"; - const { h } = window; describe("appState", () => { diff --git a/packages/excalidraw/tests/clipboard.test.tsx b/packages/excalidraw/tests/clipboard.test.tsx index c7e17f49d0..0759afd94c 100644 --- a/packages/excalidraw/tests/clipboard.test.tsx +++ b/packages/excalidraw/tests/clipboard.test.tsx @@ -1,13 +1,15 @@ import React from "react"; import { vi } from "vitest"; +import { getLineHeightInPx } from "@excalidraw/element/textMeasurements"; + +import { KEYS, arrayToMap, getLineHeight } from "@excalidraw/common"; + +import { getElementBounds } from "@excalidraw/element/bounds"; + import { createPasteEvent, serializeAsClipboardJSON } from "../clipboard"; -import { getElementBounds } from "../element"; -import { getLineHeightInPx } from "../element/textMeasurements"; -import { getLineHeight } from "../fonts"; + import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; -import { arrayToMap } from "../utils"; import { API } from "./helpers/api"; import { mockMermaidToExcalidraw } from "./helpers/mocks"; @@ -25,7 +27,7 @@ const { h } = window; const mouse = new Pointer("mouse"); -vi.mock("../keys.ts", async (importOriginal) => { +vi.mock("@excalidraw/common", async (importOriginal) => { const module: any = await importOriginal(); return { __esmodule: true, diff --git a/packages/excalidraw/tests/contextmenu.test.tsx b/packages/excalidraw/tests/contextmenu.test.tsx index 7de3495169..ef36e3d52a 100644 --- a/packages/excalidraw/tests/contextmenu.test.tsx +++ b/packages/excalidraw/tests/contextmenu.test.tsx @@ -1,12 +1,13 @@ import React from "react"; import { vi } from "vitest"; +import { KEYS, reseed } from "@excalidraw/common"; + +import { setDateTimeForTests } from "@excalidraw/common"; + import { copiedStyles } from "../actions/actionStyles"; import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; -import { reseed } from "../random"; import * as StaticScene from "../renderer/staticScene"; -import { setDateTimeForTests } from "../utils"; import { API } from "./helpers/api"; import { UI, Pointer, Keyboard } from "./helpers/ui"; diff --git a/packages/excalidraw/tests/cropElement.test.tsx b/packages/excalidraw/tests/cropElement.test.tsx index ddc93e3fee..8011483fa8 100644 --- a/packages/excalidraw/tests/cropElement.test.tsx +++ b/packages/excalidraw/tests/cropElement.test.tsx @@ -1,17 +1,22 @@ import React from "react"; import { vi } from "vitest"; +import { KEYS, cloneJSON } from "@excalidraw/common"; + +import { duplicateElement } from "@excalidraw/element/duplicate"; + +import type { + ExcalidrawImageElement, + ImageCrop, +} from "@excalidraw/element/types"; + import { Excalidraw, exportToCanvas, exportToSvg } from ".."; import { actionFlipHorizontal, actionFlipVertical } from "../actions"; -import { duplicateElement } from "../element"; -import { KEYS } from "../keys"; -import { cloneJSON } from "../utils"; import { API } from "./helpers/api"; import { Keyboard, Pointer, UI } from "./helpers/ui"; import { act, GlobalTestState, render, unmountComponent } from "./test-utils"; -import type { ExcalidrawImageElement, ImageCrop } from "../element/types"; import type { NormalizedZoomValue } from "../types"; const { h } = window; diff --git a/packages/excalidraw/tests/data/reconcile.test.ts b/packages/excalidraw/tests/data/reconcile.test.ts index 35a33956a2..1c0bf13db5 100644 --- a/packages/excalidraw/tests/data/reconcile.test.ts +++ b/packages/excalidraw/tests/data/reconcile.test.ts @@ -1,13 +1,16 @@ -import { reconcileElements } from "../../data/reconcile"; -import { syncInvalidIndices } from "../../fractionalIndex"; -import { randomInteger } from "../../random"; -import { cloneJSON } from "../../utils"; +import { syncInvalidIndices } from "@excalidraw/element/fractionalIndex"; + +import { randomInteger, cloneJSON } from "@excalidraw/common"; -import type { RemoteExcalidrawElement } from "../../data/reconcile"; import type { ExcalidrawElement, OrderedExcalidrawElement, -} from "../../element/types"; +} from "@excalidraw/element/types"; + +import { reconcileElements } from "../../data/reconcile"; + +import type { RemoteExcalidrawElement } from "../../data/reconcile"; + import type { AppState } from "../../types"; type Id = string; diff --git a/packages/excalidraw/tests/data/restore.test.ts b/packages/excalidraw/tests/data/restore.test.ts index 5292843587..4b414bbf1a 100644 --- a/packages/excalidraw/tests/data/restore.test.ts +++ b/packages/excalidraw/tests/data/restore.test.ts @@ -1,21 +1,24 @@ import { pointFrom } from "@excalidraw/math"; import { vi } from "vitest"; -import { getDefaultAppState } from "../../appState"; -import { DEFAULT_SIDEBAR, FONT_FAMILY, ROUNDNESS } from "../../constants"; -import * as restore from "../../data/restore"; -import { newElementWith } from "../../element/mutateElement"; -import * as sizeHelpers from "../../element/sizeHelpers"; -import { API } from "../helpers/api"; +import { DEFAULT_SIDEBAR, FONT_FAMILY, ROUNDNESS } from "@excalidraw/common"; + +import { newElementWith } from "@excalidraw/element/mutateElement"; +import * as sizeHelpers from "@excalidraw/element/sizeHelpers"; -import type { ImportedDataState } from "../../data/types"; import type { ExcalidrawElement, ExcalidrawFreeDrawElement, ExcalidrawLinearElement, ExcalidrawTextElement, -} from "../../element/types"; -import type { NormalizedZoomValue } from "../../types"; +} from "@excalidraw/element/types"; +import type { NormalizedZoomValue } from "@excalidraw/excalidraw/types"; + +import { API } from "../helpers/api"; +import * as restore from "../../data/restore"; +import { getDefaultAppState } from "../../appState"; + +import type { ImportedDataState } from "../../data/types"; describe("restoreElements", () => { const mockSizeHelper = vi.spyOn(sizeHelpers, "isInvisiblySmallElement"); diff --git a/packages/excalidraw/tests/dragCreate.test.tsx b/packages/excalidraw/tests/dragCreate.test.tsx index ecdfbcb64d..c33da5e7ea 100644 --- a/packages/excalidraw/tests/dragCreate.test.tsx +++ b/packages/excalidraw/tests/dragCreate.test.tsx @@ -1,9 +1,11 @@ import React from "react"; import { vi } from "vitest"; +import { KEYS, reseed } from "@excalidraw/common"; + +import type { ExcalidrawLinearElement } from "@excalidraw/element/types"; + import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; -import { reseed } from "../random"; import * as InteractiveScene from "../renderer/interactiveScene"; import * as StaticScene from "../renderer/staticScene"; @@ -15,8 +17,6 @@ import { unmountComponent, } from "./test-utils"; -import type { ExcalidrawLinearElement } from "../element/types"; - unmountComponent(); const renderInteractiveScene = vi.spyOn( diff --git a/packages/excalidraw/tests/elementLocking.test.tsx b/packages/excalidraw/tests/elementLocking.test.tsx index a1ca146830..45e370ed8a 100644 --- a/packages/excalidraw/tests/elementLocking.test.tsx +++ b/packages/excalidraw/tests/elementLocking.test.tsx @@ -1,10 +1,13 @@ import React from "react"; +import { mutateElement } from "@excalidraw/element/mutateElement"; + +import { KEYS } from "@excalidraw/common"; + import { actionSelectAll } from "../actions"; -import { mutateElement } from "../element/mutateElement"; import { t } from "../i18n"; import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; + import { API } from "../tests/helpers/api"; import { Keyboard, Pointer, UI } from "../tests/helpers/ui"; import { render, unmountComponent } from "../tests/test-utils"; diff --git a/packages/excalidraw/tests/excalidraw.test.tsx b/packages/excalidraw/tests/excalidraw.test.tsx index 0e33f8167c..34135c618d 100644 --- a/packages/excalidraw/tests/excalidraw.test.tsx +++ b/packages/excalidraw/tests/excalidraw.test.tsx @@ -2,7 +2,8 @@ import { queryByText, queryByTestId } from "@testing-library/react"; import React from "react"; import { useMemo } from "react"; -import { THEME } from "../constants"; +import { THEME } from "@excalidraw/common"; + import { t } from "../i18n"; import { Excalidraw, Footer, MainMenu } from "../index"; diff --git a/packages/excalidraw/tests/export.test.tsx b/packages/excalidraw/tests/export.test.tsx index c103362715..a42e56b90c 100644 --- a/packages/excalidraw/tests/export.test.tsx +++ b/packages/excalidraw/tests/export.test.tsx @@ -1,7 +1,10 @@ import React from "react"; +import { SVG_NS } from "@excalidraw/common"; + +import type { FileId } from "@excalidraw/element/types"; + import { getDefaultAppState } from "../appState"; -import { SVG_NS } from "../constants"; import { getDataURL } from "../data/blob"; import { encodePngMetadata } from "../data/image"; import { serializeAsJSON } from "../data/json"; @@ -15,8 +18,6 @@ import { import { API } from "./helpers/api"; import { render, waitFor } from "./test-utils"; -import type { FileId } from "../element/types"; - const { h } = window; const testElements = [ diff --git a/packages/excalidraw/tests/fixtures/diagramFixture.ts b/packages/excalidraw/tests/fixtures/diagramFixture.ts index a4fdc15607..8512fed36a 100644 --- a/packages/excalidraw/tests/fixtures/diagramFixture.ts +++ b/packages/excalidraw/tests/fixtures/diagramFixture.ts @@ -1,4 +1,4 @@ -import { VERSIONS } from "../../constants"; +import { VERSIONS } from "@excalidraw/common"; import { diamondFixture, diff --git a/packages/excalidraw/tests/fixtures/elementFixture.ts b/packages/excalidraw/tests/fixtures/elementFixture.ts index a7d8c50807..35aabd55f4 100644 --- a/packages/excalidraw/tests/fixtures/elementFixture.ts +++ b/packages/excalidraw/tests/fixtures/elementFixture.ts @@ -1,8 +1,8 @@ +import { DEFAULT_FONT_FAMILY } from "@excalidraw/common"; + import type { Radians } from "@excalidraw/math"; -import { DEFAULT_FONT_FAMILY } from "../../constants"; - -import type { ExcalidrawElement } from "../../element/types"; +import type { ExcalidrawElement } from "@excalidraw/element/types"; const elementBase: Omit = { id: "vWrqOAfkind2qcm7LDAGZ", diff --git a/packages/excalidraw/tests/flip.test.tsx b/packages/excalidraw/tests/flip.test.tsx index 9d9f686114..22a6c67f86 100644 --- a/packages/excalidraw/tests/flip.test.tsx +++ b/packages/excalidraw/tests/flip.test.tsx @@ -1,18 +1,30 @@ -import { pointFrom, type Radians } from "@excalidraw/math"; import React from "react"; import { vi } from "vitest"; +import { ROUNDNESS, KEYS, arrayToMap, cloneJSON } from "@excalidraw/common"; + +import { pointFrom, type Radians } from "@excalidraw/math"; + +import { getBoundTextElementPosition } from "@excalidraw/element/textElement"; +import { getElementAbsoluteCoords } from "@excalidraw/element/bounds"; +import { newLinearElement } from "@excalidraw/element/newElement"; + import type { LocalPoint } from "@excalidraw/math"; +import type { + ExcalidrawElement, + ExcalidrawImageElement, + ExcalidrawLinearElement, + ExcalidrawTextElementWithContainer, + FileId, +} from "@excalidraw/element/types"; + import { actionFlipHorizontal, actionFlipVertical } from "../actions"; import { createPasteEvent } from "../clipboard"; -import { ROUNDNESS } from "../constants"; -import { getElementAbsoluteCoords } from "../element"; -import { newLinearElement } from "../element"; -import { getBoundTextElementPosition } from "../element/textElement"; import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; -import { arrayToMap, cloneJSON } from "../utils"; + +// Importing to spy on it and mock the implementation (mocking does not work with simple vi.mock for some reason) +import * as blobModule from "../data/blob"; import { API } from "./helpers/api"; import { UI, Pointer, Keyboard } from "./helpers/ui"; @@ -25,25 +37,17 @@ import { waitFor, } from "./test-utils"; -import type { - ExcalidrawElement, - ExcalidrawImageElement, - ExcalidrawLinearElement, - ExcalidrawTextElementWithContainer, - FileId, -} from "../element/types"; import type { NormalizedZoomValue } from "../types"; const { h } = window; const mouse = new Pointer("mouse"); -vi.mock("../data/blob", async (actual) => { - const orig: Object = await actual(); - return { - ...orig, - resizeImageFile: (imageFile: File) => imageFile, - generateIdFromFile: () => "fileId" as FileId, - }; +beforeEach(() => { + const generateIdSpy = vi.spyOn(blobModule, "generateIdFromFile"); + const resizeFileSpy = vi.spyOn(blobModule, "resizeImageFile"); + + generateIdSpy.mockImplementation(() => Promise.resolve("fileId" as FileId)); + resizeFileSpy.mockImplementation((file: File) => Promise.resolve(file)); }); beforeEach(async () => { diff --git a/packages/excalidraw/tests/helpers/api.ts b/packages/excalidraw/tests/helpers/api.ts index 2aa9ee9998..09aa308a5d 100644 --- a/packages/excalidraw/tests/helpers/api.ts +++ b/packages/excalidraw/tests/helpers/api.ts @@ -4,29 +4,26 @@ import util from "util"; import { pointFrom, type LocalPoint, type Radians } from "@excalidraw/math"; -import { getDefaultAppState } from "../../appState"; -import { createTestHook } from "../../components/App"; -import { DEFAULT_VERTICAL_ALIGN, ROUNDNESS } from "../../constants"; -import { getMimeType } from "../../data/blob"; -import { newElement, newTextElement, newLinearElement } from "../../element"; -import { mutateElement } from "../../element/mutateElement"; +import { DEFAULT_VERTICAL_ALIGN, ROUNDNESS, assertNever } from "@excalidraw/common"; + +import { mutateElement } from "@excalidraw/element/mutateElement"; import { newArrowElement, + newElement, newEmbeddableElement, newFrameElement, newFreeDrawElement, newIframeElement, newImageElement, + newLinearElement, newMagicFrameElement, -} from "../../element/newElement"; -import { isLinearElementType } from "../../element/typeChecks"; -import { selectGroupsForSelectedElements } from "../../groups"; -import { getSelectedElements } from "../../scene/selection"; -import { assertNever } from "../../utils"; -import { GlobalTestState, createEvent, fireEvent, act } from "../test-utils"; + newTextElement, +} from "@excalidraw/element/newElement"; + +import { isLinearElementType } from "@excalidraw/element/typeChecks"; +import { getSelectedElements } from "@excalidraw/element/selection"; +import { selectGroupsForSelectedElements } from "@excalidraw/element/groups"; -import type { Action } from "../../actions/types"; -import type App from "../../components/App"; import type { ExcalidrawElement, ExcalidrawGenericElement, @@ -41,9 +38,19 @@ import type { ExcalidrawElbowArrowElement, ExcalidrawArrowElement, FixedSegment, -} from "../../element/types"; +} from "@excalidraw/element/types"; + +import type { Mutable } from "@excalidraw/common/utility-types"; + +import { getMimeType } from "../../data/blob"; +import { createTestHook } from "../../components/App"; +import { getDefaultAppState } from "../../appState"; +import { GlobalTestState, createEvent, fireEvent, act } from "../test-utils"; + +import type { Action } from "../../actions/types"; +import type App from "../../components/App"; import type { AppState } from "../../types"; -import type { Mutable } from "../../utility-types"; + const readFile = util.promisify(fs.readFile); // so that window.h is available when App.tsx is not imported as well. diff --git a/packages/excalidraw/tests/helpers/ui.ts b/packages/excalidraw/tests/helpers/ui.ts index a72e3fa74a..c328ae105a 100644 --- a/packages/excalidraw/tests/helpers/ui.ts +++ b/packages/excalidraw/tests/helpers/ui.ts @@ -1,11 +1,11 @@ import { pointFrom, pointRotateRads } from "@excalidraw/math"; -import type { GlobalPoint, LocalPoint, Radians } from "@excalidraw/math"; - -import { createTestHook } from "../../components/App"; -import { getCommonBounds, getElementPointsCoords } from "../../element/bounds"; -import { cropElement } from "../../element/cropElement"; -import { mutateElement } from "../../element/mutateElement"; +import { + getCommonBounds, + getElementPointsCoords, +} from "@excalidraw/element/bounds"; +import { cropElement } from "@excalidraw/element/cropElement"; +import { mutateElement } from "@excalidraw/element/mutateElement"; import { getTransformHandles, getTransformHandlesFromCoords, @@ -13,21 +13,18 @@ import { OMIT_SIDES_FOR_MULTIPLE_ELEMENTS, type TransformHandle, type TransformHandleDirection, -} from "../../element/transformHandles"; +} from "@excalidraw/element/transformHandles"; import { isLinearElement, isFreeDrawElement, isTextElement, isFrameLikeElement, -} from "../../element/typeChecks"; -import { KEYS } from "../../keys"; -import { arrayToMap } from "../../utils"; -import { getTextEditor } from "../queries/dom"; -import { act, fireEvent, GlobalTestState, screen } from "../test-utils"; +} from "@excalidraw/element/typeChecks"; +import { KEYS, arrayToMap } from "@excalidraw/common"; -import { API } from "./api"; +import type { GlobalPoint, LocalPoint, Radians } from "@excalidraw/math"; -import type { TransformHandleType } from "../../element/transformHandles"; +import type { TransformHandleType } from "@excalidraw/element/transformHandles"; import type { ExcalidrawElement, ExcalidrawLinearElement, @@ -39,7 +36,14 @@ import type { ExcalidrawTextContainer, ExcalidrawTextElementWithContainer, ExcalidrawImageElement, -} from "../../element/types"; +} from "@excalidraw/element/types"; + +import { createTestHook } from "../../components/App"; +import { getTextEditor } from "../queries/dom"; +import { act, fireEvent, GlobalTestState, screen } from "../test-utils"; + +import { API } from "./api"; + import type { ToolType } from "../../types"; // so that window.h is available when App.tsx is not imported as well. diff --git a/packages/excalidraw/tests/history.test.tsx b/packages/excalidraw/tests/history.test.tsx index 6e7066b902..8dd65c7a5f 100644 --- a/packages/excalidraw/tests/history.test.tsx +++ b/packages/excalidraw/tests/history.test.tsx @@ -8,10 +8,35 @@ import { import { vi } from "vitest"; import { pointFrom } from "@excalidraw/math"; +import { newElementWith } from "@excalidraw/element/mutateElement"; + +import { + EXPORT_DATA_TYPES, + MIME_TYPES, + ORIG_ID, + KEYS, + arrayToMap, + COLOR_PALETTE, + DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX, + DEFAULT_ELEMENT_STROKE_COLOR_INDEX, +} from "@excalidraw/common"; + +import "@excalidraw/utils/test-utils"; + import type { LocalPoint, Radians } from "@excalidraw/math"; +import type { + ExcalidrawElbowArrowElement, + ExcalidrawFrameElement, + ExcalidrawGenericElement, + ExcalidrawLinearElement, + ExcalidrawTextElement, + FixedPointBinding, + FractionalIndex, + SceneElementsMap, +} from "@excalidraw/element/types"; + import "../global.d.ts"; -import "../../utils/test-utils"; import { actionSendBackward, @@ -23,17 +48,8 @@ import { actionToggleViewMode } from "../actions/actionToggleViewMode"; import { getDefaultAppState } from "../appState"; import { HistoryEntry } from "../history"; import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; import * as StaticScene from "../renderer/staticScene"; -import { EXPORT_DATA_TYPES, MIME_TYPES, ORIG_ID } from "../constants"; import { Snapshot, CaptureUpdateAction } from "../store"; -import { arrayToMap } from "../utils"; -import { - COLOR_PALETTE, - DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX, - DEFAULT_ELEMENT_STROKE_COLOR_INDEX, -} from "../colors"; -import { newElementWith } from "../element/mutateElement"; import { AppStateChange, ElementsChange } from "../change"; import { API } from "./helpers/api"; @@ -47,16 +63,6 @@ import { getCloneByOrigId, } from "./test-utils"; -import type { - ExcalidrawElbowArrowElement, - ExcalidrawFrameElement, - ExcalidrawGenericElement, - ExcalidrawLinearElement, - ExcalidrawTextElement, - FixedPointBinding, - FractionalIndex, - SceneElementsMap, -} from "../element/types"; import type { AppState } from "../types"; const { h } = window; diff --git a/packages/excalidraw/tests/library.test.tsx b/packages/excalidraw/tests/library.test.tsx index b084d835bb..d2b6c13c8f 100644 --- a/packages/excalidraw/tests/library.test.tsx +++ b/packages/excalidraw/tests/library.test.tsx @@ -2,18 +2,21 @@ import { act, queryByTestId } from "@testing-library/react"; import React from "react"; import { vi } from "vitest"; -import { MIME_TYPES, ORIG_ID } from "../constants"; +import { MIME_TYPES, ORIG_ID } from "@excalidraw/common"; + +import { getCommonBoundingBox } from "@excalidraw/element/bounds"; + +import type { ExcalidrawGenericElement } from "@excalidraw/element/types"; + import { parseLibraryJSON } from "../data/blob"; import { serializeLibraryAsJSON } from "../data/json"; import { distributeLibraryItemsOnSquareGrid } from "../data/library"; -import { getCommonBoundingBox } from "../element/bounds"; import { Excalidraw } from "../index"; import { API } from "./helpers/api"; import { UI } from "./helpers/ui"; import { fireEvent, getCloneByOrigId, render, waitFor } from "./test-utils"; -import type { ExcalidrawGenericElement } from "../element/types"; import type { LibraryItem, LibraryItems } from "../types"; const { h } = window; diff --git a/packages/excalidraw/tests/linearElementEditor.test.tsx b/packages/excalidraw/tests/linearElementEditor.test.tsx index 162dbb3f0c..741799d3be 100644 --- a/packages/excalidraw/tests/linearElementEditor.test.tsx +++ b/packages/excalidraw/tests/linearElementEditor.test.tsx @@ -3,23 +3,35 @@ import { act, queryByTestId, queryByText } from "@testing-library/react"; import React from "react"; import { vi } from "vitest"; -import type { GlobalPoint } from "@excalidraw/math"; +import { + ROUNDNESS, + VERTICAL_ALIGN, + KEYS, + reseed, + arrayToMap, +} from "@excalidraw/common"; -import { ROUNDNESS, VERTICAL_ALIGN } from "../constants"; -import { LinearElementEditor } from "../element/linearElementEditor"; +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { getBoundTextElementPosition, getBoundTextMaxWidth, -} from "../element/textElement"; -import * as textElementUtils from "../element/textElement"; -import { wrapText } from "../element/textWrapping"; +} from "@excalidraw/element/textElement"; +import * as textElementUtils from "@excalidraw/element/textElement"; +import { wrapText } from "@excalidraw/element/textWrapping"; + +import type { GlobalPoint } from "@excalidraw/math"; + +import type { + ExcalidrawElement, + ExcalidrawLinearElement, + ExcalidrawTextElementWithContainer, + FontString, +} from "@excalidraw/element/types"; + import { Excalidraw, mutateElement } from "../index"; -import { KEYS } from "../keys"; -import { reseed } from "../random"; import * as InteractiveCanvas from "../renderer/interactiveScene"; import * as StaticScene from "../renderer/staticScene"; import { API } from "../tests/helpers/api"; -import { arrayToMap } from "../utils"; import { Keyboard, Pointer, UI } from "./helpers/ui"; import { @@ -30,13 +42,6 @@ import { unmountComponent, } from "./test-utils"; -import type { - ExcalidrawElement, - ExcalidrawLinearElement, - ExcalidrawTextElementWithContainer, - FontString, -} from "../element/types"; - const renderInteractiveScene = vi.spyOn( InteractiveCanvas, "renderInteractiveScene", diff --git a/packages/excalidraw/tests/move.test.tsx b/packages/excalidraw/tests/move.test.tsx index 855496f44f..77fc7e57db 100644 --- a/packages/excalidraw/tests/move.test.tsx +++ b/packages/excalidraw/tests/move.test.tsx @@ -1,23 +1,26 @@ import React from "react"; import { vi } from "vitest"; -import "../../utils/test-utils"; -import { bindOrUnbindLinearElement } from "../element/binding"; -import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; -import { reseed } from "../random"; -import * as InteractiveCanvas from "../renderer/interactiveScene"; -import * as StaticScene from "../renderer/staticScene"; +import { bindOrUnbindLinearElement } from "@excalidraw/element/binding"; -import { UI, Pointer, Keyboard } from "./helpers/ui"; -import { render, fireEvent, act, unmountComponent } from "./test-utils"; +import { KEYS, reseed } from "@excalidraw/common"; + +import "@excalidraw/utils/test-utils"; import type { ExcalidrawLinearElement, NonDeleted, ExcalidrawRectangleElement, -} from "../element/types"; -import type Scene from "../scene/Scene"; +} from "@excalidraw/element/types"; + +import type Scene from "@excalidraw/excalidraw/scene/Scene"; + +import { Excalidraw } from "../index"; +import * as InteractiveCanvas from "../renderer/interactiveScene"; +import * as StaticScene from "../renderer/staticScene"; + +import { UI, Pointer, Keyboard } from "./helpers/ui"; +import { render, fireEvent, act, unmountComponent } from "./test-utils"; unmountComponent(); diff --git a/packages/excalidraw/tests/multiPointCreate.test.tsx b/packages/excalidraw/tests/multiPointCreate.test.tsx index 5cbce49668..cde3c7f983 100644 --- a/packages/excalidraw/tests/multiPointCreate.test.tsx +++ b/packages/excalidraw/tests/multiPointCreate.test.tsx @@ -1,9 +1,12 @@ import React from "react"; import { vi } from "vitest"; +import { KEYS, reseed } from "@excalidraw/common"; + +import type { ExcalidrawLinearElement } from "@excalidraw/element/types"; + import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; -import { reseed } from "../random"; + import * as InteractiveCanvas from "../renderer/interactiveScene"; import * as StaticScene from "../renderer/staticScene"; @@ -15,8 +18,6 @@ import { unmountComponent, } from "./test-utils"; -import type { ExcalidrawLinearElement } from "../element/types"; - unmountComponent(); const renderInteractiveScene = vi.spyOn( diff --git a/packages/excalidraw/tests/packages/events.test.tsx b/packages/excalidraw/tests/packages/events.test.tsx index 3e79239c8e..bc4441c40d 100644 --- a/packages/excalidraw/tests/packages/events.test.tsx +++ b/packages/excalidraw/tests/packages/events.test.tsx @@ -1,8 +1,9 @@ import React from "react"; import { vi } from "vitest"; +import { resolvablePromise } from "@excalidraw/common"; + import { Excalidraw, CaptureUpdateAction } from "../../index"; -import { resolvablePromise } from "../../utils"; import { API } from "../helpers/api"; import { Pointer } from "../helpers/ui"; import { render } from "../test-utils"; diff --git a/packages/excalidraw/tests/queries/toolQueries.ts b/packages/excalidraw/tests/queries/toolQueries.ts index ed168735dc..8413bf5fb9 100644 --- a/packages/excalidraw/tests/queries/toolQueries.ts +++ b/packages/excalidraw/tests/queries/toolQueries.ts @@ -1,8 +1,8 @@ import { queries, buildQueries } from "@testing-library/react"; -import { TOOL_TYPE } from "../../constants"; +import { TOOL_TYPE } from "@excalidraw/common"; -import type { ToolType } from "../../types"; +import type { ToolType } from "@excalidraw/excalidraw/types"; const _getAllByToolName = (container: HTMLElement, tool: ToolType | "lock") => { const toolTitle = tool === "lock" ? "lock" : TOOL_TYPE[tool]; diff --git a/packages/excalidraw/tests/regressionTests.test.tsx b/packages/excalidraw/tests/regressionTests.test.tsx index 42d726f1d9..68765024eb 100644 --- a/packages/excalidraw/tests/regressionTests.test.tsx +++ b/packages/excalidraw/tests/regressionTests.test.tsx @@ -1,12 +1,14 @@ import React from "react"; import { vi } from "vitest"; -import { FONT_FAMILY } from "../constants"; +import { FONT_FAMILY, CODES, KEYS, reseed } from "@excalidraw/common"; + +import { setDateTimeForTests } from "@excalidraw/common"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + import { Excalidraw } from "../index"; -import { CODES, KEYS } from "../keys"; -import { reseed } from "../random"; import * as StaticScene from "../renderer/staticScene"; -import { setDateTimeForTests } from "../utils"; import { API } from "./helpers/api"; import { Keyboard, Pointer, UI } from "./helpers/ui"; @@ -19,8 +21,6 @@ import { unmountComponent, } from "./test-utils"; -import type { ExcalidrawElement } from "../element/types"; - const { h } = window; const renderStaticScene = vi.spyOn(StaticScene, "renderStaticScene"); diff --git a/packages/excalidraw/tests/rotate.test.tsx b/packages/excalidraw/tests/rotate.test.tsx index 2c678f45b9..9687b08f25 100644 --- a/packages/excalidraw/tests/rotate.test.tsx +++ b/packages/excalidraw/tests/rotate.test.tsx @@ -1,8 +1,9 @@ import React from "react"; import { expect } from "vitest"; +import { reseed } from "@excalidraw/common"; + import { Excalidraw } from "../index"; -import { reseed } from "../random"; import { UI } from "./helpers/ui"; import { render, unmountComponent } from "./test-utils"; diff --git a/packages/excalidraw/tests/scene/export.test.ts b/packages/excalidraw/tests/scene/export.test.ts index 43c37eb283..3187e2c40a 100644 --- a/packages/excalidraw/tests/scene/export.test.ts +++ b/packages/excalidraw/tests/scene/export.test.ts @@ -1,6 +1,13 @@ import { exportToCanvas, exportToSvg } from "@excalidraw/utils"; -import { FONT_FAMILY, FRAME_STYLE } from "../../constants"; +import { FONT_FAMILY, FRAME_STYLE } from "@excalidraw/common"; + +import type { + ExcalidrawTextElement, + FractionalIndex, + NonDeletedExcalidrawElement, +} from "@excalidraw/element/types"; + import { prepareElementsForExport } from "../../data"; import * as exportUtils from "../../scene/export"; import { @@ -11,12 +18,6 @@ import { } from "../fixtures/elementFixture"; import { API } from "../helpers/api"; -import type { - ExcalidrawTextElement, - FractionalIndex, - NonDeletedExcalidrawElement, -} from "../../element/types"; - describe("exportToSvg", () => { const ELEMENT_HEIGHT = 100; const ELEMENT_WIDTH = 100; diff --git a/packages/excalidraw/tests/scroll.test.tsx b/packages/excalidraw/tests/scroll.test.tsx index 2ccc4546fd..ef5eb3dbf7 100644 --- a/packages/excalidraw/tests/scroll.test.tsx +++ b/packages/excalidraw/tests/scroll.test.tsx @@ -1,7 +1,8 @@ import React from "react"; +import { KEYS } from "@excalidraw/common"; + import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; import { API } from "./helpers/api"; import { Keyboard } from "./helpers/ui"; diff --git a/packages/excalidraw/tests/search.test.tsx b/packages/excalidraw/tests/search.test.tsx index d3622d4b1a..3a42cff627 100644 --- a/packages/excalidraw/tests/search.test.tsx +++ b/packages/excalidraw/tests/search.test.tsx @@ -1,16 +1,21 @@ import React from "react"; -import { CANVAS_SEARCH_TAB, CLASSES, DEFAULT_SIDEBAR } from "../constants"; +import { + CANVAS_SEARCH_TAB, + CLASSES, + DEFAULT_SIDEBAR, + KEYS, +} from "@excalidraw/common"; + +import type { ExcalidrawTextElement } from "@excalidraw/element/types"; + import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; import { API } from "./helpers/api"; import { Keyboard } from "./helpers/ui"; import { updateTextEditor } from "./queries/dom"; import { act, render, waitFor } from "./test-utils"; -import type { ExcalidrawTextElement } from "../element/types"; - const { h } = window; const querySearchInput = async () => { diff --git a/packages/excalidraw/tests/selection.test.tsx b/packages/excalidraw/tests/selection.test.tsx index d93d3eff53..10f4f7ad98 100644 --- a/packages/excalidraw/tests/selection.test.tsx +++ b/packages/excalidraw/tests/selection.test.tsx @@ -1,12 +1,13 @@ import React from "react"; import { vi } from "vitest"; +import { KEYS, reseed } from "@excalidraw/common"; + +import { SHAPES } from "../components/shapes"; + import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; -import { reseed } from "../random"; import * as InteractiveCanvas from "../renderer/interactiveScene"; import * as StaticScene from "../renderer/staticScene"; -import { SHAPES } from "../shapes"; import { API } from "./helpers/api"; import { Keyboard, Pointer, UI } from "./helpers/ui"; diff --git a/packages/excalidraw/tests/shortcuts.test.tsx b/packages/excalidraw/tests/shortcuts.test.tsx index ee2234ecc8..d4d1cb0def 100644 --- a/packages/excalidraw/tests/shortcuts.test.tsx +++ b/packages/excalidraw/tests/shortcuts.test.tsx @@ -1,7 +1,8 @@ import React from "react"; +import { KEYS } from "@excalidraw/common"; + import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; import { API } from "./helpers/api"; import { Keyboard } from "./helpers/ui"; diff --git a/packages/excalidraw/tests/test-utils.ts b/packages/excalidraw/tests/test-utils.ts index 73b3409827..b2b8aff9c9 100644 --- a/packages/excalidraw/tests/test-utils.ts +++ b/packages/excalidraw/tests/test-utils.ts @@ -9,10 +9,15 @@ import { } from "@testing-library/react"; import ansi from "ansicolor"; +import { ORIG_ID, arrayToMap } from "@excalidraw/common"; + +import { getSelectedElements } from "@excalidraw/element/selection"; + +import type { ExcalidrawElement } from "@excalidraw/element/types"; + +import type { AllPossibleKeys } from "@excalidraw/common/utility-types"; + import { STORAGE_KEYS } from "../../../excalidraw-app/app_constants"; -import { ORIG_ID } from "../constants"; -import { getSelectedElements } from "../scene/selection"; -import { arrayToMap } from "../utils"; import { UI } from "./helpers/ui"; import * as toolQueries from "./queries/toolQueries"; @@ -20,8 +25,6 @@ import * as toolQueries from "./queries/toolQueries"; import type { RenderResult, RenderOptions } from "@testing-library/react"; import type { ImportedDataState } from "../data/types"; -import type { ExcalidrawElement } from "../element/types"; -import type { AllPossibleKeys } from "../utility-types"; export { cleanup as unmountComponent }; diff --git a/packages/excalidraw/tests/tool.test.tsx b/packages/excalidraw/tests/tool.test.tsx index f70d1ccdd1..f7c101c1da 100644 --- a/packages/excalidraw/tests/tool.test.tsx +++ b/packages/excalidraw/tests/tool.test.tsx @@ -1,7 +1,8 @@ import React from "react"; +import { resolvablePromise } from "@excalidraw/common"; + import { Excalidraw } from "../index"; -import { resolvablePromise } from "../utils"; import { Pointer } from "./helpers/ui"; import { act, render } from "./test-utils"; diff --git a/packages/excalidraw/tests/utils.test.ts b/packages/excalidraw/tests/utils.test.ts index 34944faaa0..2dc8c00972 100644 --- a/packages/excalidraw/tests/utils.test.ts +++ b/packages/excalidraw/tests/utils.test.ts @@ -1,4 +1,4 @@ -import { isTransparent } from "../utils"; +import { isTransparent } from "@excalidraw/common"; describe("Test isTransparent", () => { it("should return true when color is rgb transparent", () => { diff --git a/packages/excalidraw/tests/viewMode.test.tsx b/packages/excalidraw/tests/viewMode.test.tsx index c190ee0e3b..0a94055c79 100644 --- a/packages/excalidraw/tests/viewMode.test.tsx +++ b/packages/excalidraw/tests/viewMode.test.tsx @@ -1,8 +1,8 @@ import React from "react"; -import { CURSOR_TYPE } from "../constants"; +import { CURSOR_TYPE, KEYS } from "@excalidraw/common"; + import { Excalidraw } from "../index"; -import { KEYS } from "../keys"; import { API } from "./helpers/api"; import { Keyboard, Pointer, UI } from "./helpers/ui"; diff --git a/packages/excalidraw/tsconfig.json b/packages/excalidraw/tsconfig.json index f61b8d0af4..82cc2c2377 100644 --- a/packages/excalidraw/tsconfig.json +++ b/packages/excalidraw/tsconfig.json @@ -1,24 +1,6 @@ { + "extends": "../tsconfig.base.json", "compilerOptions": { - "outDir": "./dist/types", - "target": "ESNext", - "strict": true, - "skipLibCheck": true, - "declaration": true, - "allowSyntheticDefaultImports": true, - "module": "ESNext", - "moduleResolution": "Node", - "resolveJsonModule": true, - "jsx": "react-jsx", - "emitDeclarationOnly": true, - "paths": { - "@excalidraw/excalidraw": ["../excalidraw/index.tsx"], - "@excalidraw/utils": ["../utils/index.ts"], - "@excalidraw/math": ["../math/index.ts"], - "@excalidraw/excalidraw/*": ["../excalidraw/*"], - "@excalidraw/utils/*": ["../utils/*"], - "@excalidraw/math/*": ["../math/*"] - } - }, - "exclude": ["**/*.test.*", "tests", "types", "examples", "dist"] + "outDir": "./dist/types" + } } diff --git a/packages/excalidraw/types.ts b/packages/excalidraw/types.ts index 64c0ac2989..31ce332f8d 100644 --- a/packages/excalidraw/types.ts +++ b/packages/excalidraw/types.ts @@ -1,19 +1,16 @@ -import type { Action } from "./actions/types"; -import type { Spreadsheet } from "./charts"; -import type { ClipboardData } from "./clipboard"; -import type App from "./components/App"; -import type Library from "./data/library"; -import type { FileSystemHandle } from "./data/filesystem"; -import type { IMAGE_MIME_TYPES, MIME_TYPES } from "./constants"; -import type { ContextMenuItems } from "./components/ContextMenu"; -import type { SnapLine } from "./snapping"; -import type { Merge, MaybePromise, ValueOf, MakeBrand } from "./utility-types"; -import type { CaptureUpdateActionType } from "./store"; -import type { UserIdleState } from "./constants"; -import type { ImportedDataState } from "./data/types"; -import type { SuggestedBinding } from "./element/binding"; -import type { LinearElementEditor } from "./element/linearElementEditor"; -import type { MaybeTransformHandleType } from "./element/transformHandles"; +import type { + IMAGE_MIME_TYPES, + UserIdleState, + throttleRAF, + MIME_TYPES, +} from "@excalidraw/common"; + +import type { SuggestedBinding } from "@excalidraw/element/binding"; + +import type { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; + +import type { MaybeTransformHandleType } from "@excalidraw/element/transformHandles"; + import type { PointerType, ExcalidrawLinearElement, @@ -37,10 +34,28 @@ import type { ExcalidrawIframeLikeElement, OrderedExcalidrawElement, ExcalidrawNonSelectionElement, -} from "./element/types"; +} from "@excalidraw/element/types"; + +import type { + Merge, + MaybePromise, + ValueOf, + MakeBrand, +} from "@excalidraw/common/utility-types"; + +import type { Action } from "./actions/types"; +import type { Spreadsheet } from "./charts"; +import type { ClipboardData } from "./clipboard"; +import type App from "./components/App"; +import type Library from "./data/library"; +import type { FileSystemHandle } from "./data/filesystem"; +import type { ContextMenuItems } from "./components/ContextMenu"; +import type { SnapLine } from "./snapping"; +import type { CaptureUpdateActionType } from "./store"; +import type { ImportedDataState } from "./data/types"; + import type { Language } from "./i18n"; import type { isOverScrollBars } from "./scene/scrollbars"; -import type { throttleRAF } from "./utils"; import type React from "react"; import type { JSX } from "react"; diff --git a/packages/excalidraw/visualdebug.ts b/packages/excalidraw/visualdebug.ts index 6b70148649..9ad1490d1d 100644 --- a/packages/excalidraw/visualdebug.ts +++ b/packages/excalidraw/visualdebug.ts @@ -6,12 +6,12 @@ import { type LocalPoint, } from "@excalidraw/math"; +import { isBounds } from "@excalidraw/element/typeChecks"; + import type { Curve } from "@excalidraw/math"; import type { LineSegment } from "@excalidraw/utils"; -import { isBounds } from "./element/typeChecks"; - -import type { Bounds } from "./element/bounds"; +import type { Bounds } from "@excalidraw/element/bounds"; // The global data holder to collect the debug operations declare global { diff --git a/packages/excalidraw/vite-env.d.ts b/packages/excalidraw/vite-env.d.ts index 4292e3b6a6..3c53906ab2 100644 --- a/packages/excalidraw/vite-env.d.ts +++ b/packages/excalidraw/vite-env.d.ts @@ -24,6 +24,8 @@ interface ImportMetaEnv { // whether to disable live reload / HMR. Usuaully what you want to do when // debugging Service Workers. VITE_APP_DEV_DISABLE_LIVE_RELOAD: string; + // To enable bounding box for text containers + VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX: string; FAST_REFRESH: string; @@ -34,8 +36,6 @@ interface ImportMetaEnv { //Debug flags - // To enable bounding box for text containers - VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX: string; VITE_APP_DISABLE_SENTRY: string; // Set this flag to false if you want to open the overlay by default VITE_APP_COLLAPSE_OVERLAY: string; diff --git a/packages/excalidraw/workers.ts b/packages/excalidraw/workers.ts index f5964d0884..38efda1024 100644 --- a/packages/excalidraw/workers.ts +++ b/packages/excalidraw/workers.ts @@ -1,5 +1,6 @@ +import { debounce } from "@excalidraw/common"; + import { WorkerInTheMainChunkError, WorkerUrlNotDefinedError } from "./errors"; -import { debounce } from "./utils"; class IdleWorker { public instance: Worker; diff --git a/packages/excalidraw/element/textWysiwyg.test.tsx b/packages/excalidraw/wysiwyg/textWysiwyg.test.tsx similarity index 99% rename from packages/excalidraw/element/textWysiwyg.test.tsx rename to packages/excalidraw/wysiwyg/textWysiwyg.test.tsx index 11c700e330..959c5a0129 100644 --- a/packages/excalidraw/element/textWysiwyg.test.tsx +++ b/packages/excalidraw/wysiwyg/textWysiwyg.test.tsx @@ -1,10 +1,22 @@ -import { pointFrom } from "@excalidraw/math"; import { queryByText } from "@testing-library/react"; -import React from "react"; -import { FONT_FAMILY, TEXT_ALIGN, VERTICAL_ALIGN } from "../constants"; +import { pointFrom } from "@excalidraw/math"; +import { getOriginalContainerHeightFromCache } from "@excalidraw/element/containerCache"; + +import { + CODES, + KEYS, + FONT_FAMILY, + TEXT_ALIGN, + VERTICAL_ALIGN, +} from "@excalidraw/common"; + +import type { + ExcalidrawTextElement, + ExcalidrawTextElementWithContainer, +} from "@excalidraw/element/types"; + import { Excalidraw } from "../index"; -import { CODES, KEYS } from "../keys"; import { API } from "../tests/helpers/api"; import { Keyboard, Pointer, UI } from "../tests/helpers/ui"; import { getTextEditor, updateTextEditor } from "../tests/queries/dom"; @@ -20,13 +32,6 @@ import { restoreOriginalGetBoundingClientRect, } from "../tests/test-utils"; -import { getOriginalContainerHeightFromCache } from "./containerCache"; - -import type { - ExcalidrawTextElement, - ExcalidrawTextElementWithContainer, -} from "./types"; - unmountComponent(); const tab = " "; diff --git a/packages/excalidraw/element/textWysiwyg.tsx b/packages/excalidraw/wysiwyg/textWysiwyg.tsx similarity index 97% rename from packages/excalidraw/element/textWysiwyg.tsx rename to packages/excalidraw/wysiwyg/textWysiwyg.tsx index b31798687c..b1610125f3 100644 --- a/packages/excalidraw/element/textWysiwyg.tsx +++ b/packages/excalidraw/wysiwyg/textWysiwyg.tsx @@ -1,31 +1,21 @@ import { - actionResetZoom, - actionZoomIn, - actionZoomOut, -} from "../actions/actionCanvas"; -import { - actionDecreaseFontSize, - actionIncreaseFontSize, -} from "../actions/actionProperties"; -import { parseClipboard } from "../clipboard"; -import { CLASSES, POINTER_BUTTON } from "../constants"; -import { CODES, KEYS } from "../keys"; -import Scene from "../scene/Scene"; -import { + CODES, + KEYS, + CLASSES, + POINTER_BUTTON, isWritableElement, getFontString, getFontFamilyString, isTestEnv, -} from "../utils"; - -import { actionSaveToActiveFile } from "../actions"; +} from "@excalidraw/common"; import { originalContainerCache, updateOriginalContainerCache, -} from "./containerCache"; -import { LinearElementEditor } from "./linearElementEditor"; -import { bumpVersion, mutateElement } from "./mutateElement"; +} from "@excalidraw/element/containerCache"; + +import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; +import { bumpVersion, mutateElement } from "@excalidraw/element/mutateElement"; import { getBoundTextElementId, getContainerElement, @@ -36,22 +26,37 @@ import { computeContainerDimensionForBoundText, computeBoundTextPosition, getBoundTextElement, -} from "./textElement"; -import { getTextWidth } from "./textMeasurements"; -import { normalizeText } from "./textMeasurements"; -import { wrapText } from "./textWrapping"; +} from "@excalidraw/element/textElement"; +import { getTextWidth } from "@excalidraw/element/textMeasurements"; +import { normalizeText } from "@excalidraw/element/textMeasurements"; +import { wrapText } from "@excalidraw/element/textWrapping"; import { isArrowElement, isBoundToContainer, isTextElement, -} from "./typeChecks"; +} from "@excalidraw/element/typeChecks"; import type { ExcalidrawElement, ExcalidrawLinearElement, ExcalidrawTextElementWithContainer, ExcalidrawTextElement, -} from "./types"; +} from "@excalidraw/element/types"; + +import { actionSaveToActiveFile } from "../actions"; + +import Scene from "../scene/Scene"; +import { parseClipboard } from "../clipboard"; +import { + actionDecreaseFontSize, + actionIncreaseFontSize, +} from "../actions/actionProperties"; +import { + actionResetZoom, + actionZoomIn, + actionZoomOut, +} from "../actions/actionCanvas"; + import type App from "../components/App"; import type { AppState } from "../types"; diff --git a/packages/math/CHANGELOG.md b/packages/math/CHANGELOG.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/math/README.md b/packages/math/README.md index eaa163037b..348a9de07f 100644 --- a/packages/math/README.md +++ b/packages/math/README.md @@ -17,5 +17,3 @@ With PNPM, similarly install the package with this command: ```bash pnpm add @excalidraw/math ``` - -## API diff --git a/packages/math/package.json b/packages/math/package.json index a60c971191..aef877f451 100644 --- a/packages/math/package.json +++ b/packages/math/package.json @@ -54,6 +54,6 @@ "repository": "https://github.com/excalidraw/excalidraw", "scripts": { "gen:types": "rm -rf types && tsc", - "build:esm": "rm -rf dist && node ../../scripts/buildMath.js && yarn gen:types" + "build:esm": "rm -rf dist && node ../../scripts/buildBase.js && yarn gen:types" } } diff --git a/packages/math/angle.ts b/packages/math/src/angle.ts similarity index 100% rename from packages/math/angle.ts rename to packages/math/src/angle.ts diff --git a/packages/math/curve.ts b/packages/math/src/curve.ts similarity index 98% rename from packages/math/curve.ts rename to packages/math/src/curve.ts index cd466bbc78..a79fb43a19 100644 --- a/packages/math/curve.ts +++ b/packages/math/src/curve.ts @@ -1,8 +1,9 @@ +import type { Bounds } from "@excalidraw/element/bounds"; + import { isPoint, pointDistance, pointFrom } from "./point"; import { rectangle, rectangleIntersectLineSegment } from "./rectangle"; import type { Curve, GlobalPoint, LineSegment, LocalPoint } from "./types"; -import type { Bounds } from "../excalidraw/element/bounds"; /** * diff --git a/packages/math/ellipse.ts b/packages/math/src/ellipse.ts similarity index 100% rename from packages/math/ellipse.ts rename to packages/math/src/ellipse.ts diff --git a/packages/math/index.ts b/packages/math/src/index.ts similarity index 100% rename from packages/math/index.ts rename to packages/math/src/index.ts diff --git a/packages/math/line.ts b/packages/math/src/line.ts similarity index 100% rename from packages/math/line.ts rename to packages/math/src/line.ts diff --git a/packages/math/point.ts b/packages/math/src/point.ts similarity index 100% rename from packages/math/point.ts rename to packages/math/src/point.ts diff --git a/packages/math/polygon.ts b/packages/math/src/polygon.ts similarity index 100% rename from packages/math/polygon.ts rename to packages/math/src/polygon.ts diff --git a/packages/math/range.ts b/packages/math/src/range.ts similarity index 97% rename from packages/math/range.ts rename to packages/math/src/range.ts index dee3d7edfc..1b292344ee 100644 --- a/packages/math/range.ts +++ b/packages/math/src/range.ts @@ -1,4 +1,4 @@ -import { toBrandedType } from "@excalidraw/excalidraw/utils"; +import { toBrandedType } from "@excalidraw/common"; import type { InclusiveRange } from "./types"; diff --git a/packages/math/rectangle.ts b/packages/math/src/rectangle.ts similarity index 100% rename from packages/math/rectangle.ts rename to packages/math/src/rectangle.ts diff --git a/packages/math/segment.ts b/packages/math/src/segment.ts similarity index 100% rename from packages/math/segment.ts rename to packages/math/src/segment.ts diff --git a/packages/math/triangle.ts b/packages/math/src/triangle.ts similarity index 100% rename from packages/math/triangle.ts rename to packages/math/src/triangle.ts diff --git a/packages/math/types.ts b/packages/math/src/types.ts similarity index 100% rename from packages/math/types.ts rename to packages/math/src/types.ts diff --git a/packages/math/utils.ts b/packages/math/src/utils.ts similarity index 100% rename from packages/math/utils.ts rename to packages/math/src/utils.ts diff --git a/packages/math/vector.ts b/packages/math/src/vector.ts similarity index 100% rename from packages/math/vector.ts rename to packages/math/src/vector.ts diff --git a/packages/math/curve.test.ts b/packages/math/tests/curve.test.ts similarity index 94% rename from packages/math/curve.test.ts rename to packages/math/tests/curve.test.ts index 8d60a73465..7395620968 100644 --- a/packages/math/curve.test.ts +++ b/packages/math/tests/curve.test.ts @@ -1,13 +1,13 @@ -import "../utils/test-utils"; +import "@excalidraw/utils/test-utils"; import { curve, curveClosestPoint, curveIntersectLineSegment, curvePointDistance, -} from "./curve"; -import { pointFrom } from "./point"; -import { lineSegment } from "./segment"; +} from "../src/curve"; +import { pointFrom } from "../src/point"; +import { lineSegment } from "../src/segment"; describe("Math curve", () => { describe("line segment intersection", () => { diff --git a/packages/math/ellipse.test.ts b/packages/math/tests/ellipse.test.ts similarity index 94% rename from packages/math/ellipse.test.ts rename to packages/math/tests/ellipse.test.ts index bcaab2a5de..4fa0d4e59f 100644 --- a/packages/math/ellipse.test.ts +++ b/packages/math/tests/ellipse.test.ts @@ -4,12 +4,12 @@ import { ellipseIncludesPoint, ellipseTouchesPoint, ellipseLineIntersectionPoints, -} from "./ellipse"; -import { line } from "./line"; -import { pointFrom } from "./point"; -import { lineSegment } from "./segment"; +} from "../src/ellipse"; +import { line } from "../src/line"; +import { pointFrom } from "../src/point"; +import { lineSegment } from "../src/segment"; -import type { Ellipse, GlobalPoint } from "./types"; +import type { Ellipse, GlobalPoint } from "../src/types"; describe("point and ellipse", () => { it("point on ellipse", () => { diff --git a/packages/math/line.test.ts b/packages/math/tests/line.test.ts similarity index 88% rename from packages/math/line.test.ts rename to packages/math/tests/line.test.ts index 0e6bb1cc8f..c8915a466c 100644 --- a/packages/math/line.test.ts +++ b/packages/math/tests/line.test.ts @@ -1,5 +1,5 @@ -import { line, linesIntersectAt } from "./line"; -import { pointFrom } from "./point"; +import { line, linesIntersectAt } from "../src/line"; +import { pointFrom } from "../src/point"; describe("line-line intersections", () => { it("should correctly detect intersection at origin", () => { diff --git a/packages/math/point.test.ts b/packages/math/tests/point.test.ts similarity index 84% rename from packages/math/point.test.ts rename to packages/math/tests/point.test.ts index 0ed59ee9ab..3f3ee15cd5 100644 --- a/packages/math/point.test.ts +++ b/packages/math/tests/point.test.ts @@ -1,6 +1,6 @@ -import { pointFrom, pointRotateRads } from "./point"; +import { pointFrom, pointRotateRads } from "../src/point"; -import type { Radians } from "./types"; +import type { Radians } from "../src/types"; describe("rotate", () => { it("should rotate over (x2, y2) and return the rotated coordinates for (x1, y1)", () => { diff --git a/packages/math/range.test.ts b/packages/math/tests/range.test.ts similarity index 99% rename from packages/math/range.test.ts rename to packages/math/tests/range.test.ts index fb4b6a38d3..9808f77f41 100644 --- a/packages/math/range.test.ts +++ b/packages/math/tests/range.test.ts @@ -1,4 +1,4 @@ -import { rangeInclusive, rangeIntersection, rangesOverlap } from "./range"; +import { rangeInclusive, rangeIntersection, rangesOverlap } from "../src/range"; describe("range overlap", () => { const range1_4 = rangeInclusive(1, 4); diff --git a/packages/math/segment.test.ts b/packages/math/tests/segment.test.ts similarity index 82% rename from packages/math/segment.test.ts rename to packages/math/tests/segment.test.ts index 4237a3c855..6b29bba591 100644 --- a/packages/math/segment.test.ts +++ b/packages/math/tests/segment.test.ts @@ -1,5 +1,5 @@ -import { pointFrom } from "./point"; -import { lineSegment, lineSegmentIntersectionPoints } from "./segment"; +import { pointFrom } from "../src/point"; +import { lineSegment, lineSegmentIntersectionPoints } from "../src/segment"; describe("line-segment intersections", () => { it("should correctly detect intersection", () => { diff --git a/packages/math/vector.test.ts b/packages/math/tests/vector.test.ts similarity index 88% rename from packages/math/vector.test.ts rename to packages/math/tests/vector.test.ts index 145c909535..820f604003 100644 --- a/packages/math/vector.test.ts +++ b/packages/math/tests/vector.test.ts @@ -1,4 +1,4 @@ -import { isVector } from "."; +import { isVector } from "../src/vector"; describe("Vector", () => { test("isVector", () => { diff --git a/packages/math/tsconfig.json b/packages/math/tsconfig.json index f61b8d0af4..82cc2c2377 100644 --- a/packages/math/tsconfig.json +++ b/packages/math/tsconfig.json @@ -1,24 +1,6 @@ { + "extends": "../tsconfig.base.json", "compilerOptions": { - "outDir": "./dist/types", - "target": "ESNext", - "strict": true, - "skipLibCheck": true, - "declaration": true, - "allowSyntheticDefaultImports": true, - "module": "ESNext", - "moduleResolution": "Node", - "resolveJsonModule": true, - "jsx": "react-jsx", - "emitDeclarationOnly": true, - "paths": { - "@excalidraw/excalidraw": ["../excalidraw/index.tsx"], - "@excalidraw/utils": ["../utils/index.ts"], - "@excalidraw/math": ["../math/index.ts"], - "@excalidraw/excalidraw/*": ["../excalidraw/*"], - "@excalidraw/utils/*": ["../utils/*"], - "@excalidraw/math/*": ["../math/*"] - } - }, - "exclude": ["**/*.test.*", "tests", "types", "examples", "dist"] + "outDir": "./dist/types" + } } diff --git a/packages/tsconfig.base.json b/packages/tsconfig.base.json new file mode 100644 index 0000000000..18f7fcb361 --- /dev/null +++ b/packages/tsconfig.base.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ESNext", + "strict": true, + "skipLibCheck": true, + "declaration": true, + "allowSyntheticDefaultImports": true, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "jsx": "react-jsx", + "emitDeclarationOnly": true, + "paths": { + "@excalidraw/common": ["./common/src/index.ts"], + "@excalidraw/common/*": ["./common/src/*"], + "@excalidraw/element": ["./element/src/index.ts"], + "@excalidraw/element/*": ["./element/src/*"], + "@excalidraw/excalidraw": ["./excalidraw/index.tsx"], + "@excalidraw/excalidraw/*": ["./excalidraw/*"], + "@excalidraw/math": ["./math/src/index.ts"], + "@excalidraw/math/*": ["./math/src/*"], + "@excalidraw/utils": ["./utils/src/index.ts"], + "@excalidraw/utils/*": ["./utils/src/*"] + } + }, + "exclude": ["**/*.test.*", "tests", "types", "examples", "dist"] +} diff --git a/packages/utils/bbox.ts b/packages/utils/src/bbox.ts similarity index 96% rename from packages/utils/bbox.ts rename to packages/utils/src/bbox.ts index 61c75a6687..a561281563 100644 --- a/packages/utils/bbox.ts +++ b/packages/utils/src/bbox.ts @@ -5,7 +5,7 @@ import { type LocalPoint, } from "@excalidraw/math"; -import type { Bounds } from "@excalidraw/excalidraw/element/bounds"; +import type { Bounds } from "@excalidraw/element/bounds"; export type LineSegment

= [P, P]; diff --git a/packages/utils/collision.ts b/packages/utils/src/collision.ts similarity index 96% rename from packages/utils/collision.ts rename to packages/utils/src/collision.ts index f90019418e..b7c155f663 100644 --- a/packages/utils/collision.ts +++ b/packages/utils/src/collision.ts @@ -12,13 +12,9 @@ import { import type { Curve } from "@excalidraw/math"; -import { - pointInEllipse, - pointOnEllipse, - type GeometricShape, -} from "./geometry/shape"; +import { pointInEllipse, pointOnEllipse } from "./shape"; -import type { Polycurve, Polyline } from "./geometry/shape"; +import type { Polycurve, Polyline, GeometricShape } from "./shape"; // check if the given point is considered on the given shape's border export const isPointOnShape = ( diff --git a/packages/utils/export.ts b/packages/utils/src/export.ts similarity index 98% rename from packages/utils/export.ts rename to packages/utils/src/export.ts index 6de25c62bf..4559fe1af8 100644 --- a/packages/utils/export.ts +++ b/packages/utils/src/export.ts @@ -1,10 +1,10 @@ +import { MIME_TYPES } from "@excalidraw/common"; import { getDefaultAppState } from "@excalidraw/excalidraw/appState"; import { copyBlobToClipboardAsPng, copyTextToSystemClipboard, copyToClipboard, } from "@excalidraw/excalidraw/clipboard"; -import { MIME_TYPES } from "@excalidraw/excalidraw/constants"; import { encodePngMetadata } from "@excalidraw/excalidraw/data/image"; import { serializeAsJSON } from "@excalidraw/excalidraw/data/json"; import { restore } from "@excalidraw/excalidraw/data/restore"; @@ -17,7 +17,7 @@ import type { ExcalidrawElement, ExcalidrawFrameLikeElement, NonDeleted, -} from "@excalidraw/excalidraw/element/types"; +} from "@excalidraw/element/types"; import type { AppState, BinaryFiles } from "@excalidraw/excalidraw/types"; export { MIME_TYPES }; diff --git a/packages/utils/index.ts b/packages/utils/src/index.ts similarity index 52% rename from packages/utils/index.ts rename to packages/utils/src/index.ts index 2a929134e4..58830b356d 100644 --- a/packages/utils/index.ts +++ b/packages/utils/src/index.ts @@ -1,4 +1,4 @@ export * from "./export"; export * from "./withinBounds"; export * from "./bbox"; -export { getCommonBounds } from "@excalidraw/excalidraw/element/bounds"; +export { getCommonBounds } from "@excalidraw/element/bounds"; diff --git a/packages/utils/geometry/shape.ts b/packages/utils/src/shape.ts similarity index 98% rename from packages/utils/geometry/shape.ts rename to packages/utils/src/shape.ts index ea3cde3f60..b750c232e7 100644 --- a/packages/utils/geometry/shape.ts +++ b/packages/utils/src/shape.ts @@ -11,9 +11,9 @@ * also included in this file are methods for converting an Excalidraw element or a Drawable from roughjs * to pure shapes */ +import { pointsOnBezierCurves } from "points-on-curve"; -import { getElementAbsoluteCoords } from "@excalidraw/excalidraw/element"; -import { invariant } from "@excalidraw/excalidraw/utils"; +import { invariant } from "@excalidraw/common"; import { curve, lineSegment, @@ -33,7 +33,8 @@ import { type GlobalPoint, type LocalPoint, } from "@excalidraw/math"; -import { pointsOnBezierCurves } from "points-on-curve"; + +import { getElementAbsoluteCoords } from "@excalidraw/element/bounds"; import type { ElementsMap, @@ -50,7 +51,7 @@ import type { ExcalidrawRectangleElement, ExcalidrawSelectionElement, ExcalidrawTextElement, -} from "@excalidraw/excalidraw/element/types"; +} from "@excalidraw/element/types"; import type { Curve, LineSegment, Polygon, Radians } from "@excalidraw/math"; import type { Drawable, Op } from "roughjs/bin/core"; diff --git a/packages/utils/test-utils.ts b/packages/utils/src/test-utils.ts similarity index 100% rename from packages/utils/test-utils.ts rename to packages/utils/src/test-utils.ts diff --git a/packages/utils/withinBounds.ts b/packages/utils/src/withinBounds.ts similarity index 94% rename from packages/utils/withinBounds.ts rename to packages/utils/src/withinBounds.ts index 71bc78969d..0e1cf38a61 100644 --- a/packages/utils/withinBounds.ts +++ b/packages/utils/src/withinBounds.ts @@ -1,12 +1,12 @@ -import { getElementBounds } from "@excalidraw/excalidraw/element/bounds"; +import { arrayToMap } from "@excalidraw/common"; +import { getElementBounds } from "@excalidraw/element/bounds"; import { isArrowElement, isExcalidrawElement, isFreeDrawElement, isLinearElement, isTextElement, -} from "@excalidraw/excalidraw/element/typeChecks"; -import { arrayToMap } from "@excalidraw/excalidraw/utils"; +} from "@excalidraw/element/typeChecks"; import { rangeIncludesValue, pointFrom, @@ -14,13 +14,13 @@ import { rangeInclusive, } from "@excalidraw/math"; -import type { Bounds } from "@excalidraw/excalidraw/element/bounds"; +import type { Bounds } from "@excalidraw/element/bounds"; import type { ExcalidrawElement, ExcalidrawFreeDrawElement, ExcalidrawLinearElement, NonDeletedExcalidrawElement, -} from "@excalidraw/excalidraw/element/types"; +} from "@excalidraw/element/types"; import type { LocalPoint } from "@excalidraw/math"; type Element = NonDeletedExcalidrawElement; diff --git a/packages/utils/__snapshots__/export.test.ts.snap b/packages/utils/tests/__snapshots__/export.test.ts.snap similarity index 100% rename from packages/utils/__snapshots__/export.test.ts.snap rename to packages/utils/tests/__snapshots__/export.test.ts.snap diff --git a/packages/utils/__snapshots__/utils.test.ts.snap b/packages/utils/tests/__snapshots__/utils.test.ts.snap similarity index 100% rename from packages/utils/__snapshots__/utils.test.ts.snap rename to packages/utils/tests/__snapshots__/utils.test.ts.snap diff --git a/packages/utils/collision.test.ts b/packages/utils/tests/collision.test.ts similarity index 96% rename from packages/utils/collision.test.ts rename to packages/utils/tests/collision.test.ts index 24f96e9857..35bc28b34e 100644 --- a/packages/utils/collision.test.ts +++ b/packages/utils/tests/collision.test.ts @@ -9,9 +9,9 @@ import { import type { Curve, Degrees, GlobalPoint } from "@excalidraw/math"; -import { pointOnCurve, pointOnPolyline } from "./collision"; +import { pointOnCurve, pointOnPolyline } from "../src/collision"; -import type { Polyline } from "./geometry/shape"; +import type { Polyline } from "../src/shape"; describe("point and curve", () => { const c: Curve = curve( diff --git a/packages/utils/export.test.ts b/packages/utils/tests/export.test.ts similarity index 97% rename from packages/utils/export.test.ts rename to packages/utils/tests/export.test.ts index 86bbe80b7f..47b9398ab7 100644 --- a/packages/utils/export.test.ts +++ b/packages/utils/tests/export.test.ts @@ -1,9 +1,9 @@ -import { MIME_TYPES } from "@excalidraw/excalidraw/constants"; +import { MIME_TYPES } from "@excalidraw/common"; import * as mockedSceneExportUtils from "@excalidraw/excalidraw/scene/export"; import { diagramFactory } from "@excalidraw/excalidraw/tests/fixtures/diagramFixture"; import { vi } from "vitest"; -import * as utils from "."; +import * as utils from "../src"; const exportToSvgSpy = vi.spyOn(mockedSceneExportUtils, "exportToSvg"); diff --git a/packages/utils/geometry/geometry.test.ts b/packages/utils/tests/geometry.test.ts similarity index 98% rename from packages/utils/geometry/geometry.test.ts rename to packages/utils/tests/geometry.test.ts index 6ddab71b0a..8a2f95d3fc 100644 --- a/packages/utils/geometry/geometry.test.ts +++ b/packages/utils/tests/geometry.test.ts @@ -15,7 +15,7 @@ import type { Radians, } from "@excalidraw/math"; -import { pointInEllipse, pointOnEllipse, type Ellipse } from "./shape"; +import { pointInEllipse, pointOnEllipse, type Ellipse } from "../src/shape"; describe("point and line", () => { // const l: Line = line(point(1, 0), point(1, 2)); diff --git a/packages/utils/utils.unmocked.test.ts b/packages/utils/tests/utils.unmocked.test.ts similarity index 98% rename from packages/utils/utils.unmocked.test.ts rename to packages/utils/tests/utils.unmocked.test.ts index 417eabda1e..b77bc37d1c 100644 --- a/packages/utils/utils.unmocked.test.ts +++ b/packages/utils/tests/utils.unmocked.test.ts @@ -4,7 +4,7 @@ import { API } from "@excalidraw/excalidraw/tests/helpers/api"; import type { ImportedDataState } from "@excalidraw/excalidraw/data/types"; -import * as utils from "./index"; +import * as utils from "../src"; // NOTE this test file is using the actual API, unmocked. Hence splitting it // from the other test file, because I couldn't figure out how to test diff --git a/packages/utils/withinBounds.test.ts b/packages/utils/tests/withinBounds.test.ts similarity index 98% rename from packages/utils/withinBounds.test.ts rename to packages/utils/tests/withinBounds.test.ts index b07d0bc338..d1af75de86 100644 --- a/packages/utils/withinBounds.test.ts +++ b/packages/utils/tests/withinBounds.test.ts @@ -1,12 +1,12 @@ import { API } from "@excalidraw/excalidraw/tests/helpers/api"; -import type { Bounds } from "@excalidraw/excalidraw/element/bounds"; +import type { Bounds } from "@excalidraw/element/bounds"; import { elementPartiallyOverlapsWithOrContainsBBox, elementsOverlappingBBox, isElementInsideBBox, -} from "./withinBounds"; +} from "../src/withinBounds"; const makeElement = (x: number, y: number, width: number, height: number) => API.createElement({ diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index f61b8d0af4..82cc2c2377 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -1,24 +1,6 @@ { + "extends": "../tsconfig.base.json", "compilerOptions": { - "outDir": "./dist/types", - "target": "ESNext", - "strict": true, - "skipLibCheck": true, - "declaration": true, - "allowSyntheticDefaultImports": true, - "module": "ESNext", - "moduleResolution": "Node", - "resolveJsonModule": true, - "jsx": "react-jsx", - "emitDeclarationOnly": true, - "paths": { - "@excalidraw/excalidraw": ["../excalidraw/index.tsx"], - "@excalidraw/utils": ["../utils/index.ts"], - "@excalidraw/math": ["../math/index.ts"], - "@excalidraw/excalidraw/*": ["../excalidraw/*"], - "@excalidraw/utils/*": ["../utils/*"], - "@excalidraw/math/*": ["../math/*"] - } - }, - "exclude": ["**/*.test.*", "tests", "types", "examples", "dist"] + "outDir": "./dist/types" + } } diff --git a/scripts/buildMath.js b/scripts/buildBase.js similarity index 77% rename from scripts/buildMath.js rename to scripts/buildBase.js index ba421b48cb..336b498235 100644 --- a/scripts/buildMath.js +++ b/scripts/buildBase.js @@ -1,27 +1,27 @@ const path = require("path"); const { build } = require("esbuild"); -const { sassPlugin } = require("esbuild-sass-plugin"); // contains all dependencies bundled inside const getConfig = (outdir) => ({ outdir, bundle: true, format: "esm", - entryPoints: ["index.ts"], + entryPoints: ["src/index.ts"], entryNames: "[name]", assetNames: "[dir]/[name]", alias: { + "@excalidraw/common": path.resolve(__dirname, "../packages/common/src"), + "@excalidraw/element": path.resolve(__dirname, "../packages/element/src"), "@excalidraw/excalidraw": path.resolve(__dirname, "../packages/excalidraw"), - "@excalidraw/utils": path.resolve(__dirname, "../packages/utils"), - "@excalidraw/math": path.resolve(__dirname, "../packages/math"), + "@excalidraw/math": path.resolve(__dirname, "../packages/math/src"), + "@excalidraw/utils": path.resolve(__dirname, "../packages/utils/src"), }, }); function buildDev(config) { return build({ ...config, - plugins: [sassPlugin()], sourcemap: true, define: { "import.meta.env": JSON.stringify({ DEV: true }), @@ -32,7 +32,6 @@ function buildDev(config) { function buildProd(config) { return build({ ...config, - plugins: [sassPlugin()], minify: true, define: { "import.meta.env": JSON.stringify({ PROD: true }), @@ -42,10 +41,10 @@ function buildProd(config) { const createESMRawBuild = async () => { // development unminified build with source maps - buildDev(getConfig("dist/dev")); + await buildDev(getConfig("dist/dev")); // production minified build without sourcemaps - buildProd(getConfig("dist/prod")); + await buildProd(getConfig("dist/prod")); }; (async () => { diff --git a/scripts/buildPackage.js b/scripts/buildPackage.js index 3dd15eecae..baf20615f6 100644 --- a/scripts/buildPackage.js +++ b/scripts/buildPackage.js @@ -28,9 +28,11 @@ const getConfig = (outdir) => ({ assetNames: "[dir]/[name]", chunkNames: "[dir]/[name]-[hash]", alias: { + "@excalidraw/common": path.resolve(__dirname, "../packages/common/src"), + "@excalidraw/element": path.resolve(__dirname, "../packages/element/src"), "@excalidraw/excalidraw": path.resolve(__dirname, "../packages/excalidraw"), - "@excalidraw/utils": path.resolve(__dirname, "../packages/utils"), - "@excalidraw/math": path.resolve(__dirname, "../packages/math"), + "@excalidraw/math": path.resolve(__dirname, "../packages/math/src"), + "@excalidraw/utils": path.resolve(__dirname, "../packages/utils/src"), }, loader: { ".woff2": "file", diff --git a/scripts/buildUtils.js b/scripts/buildUtils.js index b5718f57e0..1cf3ffbaaf 100644 --- a/scripts/buildUtils.js +++ b/scripts/buildUtils.js @@ -10,13 +10,15 @@ const getConfig = (outdir) => ({ outdir, bundle: true, format: "esm", - entryPoints: ["index.ts"], + entryPoints: ["src/index.ts"], entryNames: "[name]", assetNames: "[dir]/[name]", alias: { + "@excalidraw/common": path.resolve(__dirname, "../packages/common/src"), + "@excalidraw/element": path.resolve(__dirname, "../packages/element/src"), "@excalidraw/excalidraw": path.resolve(__dirname, "../packages/excalidraw"), - "@excalidraw/utils": path.resolve(__dirname, "../packages/utils"), - "@excalidraw/math": path.resolve(__dirname, "../packages/math"), + "@excalidraw/math": path.resolve(__dirname, "../packages/math/src"), + "@excalidraw/utils": path.resolve(__dirname, "../packages/utils/src"), }, }); @@ -49,10 +51,10 @@ function buildProd(config) { const createESMRawBuild = async () => { // development unminified build with source maps - buildDev(getConfig("dist/dev")); + await buildDev(getConfig("dist/dev")); // production minified build without sourcemaps - buildProd(getConfig("dist/prod")); + await buildProd(getConfig("dist/prod")); }; (async () => { diff --git a/tsconfig.json b/tsconfig.json index 3eded705f5..45a29dd618 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,12 +19,16 @@ "jsx": "react-jsx", "baseUrl": ".", "paths": { + "@excalidraw/common": ["./packages/common/src/index.ts"], + "@excalidraw/common/*": ["./packages/common/src/*"], "@excalidraw/excalidraw": ["./packages/excalidraw/index.tsx"], - "@excalidraw/utils": ["./packages/utils/index.ts"], - "@excalidraw/math": ["./packages/math/index.ts"], "@excalidraw/excalidraw/*": ["./packages/excalidraw/*"], - "@excalidraw/utils/*": ["./packages/utils/*"], - "@excalidraw/math/*": ["./packages/math/*"] + "@excalidraw/element": ["./packages/element/src/index.ts"], + "@excalidraw/element/*": ["./packages/element/src/*"], + "@excalidraw/math": ["./packages/math/src/index.ts"], + "@excalidraw/math/*": ["./packages/math/src/*"], + "@excalidraw/utils": ["./packages/utils/src/index.ts"], + "@excalidraw/utils/*": ["./packages/utils/src/*"] } }, "include": ["packages", "excalidraw-app"], diff --git a/vitest.config.mts b/vitest.config.mts index f9d7d255ee..353f84ccfc 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -5,6 +5,22 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ resolve: { alias: [ + { + find: /^@excalidraw\/common$/, + replacement: path.resolve(__dirname, "./packages/common/src/index.ts"), + }, + { + find: /^@excalidraw\/common\/(.*?)/, + replacement: path.resolve(__dirname, "./packages/common/src/$1"), + }, + { + find: /^@excalidraw\/element$/, + replacement: path.resolve(__dirname, "./packages/element/src/index.ts"), + }, + { + find: /^@excalidraw\/element\/(.*?)/, + replacement: path.resolve(__dirname, "./packages/element/src/$1"), + }, { find: /^@excalidraw\/excalidraw$/, replacement: path.resolve(__dirname, "./packages/excalidraw/index.tsx"), @@ -13,21 +29,21 @@ export default defineConfig({ find: /^@excalidraw\/excalidraw\/(.*?)/, replacement: path.resolve(__dirname, "./packages/excalidraw/$1"), }, - { - find: /^@excalidraw\/utils$/, - replacement: path.resolve(__dirname, "./packages/utils/index.ts"), - }, - { - find: /^@excalidraw\/utils\/(.*?)/, - replacement: path.resolve(__dirname, "./packages/utils/$1"), - }, { find: /^@excalidraw\/math$/, - replacement: path.resolve(__dirname, "./packages/math/index.ts"), + replacement: path.resolve(__dirname, "./packages/math/src/index.ts"), }, { find: /^@excalidraw\/math\/(.*?)/, - replacement: path.resolve(__dirname, "./packages/math/$1"), + replacement: path.resolve(__dirname, "./packages/math/src/$1"), + }, + { + find: /^@excalidraw\/utils$/, + replacement: path.resolve(__dirname, "./packages/utils/src/index.ts"), + }, + { + find: /^@excalidraw\/utils\/(.*?)/, + replacement: path.resolve(__dirname, "./packages/utils/src/$1"), }, ], },