Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/master' into aakansha/esm

Aakansha Doshi 1 gadu atpakaļ
vecāks
revīzija
5af532d229
100 mainītis faili ar 350 papildinājumiem un 291 dzēšanām
  1. 7 0
      .dockerignore
  2. 2 1
      .eslintrc.json
  3. 7 5
      Dockerfile
  4. 1 1
      examples/excalidraw/components/App.tsx
  5. 1 1
      examples/excalidraw/components/MobileFooter.tsx
  6. 1 1
      examples/excalidraw/utils.ts
  7. 7 10
      excalidraw-app/App.tsx
  8. 2 2
      excalidraw-app/CustomStats.tsx
  9. 9 7
      excalidraw-app/collab/Collab.tsx
  10. 5 5
      excalidraw-app/collab/Portal.tsx
  11. 3 3
      excalidraw-app/components/AppMainMenu.tsx
  12. 2 2
      excalidraw-app/components/AppWelcomeScreen.tsx
  13. 2 2
      excalidraw-app/components/ExportToExcalidrawPlus.tsx
  14. 1 1
      excalidraw-app/components/GitHubCorner.tsx
  15. 2 2
      excalidraw-app/data/FileManager.ts
  16. 5 5
      excalidraw-app/data/LocalData.ts
  17. 6 5
      excalidraw-app/data/firebase.ts
  18. 6 6
      excalidraw-app/data/index.ts
  19. 2 2
      excalidraw-app/data/localStorage.ts
  20. 4 0
      excalidraw-app/index.scss
  21. 2 1
      excalidraw-app/share/ShareDialog.tsx
  22. 6 7
      excalidraw-app/tests/__snapshots__/MobileMenu.test.tsx.snap
  23. 1 1
      excalidraw-app/useHandleAppTheme.ts
  24. 3 3
      package.json
  25. 4 3
      packages/excalidraw/actions/actionAlign.tsx
  26. 3 3
      packages/excalidraw/actions/actionBoundText.tsx
  27. 3 3
      packages/excalidraw/actions/actionCanvas.tsx
  28. 2 2
      packages/excalidraw/actions/actionDeleteSelected.tsx
  29. 4 3
      packages/excalidraw/actions/actionDistribute.tsx
  30. 3 3
      packages/excalidraw/actions/actionDuplicateSelection.tsx
  31. 1 1
      packages/excalidraw/actions/actionElementLock.ts
  32. 1 1
      packages/excalidraw/actions/actionExport.tsx
  33. 1 1
      packages/excalidraw/actions/actionFinalize.tsx
  34. 2 2
      packages/excalidraw/actions/actionFlip.ts
  35. 2 2
      packages/excalidraw/actions/actionFrame.ts
  36. 2 2
      packages/excalidraw/actions/actionGroup.tsx
  37. 7 5
      packages/excalidraw/actions/actionHistory.tsx
  38. 34 6
      packages/excalidraw/actions/actionLinearEditor.tsx
  39. 2 2
      packages/excalidraw/actions/actionNavigate.tsx
  40. 2 2
      packages/excalidraw/actions/actionProperties.tsx
  41. 1 1
      packages/excalidraw/actions/actionSelectAll.ts
  42. 1 1
      packages/excalidraw/actions/actionStyles.ts
  43. 1 1
      packages/excalidraw/actions/actionToggleGridMode.tsx
  44. 4 0
      packages/excalidraw/actions/actionZindex.tsx
  45. 6 3
      packages/excalidraw/actions/manager.tsx
  46. 1 1
      packages/excalidraw/actions/register.ts
  47. 2 2
      packages/excalidraw/actions/shortcuts.ts
  48. 8 5
      packages/excalidraw/actions/types.ts
  49. 3 2
      packages/excalidraw/align.ts
  50. 4 3
      packages/excalidraw/animated-trail.ts
  51. 1 1
      packages/excalidraw/appState.ts
  52. 6 10
      packages/excalidraw/change.ts
  53. 2 6
      packages/excalidraw/charts.test.ts
  54. 1 1
      packages/excalidraw/charts.ts
  55. 3 3
      packages/excalidraw/clients.ts
  56. 4 3
      packages/excalidraw/clipboard.ts
  57. 1 1
      packages/excalidraw/colors.ts
  58. 17 7
      packages/excalidraw/components/Actions.tsx
  59. 24 26
      packages/excalidraw/components/App.tsx
  60. 2 4
      packages/excalidraw/components/ColorPicker/ColorInput.tsx
  61. 6 7
      packages/excalidraw/components/ColorPicker/ColorPicker.tsx
  62. 3 3
      packages/excalidraw/components/ColorPicker/Picker.tsx
  63. 3 2
      packages/excalidraw/components/ColorPicker/PickerColorList.tsx
  64. 1 1
      packages/excalidraw/components/ColorPicker/PickerHeading.tsx
  65. 1 1
      packages/excalidraw/components/ColorPicker/ShadeList.tsx
  66. 1 1
      packages/excalidraw/components/ColorPicker/TopPicks.tsx
  67. 3 6
      packages/excalidraw/components/ColorPicker/colorPickerUtils.ts
  68. 4 5
      packages/excalidraw/components/ColorPicker/keyboardNavHandlers.ts
  69. 10 11
      packages/excalidraw/components/CommandPalette/CommandPalette.tsx
  70. 1 1
      packages/excalidraw/components/CommandPalette/defaultCommandPaletteItems.ts
  71. 3 3
      packages/excalidraw/components/CommandPalette/types.ts
  72. 2 1
      packages/excalidraw/components/ConfirmDialog.tsx
  73. 6 7
      packages/excalidraw/components/ContextMenu.tsx
  74. 1 1
      packages/excalidraw/components/DarkModeToggle.tsx
  75. 2 2
      packages/excalidraw/components/DefaultSidebar.tsx
  76. 1 1
      packages/excalidraw/components/DialogActionButton.tsx
  77. 2 2
      packages/excalidraw/components/EyeDropper.tsx
  78. 1 1
      packages/excalidraw/components/FollowMode/FollowMode.tsx
  79. 1 1
      packages/excalidraw/components/HintViewer.tsx
  80. 1 1
      packages/excalidraw/components/ImageExportDialog.tsx
  81. 3 2
      packages/excalidraw/components/InitializeApp.tsx
  82. 3 3
      packages/excalidraw/components/JSONExportDialog.tsx
  83. 1 1
      packages/excalidraw/components/LaserPointerButton.tsx
  84. 5 4
      packages/excalidraw/components/LayerUI.tsx
  85. 4 3
      packages/excalidraw/components/LibraryMenu.tsx
  86. 1 1
      packages/excalidraw/components/LibraryMenuBrowseButton.tsx
  87. 1 1
      packages/excalidraw/components/LibraryMenuControlButtons.tsx
  88. 3 2
      packages/excalidraw/components/LibraryMenuHeaderContent.tsx
  89. 1 1
      packages/excalidraw/components/LibraryMenuItems.tsx
  90. 5 4
      packages/excalidraw/components/LibraryMenuSection.tsx
  91. 3 2
      packages/excalidraw/components/LibraryUnit.tsx
  92. 1 1
      packages/excalidraw/components/LoadingMessage.tsx
  93. 1 1
      packages/excalidraw/components/LockButton.tsx
  94. 1 1
      packages/excalidraw/components/MagicButton.tsx
  95. 2 2
      packages/excalidraw/components/MagicSettings.tsx
  96. 3 3
      packages/excalidraw/components/MobileMenu.tsx
  97. 1 1
      packages/excalidraw/components/Modal.tsx
  98. 1 1
      packages/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.ts
  99. 4 3
      packages/excalidraw/components/PasteChartDialog.tsx
  100. 1 1
      packages/excalidraw/components/PenModeButton.tsx

+ 7 - 0
.dockerignore

@@ -4,8 +4,15 @@
 !.eslintrc.json
 !.npmrc
 !.prettierrc
+!excalidraw-app/
 !package.json
 !public/
 !packages/
 !tsconfig.json
 !yarn.lock
+
+# keep (sub)sub directories at the end to exclude from explicit included
+# e.g. ./packages/excalidraw/{dist,node_modules}
+**/build
+**/dist
+**/node_modules

+ 2 - 1
.eslintrc.json

@@ -2,6 +2,7 @@
   "extends": ["@excalidraw/eslint-config", "react-app"],
   "rules": {
     "import/no-anonymous-default-export": "off",
-    "no-restricted-globals": "off"
+    "no-restricted-globals": "off",
+    "@typescript-eslint/consistent-type-imports": ["error", { "prefer": "type-imports", "disallowTypeAnnotations": false, "fixStyle": "separate-type-imports" }]
   }
 }

+ 7 - 5
Dockerfile

@@ -2,16 +2,18 @@ FROM node:18 AS build
 
 WORKDIR /opt/node_app
 
-COPY package.json yarn.lock ./
-RUN yarn --ignore-optional --network-timeout 600000
+COPY . .
+
+# do not ignore optional dependencies:
+# Error: Cannot find module @rollup/rollup-linux-x64-gnu
+RUN yarn --network-timeout 600000
 
 ARG NODE_ENV=production
 
-COPY . .
 RUN yarn build:app:docker
 
-FROM nginx:1.21-alpine
+FROM nginx:1.24-alpine
 
-COPY --from=build /opt/node_app/build /usr/share/nginx/html
+COPY --from=build /opt/node_app/excalidraw-app/build /usr/share/nginx/html
 
 HEALTHCHECK CMD wget -q -O /dev/null http://localhost || exit 1

+ 1 - 1
examples/excalidraw/components/App.tsx

@@ -12,9 +12,9 @@ import type * as TExcalidraw from "@excalidraw/excalidraw";
 
 import { nanoid } from "nanoid";
 
+import type { ResolvablePromise } from "../utils";
 import {
   resolvablePromise,
-  ResolvablePromise,
   distance2d,
   fileOpen,
   withBatchedUpdates,

+ 1 - 1
examples/excalidraw/components/MobileFooter.tsx

@@ -1,4 +1,4 @@
-import { ExcalidrawImperativeAPI } from "@excalidraw/excalidraw/dist/excalidraw/types";
+import type { ExcalidrawImperativeAPI } from "@excalidraw/excalidraw/dist/excalidraw/types";
 import CustomFooter from "./CustomFooter";
 import type * as TExcalidraw from "@excalidraw/excalidraw";
 

+ 1 - 1
examples/excalidraw/utils.ts

@@ -1,6 +1,6 @@
 import { unstable_batchedUpdates } from "react-dom";
 import { fileOpen as _fileOpen } from "browser-fs-access";
-import type { MIME_TYPES } from "@excalidraw/excalidraw";
+import { MIME_TYPES } from "@excalidraw/excalidraw";
 import { AbortError } from "../../packages/excalidraw/errors";
 
 type FILE_EXTENSION = Exclude<keyof typeof MIME_TYPES, "binary">;

+ 7 - 10
excalidraw-app/App.tsx

@@ -13,7 +13,7 @@ import {
   VERSION_TIMEOUT,
 } from "../packages/excalidraw/constants";
 import { loadFromBlob } from "../packages/excalidraw/data/blob";
-import {
+import type {
   FileId,
   NonDeletedExcalidrawElement,
   OrderedExcalidrawElement,
@@ -29,20 +29,20 @@ import {
   StoreAction,
   reconcileElements,
 } from "../packages/excalidraw";
-import {
+import type {
   AppState,
   ExcalidrawImperativeAPI,
   BinaryFiles,
   ExcalidrawInitialDataState,
   UIAppState,
 } from "../packages/excalidraw/types";
+import type { ResolvablePromise } from "../packages/excalidraw/utils";
 import {
   debounce,
   getVersion,
   getFrame,
   isTestEnv,
   preventUnload,
-  ResolvablePromise,
   resolvablePromise,
   isRunningInIframe,
 } from "../packages/excalidraw/utils";
@@ -52,8 +52,8 @@ import {
   STORAGE_KEYS,
   SYNC_BROWSER_TABS_TIMEOUT,
 } from "./app_constants";
+import type { CollabAPI } from "./collab/Collab";
 import Collab, {
-  CollabAPI,
   collabAPIAtom,
   isCollaboratingAtom,
   isOfflineAtom,
@@ -69,11 +69,8 @@ import {
   importUsernameFromLocalStorage,
 } from "./data/localStorage";
 import CustomStats from "./CustomStats";
-import {
-  restore,
-  restoreAppState,
-  RestoredDataState,
-} from "../packages/excalidraw/data/restore";
+import type { RestoredDataState } from "../packages/excalidraw/data/restore";
+import { restore, restoreAppState } from "../packages/excalidraw/data/restore";
 import {
   ExportToExcalidrawPlus,
   exportToExcalidrawPlus,
@@ -101,7 +98,7 @@ import { useAtomWithInitialValue } from "../packages/excalidraw/jotai";
 import { appJotaiStore } from "./app-jotai";
 
 import "./index.scss";
-import { ResolutionType } from "../packages/excalidraw/utility-types";
+import type { ResolutionType } from "../packages/excalidraw/utility-types";
 import { ShareableLinkDialog } from "../packages/excalidraw/components/ShareableLinkDialog";
 import { openConfirmModal } from "../packages/excalidraw/components/OverwriteConfirm/OverwriteConfirmState";
 import { OverwriteConfirmDialog } from "../packages/excalidraw/components/OverwriteConfirm/OverwriteConfirm";

+ 2 - 2
excalidraw-app/CustomStats.tsx

@@ -7,8 +7,8 @@ import {
 import { DEFAULT_VERSION } from "../packages/excalidraw/constants";
 import { t } from "../packages/excalidraw/i18n";
 import { copyTextToSystemClipboard } from "../packages/excalidraw/clipboard";
-import { NonDeletedExcalidrawElement } from "../packages/excalidraw/element/types";
-import { UIAppState } from "../packages/excalidraw/types";
+import type { NonDeletedExcalidrawElement } from "../packages/excalidraw/element/types";
+import type { UIAppState } from "../packages/excalidraw/types";
 
 type StorageSizes = { scene: number; total: number };
 

+ 9 - 7
excalidraw-app/collab/Collab.tsx

@@ -1,13 +1,13 @@
 import throttle from "lodash.throttle";
 import { PureComponent } from "react";
-import {
+import type {
   ExcalidrawImperativeAPI,
   SocketId,
 } from "../../packages/excalidraw/types";
 import { ErrorDialog } from "../../packages/excalidraw/components/ErrorDialog";
 import { APP_NAME, ENV, EVENT } from "../../packages/excalidraw/constants";
-import { ImportedDataState } from "../../packages/excalidraw/data/types";
-import {
+import type { ImportedDataState } from "../../packages/excalidraw/data/types";
+import type {
   ExcalidrawElement,
   InitializedExcalidrawImageElement,
   OrderedExcalidrawElement,
@@ -19,7 +19,7 @@ import {
   zoomToFitBounds,
   reconcileElements,
 } from "../../packages/excalidraw";
-import { Collaborator, Gesture } from "../../packages/excalidraw/types";
+import type { Collaborator, Gesture } from "../../packages/excalidraw/types";
 import {
   assertNever,
   preventUnload,
@@ -36,12 +36,14 @@ import {
   SYNC_FULL_SCENE_INTERVAL_MS,
   WS_EVENTS,
 } from "../app_constants";
+import type {
+  SocketUpdateDataSource,
+  SyncableExcalidrawElement,
+} from "../data";
 import {
   generateCollaborationLinkData,
   getCollaborationLink,
   getSyncableElements,
-  SocketUpdateDataSource,
-  SyncableExcalidrawElement,
 } from "../data";
 import {
   isSavedToFirebase,
@@ -77,7 +79,7 @@ import { resetBrowserStateVersions } from "../data/tabSync";
 import { LocalData } from "../data/LocalData";
 import { atom } from "jotai";
 import { appJotaiStore } from "../app-jotai";
-import { Mutable, ValueOf } from "../../packages/excalidraw/utility-types";
+import type { Mutable, ValueOf } from "../../packages/excalidraw/utility-types";
 import { getVisibleSceneBounds } from "../../packages/excalidraw/element/bounds";
 import { withBatchedUpdates } from "../../packages/excalidraw/reactUtils";
 import { collabErrorIndicatorAtom } from "./CollabError";

+ 5 - 5
excalidraw-app/collab/Portal.tsx

@@ -1,15 +1,15 @@
-import {
-  isSyncableElement,
+import type {
   SocketUpdateData,
   SocketUpdateDataSource,
   SyncableExcalidrawElement,
 } from "../data";
+import { isSyncableElement } from "../data";
 
-import { TCollabClass } from "./Collab";
+import type { TCollabClass } from "./Collab";
 
-import { OrderedExcalidrawElement } from "../../packages/excalidraw/element/types";
+import type { OrderedExcalidrawElement } from "../../packages/excalidraw/element/types";
 import { WS_EVENTS, FILE_UPLOAD_TIMEOUT, WS_SUBTYPES } from "../app_constants";
-import {
+import type {
   OnUserFollowedPayload,
   SocketId,
   UserIdleState,

+ 3 - 3
excalidraw-app/components/AppMainMenu.tsx

@@ -1,9 +1,9 @@
 import React from "react";
 import {
-  arrowBarToLeftIcon,
+  loginIcon,
   ExcalLogo,
 } from "../../packages/excalidraw/components/icons";
-import { Theme } from "../../packages/excalidraw/element/types";
+import type { Theme } from "../../packages/excalidraw/element/types";
 import { MainMenu } from "../../packages/excalidraw/index";
 import { isExcalidrawPlusSignedUser } from "../app_constants";
 import { LanguageList } from "./LanguageList";
@@ -42,7 +42,7 @@ export const AppMainMenu: React.FC<{
       </MainMenu.ItemLink>
       <MainMenu.DefaultItems.Socials />
       <MainMenu.ItemLink
-        icon={arrowBarToLeftIcon}
+        icon={loginIcon}
         href={`${import.meta.env.VITE_APP_PLUS_APP}${
           isExcalidrawPlusSignedUser ? "" : "/sign-up"
         }?utm_source=signin&utm_medium=app&utm_content=hamburger`}

+ 2 - 2
excalidraw-app/components/AppWelcomeScreen.tsx

@@ -1,5 +1,5 @@
 import React from "react";
-import { arrowBarToLeftIcon } from "../../packages/excalidraw/components/icons";
+import { loginIcon } from "../../packages/excalidraw/components/icons";
 import { useI18n } from "../../packages/excalidraw/i18n";
 import { WelcomeScreen } from "../../packages/excalidraw/index";
 import { isExcalidrawPlusSignedUser } from "../app_constants";
@@ -61,7 +61,7 @@ export const AppWelcomeScreen: React.FC<{
                 import.meta.env.VITE_APP_PLUS_LP
               }/plus?utm_source=excalidraw&utm_medium=app&utm_content=welcomeScreenGuest`}
               shortcut={null}
-              icon={arrowBarToLeftIcon}
+              icon={loginIcon}
             >
               Sign up
             </WelcomeScreen.Center.MenuItemLink>

+ 2 - 2
excalidraw-app/components/ExportToExcalidrawPlus.tsx

@@ -3,11 +3,11 @@ import { Card } from "../../packages/excalidraw/components/Card";
 import { ToolButton } from "../../packages/excalidraw/components/ToolButton";
 import { serializeAsJSON } from "../../packages/excalidraw/data/json";
 import { loadFirebaseStorage, saveFilesToFirebase } from "../data/firebase";
-import {
+import type {
   FileId,
   NonDeletedExcalidrawElement,
 } from "../../packages/excalidraw/element/types";
-import {
+import type {
   AppState,
   BinaryFileData,
   BinaryFiles,

+ 1 - 1
excalidraw-app/components/GitHubCorner.tsx

@@ -1,7 +1,7 @@
 import oc from "open-color";
 import React from "react";
 import { THEME } from "../../packages/excalidraw/constants";
-import { Theme } from "../../packages/excalidraw/element/types";
+import type { Theme } from "../../packages/excalidraw/element/types";
 
 // https://github.com/tholman/github-corners
 export const GitHubCorner = React.memo(

+ 2 - 2
excalidraw-app/data/FileManager.ts

@@ -2,14 +2,14 @@ import { StoreAction } from "../../packages/excalidraw";
 import { compressData } from "../../packages/excalidraw/data/encode";
 import { newElementWith } from "../../packages/excalidraw/element/mutateElement";
 import { isInitializedImageElement } from "../../packages/excalidraw/element/typeChecks";
-import {
+import type {
   ExcalidrawElement,
   ExcalidrawImageElement,
   FileId,
   InitializedExcalidrawImageElement,
 } from "../../packages/excalidraw/element/types";
 import { t } from "../../packages/excalidraw/i18n";
-import {
+import type {
   BinaryFileData,
   BinaryFileMetadata,
   ExcalidrawImperativeAPI,

+ 5 - 5
excalidraw-app/data/LocalData.ts

@@ -20,19 +20,19 @@ import {
   get,
 } from "idb-keyval";
 import { clearAppStateForLocalStorage } from "../../packages/excalidraw/appState";
-import { LibraryPersistedData } from "../../packages/excalidraw/data/library";
-import { ImportedDataState } from "../../packages/excalidraw/data/types";
+import type { LibraryPersistedData } from "../../packages/excalidraw/data/library";
+import type { ImportedDataState } from "../../packages/excalidraw/data/types";
 import { clearElementsForLocalStorage } from "../../packages/excalidraw/element";
-import {
+import type {
   ExcalidrawElement,
   FileId,
 } from "../../packages/excalidraw/element/types";
-import {
+import type {
   AppState,
   BinaryFileData,
   BinaryFiles,
 } from "../../packages/excalidraw/types";
-import { MaybePromise } from "../../packages/excalidraw/utility-types";
+import type { MaybePromise } from "../../packages/excalidraw/utility-types";
 import { debounce } from "../../packages/excalidraw/utils";
 import { SAVE_TO_LOCAL_STORAGE_TIMEOUT, STORAGE_KEYS } from "../app_constants";
 import { FileManager } from "./FileManager";

+ 6 - 5
excalidraw-app/data/firebase.ts

@@ -1,13 +1,13 @@
 import { reconcileElements } from "../../packages/excalidraw";
-import {
+import type {
   ExcalidrawElement,
   FileId,
   OrderedExcalidrawElement,
 } from "../../packages/excalidraw/element/types";
 import { getSceneVersion } from "../../packages/excalidraw/element";
-import Portal from "../collab/Portal";
+import type Portal from "../collab/Portal";
 import { restoreElements } from "../../packages/excalidraw/data/restore";
-import {
+import type {
   AppState,
   BinaryFileData,
   BinaryFileMetadata,
@@ -20,8 +20,9 @@ import {
   decryptData,
 } from "../../packages/excalidraw/data/encryption";
 import { MIME_TYPES } from "../../packages/excalidraw/constants";
-import { getSyncableElements, SyncableExcalidrawElement } from ".";
-import { ResolutionType } from "../../packages/excalidraw/utility-types";
+import type { SyncableExcalidrawElement } from ".";
+import { getSyncableElements } from ".";
+import type { ResolutionType } from "../../packages/excalidraw/utility-types";
 import type { Socket } from "socket.io-client";
 import type { RemoteExcalidrawElement } from "../../packages/excalidraw/data/reconcile";
 

+ 6 - 6
excalidraw-app/data/index.ts

@@ -9,30 +9,30 @@ import {
 } from "../../packages/excalidraw/data/encryption";
 import { serializeAsJSON } from "../../packages/excalidraw/data/json";
 import { restore } from "../../packages/excalidraw/data/restore";
-import { ImportedDataState } from "../../packages/excalidraw/data/types";
-import { SceneBounds } from "../../packages/excalidraw/element/bounds";
+import type { ImportedDataState } from "../../packages/excalidraw/data/types";
+import type { SceneBounds } from "../../packages/excalidraw/element/bounds";
 import { isInvisiblySmallElement } from "../../packages/excalidraw/element/sizeHelpers";
 import { isInitializedImageElement } from "../../packages/excalidraw/element/typeChecks";
-import {
+import type {
   ExcalidrawElement,
   FileId,
   OrderedExcalidrawElement,
 } from "../../packages/excalidraw/element/types";
 import { t } from "../../packages/excalidraw/i18n";
-import {
+import type {
   AppState,
   BinaryFileData,
   BinaryFiles,
   SocketId,
   UserIdleState,
 } from "../../packages/excalidraw/types";
-import { MakeBrand } from "../../packages/excalidraw/utility-types";
+import type { MakeBrand } from "../../packages/excalidraw/utility-types";
 import { bytesToHexString } from "../../packages/excalidraw/utils";
+import type { WS_SUBTYPES } from "../app_constants";
 import {
   DELETED_ELEMENT_TIMEOUT,
   FILE_UPLOAD_MAX_BYTES,
   ROOM_ID_BYTES,
-  WS_SUBTYPES,
 } from "../app_constants";
 import { encodeFilesForUpload } from "./FileManager";
 import { saveFilesToFirebase } from "./firebase";

+ 2 - 2
excalidraw-app/data/localStorage.ts

@@ -1,5 +1,5 @@
-import { ExcalidrawElement } from "../../packages/excalidraw/element/types";
-import { AppState } from "../../packages/excalidraw/types";
+import type { ExcalidrawElement } from "../../packages/excalidraw/element/types";
+import type { AppState } from "../../packages/excalidraw/types";
 import {
   clearAppStateForLocalStorage,
   getDefaultAppState,

+ 4 - 0
excalidraw-app/index.scss

@@ -40,6 +40,10 @@
       }
       &.highlighted {
         color: var(--color-promo);
+        font-weight: 700;
+        .dropdown-menu-item__icon g {
+          stroke-width: 2;
+        }
       }
     }
   }

+ 2 - 1
excalidraw-app/share/ShareDialog.tsx

@@ -18,7 +18,8 @@ import {
 } from "../../packages/excalidraw/components/icons";
 import { TextField } from "../../packages/excalidraw/components/TextField";
 import { FilledButton } from "../../packages/excalidraw/components/FilledButton";
-import { activeRoomLinkAtom, CollabAPI } from "../collab/Collab";
+import type { CollabAPI } from "../collab/Collab";
+import { activeRoomLinkAtom } from "../collab/Collab";
 import { atom, useAtom, useAtomValue } from "jotai";
 
 import "./ShareDialog.scss";

+ 6 - 7
excalidraw-app/tests/__snapshots__/MobileMenu.test.tsx.snap

@@ -216,23 +216,22 @@ exports[`Test MobileMenu > should initialize with welcome screen and hide once u
           stroke-width="2"
           viewBox="0 0 24 24"
         >
-          <g>
+          <g
+            stroke-width="1.5"
+          >
             <path
               d="M0 0h24v24H0z"
               fill="none"
               stroke="none"
             />
             <path
-              d="M10 12l10 0"
-            />
-            <path
-              d="M10 12l4 4"
+              d="M15 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2"
             />
             <path
-              d="M10 12l4 -4"
+              d="M21 12h-13l3 -3"
             />
             <path
-              d="M4 4l0 16"
+              d="M11 15l-3 -3"
             />
           </g>
         </svg>

+ 1 - 1
excalidraw-app/useHandleAppTheme.ts

@@ -2,7 +2,7 @@ import { atom, useAtom } from "jotai";
 import { useEffect, useLayoutEffect, useState } from "react";
 import { THEME } from "../packages/excalidraw";
 import { EVENT } from "../packages/excalidraw/constants";
-import { Theme } from "../packages/excalidraw/element/types";
+import type { Theme } from "../packages/excalidraw/element/types";
 import { CODES, KEYS } from "../packages/excalidraw/keys";
 import { STORAGE_KEYS } from "./app_constants";
 

+ 3 - 3
package.json

@@ -60,9 +60,9 @@
   "prettier": "@excalidraw/prettier-config",
   "scripts": {
     "build-node": "node ./scripts/build-node.js",
-    "build:app:docker": "cross-env VITE_APP_DISABLE_SENTRY=true VITE_APP_DISABLE_TRACKING=true vite build",
-    "build:app": "cross-env VITE_APP_GIT_SHA=$VERCEL_GIT_COMMIT_SHA vite build",
-    "build:version": "node ./scripts/build-version.js",
+    "build:app:docker": "yarn --cwd ./excalidraw-app build:app:docker",
+    "build:app": "yarn --cwd ./excalidraw-app build:app",
+    "build:version": "yarn --cwd ./excalidraw-app build:version",
     "build": "yarn workspace @excalidraw/utils build:esm && yarn --cwd ./excalidraw-app build",
     "clear:workspaces": "yarn workspace @excalidraw/utils run clear && yarn workspace @excalidraw/excalidraw run clear",
     "fix:code": "yarn test:code --fix",

+ 4 - 3
packages/excalidraw/actions/actionAlign.tsx

@@ -1,4 +1,5 @@
-import { alignElements, Alignment } from "../align";
+import type { Alignment } from "../align";
+import { alignElements } from "../align";
 import {
   AlignBottomIcon,
   AlignLeftIcon,
@@ -10,13 +11,13 @@ import {
 import { ToolButton } from "../components/ToolButton";
 import { getNonDeletedElements } from "../element";
 import { isFrameLikeElement } from "../element/typeChecks";
-import { ExcalidrawElement } from "../element/types";
+import type { ExcalidrawElement } from "../element/types";
 import { updateFrameMembershipOfSelectedElements } from "../frame";
 import { t } from "../i18n";
 import { KEYS } from "../keys";
 import { isSomeElementSelected } from "../scene";
 import { StoreAction } from "../store";
-import { AppClassProperties, AppState, UIAppState } from "../types";
+import type { AppClassProperties, AppState, UIAppState } from "../types";
 import { arrayToMap, getShortcutKey } from "../utils";
 import { register } from "./register";
 

+ 3 - 3
packages/excalidraw/actions/actionBoundText.tsx

@@ -23,14 +23,14 @@ import {
   isTextBindableContainer,
   isUsingAdaptiveRadius,
 } from "../element/typeChecks";
-import {
+import type {
   ExcalidrawElement,
   ExcalidrawLinearElement,
   ExcalidrawTextContainer,
   ExcalidrawTextElement,
 } from "../element/types";
-import { AppState } from "../types";
-import { Mutable } from "../utility-types";
+import type { AppState } from "../types";
+import type { Mutable } from "../utility-types";
 import { arrayToMap, getFontString } from "../utils";
 import { register } from "./register";
 import { syncMovedIndices } from "../fractionalIndex";

+ 3 - 3
packages/excalidraw/actions/actionCanvas.tsx

@@ -18,13 +18,13 @@ import {
   ZOOM_STEP,
 } from "../constants";
 import { getCommonBounds, getNonDeletedElements } from "../element";
-import { ExcalidrawElement } from "../element/types";
+import type { ExcalidrawElement } from "../element/types";
 import { t } from "../i18n";
 import { CODES, KEYS } from "../keys";
 import { getNormalizedZoom } from "../scene";
 import { centerScrollOn } from "../scene/scroll";
 import { getStateForZoom } from "../scene/zoom";
-import { AppState, NormalizedZoomValue } from "../types";
+import type { AppState, NormalizedZoomValue } from "../types";
 import { getShortcutKey, updateActiveTool } from "../utils";
 import { register } from "./register";
 import { Tooltip } from "../components/Tooltip";
@@ -35,7 +35,7 @@ import {
   isHandToolActive,
 } from "../appState";
 import { DEFAULT_CANVAS_BACKGROUND_PICKS } from "../colors";
-import { SceneBounds } from "../element/bounds";
+import type { SceneBounds } from "../element/bounds";
 import { setCursor } from "../cursor";
 import { StoreAction } from "../store";
 

+ 2 - 2
packages/excalidraw/actions/actionDeleteSelected.tsx

@@ -4,8 +4,8 @@ import { ToolButton } from "../components/ToolButton";
 import { t } from "../i18n";
 import { register } from "./register";
 import { getNonDeletedElements } from "../element";
-import { ExcalidrawElement } from "../element/types";
-import { AppState } from "../types";
+import type { ExcalidrawElement } from "../element/types";
+import type { AppState } from "../types";
 import { newElementWith } from "../element/mutateElement";
 import { getElementsInGroup } from "../groups";
 import { LinearElementEditor } from "../element/linearElementEditor";

+ 4 - 3
packages/excalidraw/actions/actionDistribute.tsx

@@ -3,16 +3,17 @@ import {
   DistributeVerticallyIcon,
 } from "../components/icons";
 import { ToolButton } from "../components/ToolButton";
-import { distributeElements, Distribution } from "../distribute";
+import type { Distribution } from "../distribute";
+import { distributeElements } from "../distribute";
 import { getNonDeletedElements } from "../element";
 import { isFrameLikeElement } from "../element/typeChecks";
-import { ExcalidrawElement } from "../element/types";
+import type { ExcalidrawElement } from "../element/types";
 import { updateFrameMembershipOfSelectedElements } from "../frame";
 import { t } from "../i18n";
 import { CODES, KEYS } from "../keys";
 import { isSomeElementSelected } from "../scene";
 import { StoreAction } from "../store";
-import { AppClassProperties, AppState } from "../types";
+import type { AppClassProperties, AppState } from "../types";
 import { arrayToMap, getShortcutKey } from "../utils";
 import { register } from "./register";
 

+ 3 - 3
packages/excalidraw/actions/actionDuplicateSelection.tsx

@@ -1,6 +1,6 @@
 import { KEYS } from "../keys";
 import { register } from "./register";
-import { ExcalidrawElement } from "../element/types";
+import type { ExcalidrawElement } from "../element/types";
 import { duplicateElement, getNonDeletedElements } from "../element";
 import { isSomeElementSelected } from "../scene";
 import { ToolButton } from "../components/ToolButton";
@@ -12,9 +12,9 @@ import {
   getSelectedGroupForElement,
   getElementsInGroup,
 } from "../groups";
-import { AppState } from "../types";
+import type { AppState } from "../types";
 import { fixBindingsAfterDuplication } from "../element/binding";
-import { ActionResult } from "./types";
+import type { ActionResult } from "./types";
 import { GRID_SIZE } from "../constants";
 import {
   bindTextToShapeAfterDuplication,

+ 1 - 1
packages/excalidraw/actions/actionElementLock.ts

@@ -1,7 +1,7 @@
 import { LockedIcon, UnlockedIcon } from "../components/icons";
 import { newElementWith } from "../element/mutateElement";
 import { isFrameLikeElement } from "../element/typeChecks";
-import { ExcalidrawElement } from "../element/types";
+import type { ExcalidrawElement } from "../element/types";
 import { KEYS } from "../keys";
 import { getSelectedElements } from "../scene";
 import { StoreAction } from "../store";

+ 1 - 1
packages/excalidraw/actions/actionExport.tsx

@@ -16,7 +16,7 @@ import { getSelectedElements, isSomeElementSelected } from "../scene";
 import { getNonDeletedElements } from "../element";
 import { isImageFileHandle } from "../data/blob";
 import { nativeFileSystemSupported } from "../data/filesystem";
-import { Theme } from "../element/types";
+import type { Theme } from "../element/types";
 
 import "../components/ToolIcon.scss";
 import { StoreAction } from "../store";

+ 1 - 1
packages/excalidraw/actions/actionFinalize.tsx

@@ -13,7 +13,7 @@ import {
   bindOrUnbindLinearElement,
 } from "../element/binding";
 import { isBindingElement, isLinearElement } from "../element/typeChecks";
-import { AppState } from "../types";
+import type { AppState } from "../types";
 import { resetCursor } from "../cursor";
 import { StoreAction } from "../store";
 

+ 2 - 2
packages/excalidraw/actions/actionFlip.ts

@@ -1,13 +1,13 @@
 import { register } from "./register";
 import { getSelectedElements } from "../scene";
 import { getNonDeletedElements } from "../element";
-import {
+import type {
   ExcalidrawElement,
   NonDeleted,
   NonDeletedSceneElementsMap,
 } from "../element/types";
 import { resizeMultipleElements } from "../element/resizeElements";
-import { AppClassProperties, AppState } from "../types";
+import type { AppClassProperties, AppState } from "../types";
 import { arrayToMap } from "../utils";
 import { CODES, KEYS } from "../keys";
 import { getCommonBoundingBox } from "../element/bounds";

+ 2 - 2
packages/excalidraw/actions/actionFrame.ts

@@ -1,9 +1,9 @@
 import { getNonDeletedElements } from "../element";
-import { ExcalidrawElement } from "../element/types";
+import type { ExcalidrawElement } from "../element/types";
 import { removeAllElementsFromFrame } from "../frame";
 import { getFrameChildren } from "../frame";
 import { KEYS } from "../keys";
-import { AppClassProperties, AppState, UIAppState } from "../types";
+import type { AppClassProperties, AppState, UIAppState } from "../types";
 import { updateActiveTool } from "../utils";
 import { setCursorForShape } from "../cursor";
 import { register } from "./register";

+ 2 - 2
packages/excalidraw/actions/actionGroup.tsx

@@ -17,12 +17,12 @@ import {
 import { getNonDeletedElements } from "../element";
 import { randomId } from "../random";
 import { ToolButton } from "../components/ToolButton";
-import {
+import type {
   ExcalidrawElement,
   ExcalidrawTextElement,
   OrderedExcalidrawElement,
 } from "../element/types";
-import { AppClassProperties, AppState } from "../types";
+import type { AppClassProperties, AppState } from "../types";
 import { isBoundToContainer } from "../element/typeChecks";
 import {
   getElementsInResizingFrame,

+ 7 - 5
packages/excalidraw/actions/actionHistory.tsx

@@ -1,14 +1,16 @@
-import { Action, ActionResult } from "./types";
+import type { Action, ActionResult } from "./types";
 import { UndoIcon, RedoIcon } from "../components/icons";
 import { ToolButton } from "../components/ToolButton";
 import { t } from "../i18n";
-import { History, HistoryChangedEvent } from "../history";
-import { AppState } from "../types";
+import type { History } from "../history";
+import { HistoryChangedEvent } from "../history";
+import type { AppState } from "../types";
 import { KEYS } from "../keys";
 import { arrayToMap } from "../utils";
 import { isWindows } from "../constants";
-import { SceneElementsMap } from "../element/types";
-import { Store, StoreAction } from "../store";
+import type { SceneElementsMap } from "../element/types";
+import type { Store } from "../store";
+import { StoreAction } from "../store";
 import { useEmitter } from "../hooks/useEmitter";
 
 const writeData = (

+ 34 - 6
packages/excalidraw/actions/actionLinearEditor.ts → packages/excalidraw/actions/actionLinearEditor.tsx

@@ -1,9 +1,12 @@
 import { DEFAULT_CATEGORIES } from "../components/CommandPalette/CommandPalette";
 import { LinearElementEditor } from "../element/linearElementEditor";
 import { isLinearElement } from "../element/typeChecks";
-import { ExcalidrawLinearElement } from "../element/types";
+import type { ExcalidrawLinearElement } from "../element/types";
 import { StoreAction } from "../store";
 import { register } from "./register";
+import { ToolButton } from "../components/ToolButton";
+import { t } from "../i18n";
+import { lineEditorIcon } from "../components/icons";
 
 export const actionToggleLinearEditor = register({
   name: "toggleLinearEditor",
@@ -11,18 +14,23 @@ export const actionToggleLinearEditor = register({
   label: (elements, appState, app) => {
     const selectedElement = app.scene.getSelectedElements({
       selectedElementIds: appState.selectedElementIds,
-      includeBoundTextElement: true,
-    })[0] as ExcalidrawLinearElement;
-    return appState.editingLinearElement?.elementId === selectedElement?.id
-      ? "labels.lineEditor.exit"
+    })[0] as ExcalidrawLinearElement | undefined;
+
+    return selectedElement?.type === "arrow"
+      ? "labels.lineEditor.editArrow"
       : "labels.lineEditor.edit";
   },
+  keywords: ["line"],
   trackEvent: {
     category: "element",
   },
   predicate: (elements, appState, _, app) => {
     const selectedElements = app.scene.getSelectedElements(appState);
-    if (selectedElements.length === 1 && isLinearElement(selectedElements[0])) {
+    if (
+      !appState.editingLinearElement &&
+      selectedElements.length === 1 &&
+      isLinearElement(selectedElements[0])
+    ) {
       return true;
     }
     return false;
@@ -45,4 +53,24 @@ export const actionToggleLinearEditor = register({
       storeAction: StoreAction.CAPTURE,
     };
   },
+  PanelComponent: ({ appState, updateData, app }) => {
+    const selectedElement = app.scene.getSelectedElements({
+      selectedElementIds: appState.selectedElementIds,
+    })[0] as ExcalidrawLinearElement;
+
+    const label = t(
+      selectedElement.type === "arrow"
+        ? "labels.lineEditor.editArrow"
+        : "labels.lineEditor.edit",
+    );
+    return (
+      <ToolButton
+        type="button"
+        icon={lineEditorIcon}
+        title={label}
+        aria-label={label}
+        onClick={() => updateData(null)}
+      />
+    );
+  },
 });

+ 2 - 2
packages/excalidraw/actions/actionNavigate.tsx

@@ -1,6 +1,6 @@
 import { getClientColor } from "../clients";
 import { Avatar } from "../components/Avatar";
-import { GoToCollaboratorComponentProps } from "../components/UserList";
+import type { GoToCollaboratorComponentProps } from "../components/UserList";
 import {
   eyeIcon,
   microphoneIcon,
@@ -8,7 +8,7 @@ import {
 } from "../components/icons";
 import { t } from "../i18n";
 import { StoreAction } from "../store";
-import { Collaborator } from "../types";
+import type { Collaborator } from "../types";
 import { register } from "./register";
 import clsx from "clsx";
 

+ 2 - 2
packages/excalidraw/actions/actionProperties.tsx

@@ -1,4 +1,4 @@
-import { AppClassProperties, AppState, Primitive } from "../types";
+import type { AppClassProperties, AppState, Primitive } from "../types";
 import {
   DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE,
   DEFAULT_ELEMENT_BACKGROUND_PICKS,
@@ -74,7 +74,7 @@ import {
   isLinearElement,
   isUsingAdaptiveRadius,
 } from "../element/typeChecks";
-import {
+import type {
   Arrowhead,
   ExcalidrawElement,
   ExcalidrawLinearElement,

+ 1 - 1
packages/excalidraw/actions/actionSelectAll.ts

@@ -2,7 +2,7 @@ import { KEYS } from "../keys";
 import { register } from "./register";
 import { selectGroupsForSelectedElements } from "../groups";
 import { getNonDeletedElements, isTextElement } from "../element";
-import { ExcalidrawElement } from "../element/types";
+import type { ExcalidrawElement } from "../element/types";
 import { isLinearElement } from "../element/typeChecks";
 import { LinearElementEditor } from "../element/linearElementEditor";
 import { excludeElementsInFramesFromSelection } from "../scene/selection";

+ 1 - 1
packages/excalidraw/actions/actionStyles.ts

@@ -24,7 +24,7 @@ import {
   isArrowElement,
 } from "../element/typeChecks";
 import { getSelectedElements } from "../scene";
-import { ExcalidrawTextElement } from "../element/types";
+import type { ExcalidrawTextElement } from "../element/types";
 import { paintIcon } from "../components/icons";
 import { StoreAction } from "../store";
 

+ 1 - 1
packages/excalidraw/actions/actionToggleGridMode.tsx

@@ -1,7 +1,7 @@
 import { CODES, KEYS } from "../keys";
 import { register } from "./register";
 import { GRID_SIZE } from "../constants";
-import { AppState } from "../types";
+import type { AppState } from "../types";
 import { gridIcon } from "../components/icons";
 import { StoreAction } from "../store";
 

+ 4 - 0
packages/excalidraw/actions/actionZindex.tsx

@@ -20,6 +20,7 @@ import { StoreAction } from "../store";
 export const actionSendBackward = register({
   name: "sendBackward",
   label: "labels.sendBackward",
+  keywords: ["move down", "zindex", "layer"],
   icon: SendBackwardIcon,
   trackEvent: { category: "element" },
   perform: (elements, appState) => {
@@ -49,6 +50,7 @@ export const actionSendBackward = register({
 export const actionBringForward = register({
   name: "bringForward",
   label: "labels.bringForward",
+  keywords: ["move up", "zindex", "layer"],
   icon: BringForwardIcon,
   trackEvent: { category: "element" },
   perform: (elements, appState) => {
@@ -78,6 +80,7 @@ export const actionBringForward = register({
 export const actionSendToBack = register({
   name: "sendToBack",
   label: "labels.sendToBack",
+  keywords: ["move down", "zindex", "layer"],
   icon: SendToBackIcon,
   trackEvent: { category: "element" },
   perform: (elements, appState) => {
@@ -114,6 +117,7 @@ export const actionSendToBack = register({
 export const actionBringToFront = register({
   name: "bringToFront",
   label: "labels.bringToFront",
+  keywords: ["move up", "zindex", "layer"],
   icon: BringToFrontIcon,
   trackEvent: { category: "element" },
 

+ 6 - 3
packages/excalidraw/actions/manager.tsx

@@ -1,5 +1,5 @@
 import React from "react";
-import {
+import type {
   Action,
   UpdaterFn,
   ActionName,
@@ -7,8 +7,11 @@ import {
   PanelComponentProps,
   ActionSource,
 } from "./types";
-import { ExcalidrawElement, OrderedExcalidrawElement } from "../element/types";
-import { AppClassProperties, AppState } from "../types";
+import type {
+  ExcalidrawElement,
+  OrderedExcalidrawElement,
+} from "../element/types";
+import type { AppClassProperties, AppState } from "../types";
 import { trackEvent } from "../analytics";
 import { isPromiseLike } from "../utils";
 

+ 1 - 1
packages/excalidraw/actions/register.ts

@@ -1,4 +1,4 @@
-import { Action } from "./types";
+import type { Action } from "./types";
 
 export let actions: readonly Action[] = [];
 

+ 2 - 2
packages/excalidraw/actions/shortcuts.ts

@@ -1,8 +1,8 @@
 import { isDarwin } from "../constants";
 import { t } from "../i18n";
-import { SubtypeOf } from "../utility-types";
+import type { SubtypeOf } from "../utility-types";
 import { getShortcutKey } from "../utils";
-import { ActionName } from "./types";
+import type { ActionName } from "./types";
 
 export type ShortcutName =
   | SubtypeOf<

+ 8 - 5
packages/excalidraw/actions/types.ts

@@ -1,14 +1,17 @@
-import React from "react";
-import { ExcalidrawElement, OrderedExcalidrawElement } from "../element/types";
-import {
+import type React from "react";
+import type {
+  ExcalidrawElement,
+  OrderedExcalidrawElement,
+} from "../element/types";
+import type {
   AppClassProperties,
   AppState,
   ExcalidrawProps,
   BinaryFiles,
   UIAppState,
 } from "../types";
-import { MarkOptional } from "../utility-types";
-import { StoreActionType } from "../store";
+import type { MarkOptional } from "../utility-types";
+import type { StoreActionType } from "../store";
 
 export type ActionSource =
   | "ui"

+ 3 - 2
packages/excalidraw/align.ts

@@ -1,6 +1,7 @@
-import { ElementsMap, ExcalidrawElement } from "./element/types";
+import type { ElementsMap, ExcalidrawElement } from "./element/types";
 import { newElementWith } from "./element/mutateElement";
-import { BoundingBox, getCommonBoundingBox } from "./element/bounds";
+import type { BoundingBox } from "./element/bounds";
+import { getCommonBoundingBox } from "./element/bounds";
 import { getMaximumGroups } from "./groups";
 
 export interface Alignment {

+ 4 - 3
packages/excalidraw/animated-trail.ts

@@ -1,6 +1,7 @@
-import { LaserPointer, LaserPointerOptions } from "@excalidraw/laser-pointer";
-import { AnimationFrameHandler } from "./animation-frame-handler";
-import { AppState } from "./types";
+import type { LaserPointerOptions } from "@excalidraw/laser-pointer";
+import { LaserPointer } from "@excalidraw/laser-pointer";
+import type { AnimationFrameHandler } from "./animation-frame-handler";
+import type { AppState } from "./types";
 import { getSvgPathFromStroke, sceneCoordsToViewportCoords } from "./utils";
 import type App from "./components/App";
 import { SVG_NS } from "./constants";

+ 1 - 1
packages/excalidraw/appState.ts

@@ -7,7 +7,7 @@ import {
   EXPORT_SCALES,
   THEME,
 } from "./constants";
-import { AppState, NormalizedZoomValue } from "./types";
+import type { AppState, NormalizedZoomValue } from "./types";
 
 const defaultExportScale = EXPORT_SCALES.includes(devicePixelRatio)
   ? devicePixelRatio

+ 6 - 10
packages/excalidraw/change.ts

@@ -1,18 +1,14 @@
 import { ENV } from "./constants";
+import type { BindableProp, BindingProp } from "./element/binding";
 import {
   BoundElement,
   BindableElement,
-  BindableProp,
-  BindingProp,
   bindingProperties,
   updateBoundElements,
 } from "./element/binding";
 import { LinearElementEditor } from "./element/linearElementEditor";
-import {
-  ElementUpdate,
-  mutateElement,
-  newElementWith,
-} from "./element/mutateElement";
+import type { ElementUpdate } from "./element/mutateElement";
+import { mutateElement, newElementWith } from "./element/mutateElement";
 import {
   getBoundTextElementId,
   redrawTextBoundingBox,
@@ -23,7 +19,7 @@ import {
   isBoundToContainer,
   isTextElement,
 } from "./element/typeChecks";
-import {
+import type {
   ExcalidrawElement,
   ExcalidrawLinearElement,
   ExcalidrawTextElement,
@@ -34,13 +30,13 @@ import {
 import { orderByFractionalIndex, syncMovedIndices } from "./fractionalIndex";
 import { getNonDeletedGroupIds } from "./groups";
 import { getObservedAppState } from "./store";
-import {
+import type {
   AppState,
   ObservedAppState,
   ObservedElementsAppState,
   ObservedStandaloneAppState,
 } from "./types";
-import { SubtypeOf, ValueOf } from "./utility-types";
+import type { SubtypeOf, ValueOf } from "./utility-types";
 import {
   arrayToMap,
   arrayToObject,

+ 2 - 6
packages/excalidraw/charts.test.ts

@@ -1,9 +1,5 @@
-import {
-  Spreadsheet,
-  tryParseCells,
-  tryParseNumber,
-  VALID_SPREADSHEET,
-} from "./charts";
+import type { Spreadsheet } from "./charts";
+import { tryParseCells, tryParseNumber, VALID_SPREADSHEET } from "./charts";
 
 describe("charts", () => {
   describe("tryParseNumber", () => {

+ 1 - 1
packages/excalidraw/charts.ts

@@ -9,7 +9,7 @@ import {
   VERTICAL_ALIGN,
 } from "./constants";
 import { newElement, newLinearElement, newTextElement } from "./element";
-import { NonDeletedExcalidrawElement } from "./element/types";
+import type { NonDeletedExcalidrawElement } from "./element/types";
 import { randomId } from "./random";
 
 export type ChartElements = readonly NonDeletedExcalidrawElement[];

+ 3 - 3
packages/excalidraw/clients.ts

@@ -5,13 +5,13 @@ import {
   THEME,
 } from "./constants";
 import { roundRect } from "./renderer/roundRect";
-import { InteractiveCanvasRenderConfig } from "./scene/types";
-import {
+import type { InteractiveCanvasRenderConfig } from "./scene/types";
+import type {
   Collaborator,
   InteractiveCanvasAppState,
   SocketId,
-  UserIdleState,
 } from "./types";
+import { UserIdleState } from "./types";
 
 function hashToInteger(id: string) {
   let hash = 0;

+ 4 - 3
packages/excalidraw/clipboard.ts

@@ -1,9 +1,10 @@
-import {
+import type {
   ExcalidrawElement,
   NonDeletedExcalidrawElement,
 } from "./element/types";
-import { BinaryFiles } from "./types";
-import { tryParseSpreadsheet, Spreadsheet, VALID_SPREADSHEET } from "./charts";
+import type { BinaryFiles } from "./types";
+import type { Spreadsheet } from "./charts";
+import { tryParseSpreadsheet, VALID_SPREADSHEET } from "./charts";
 import {
   ALLOWED_PASTE_MIME_TYPES,
   EXPORT_DATA_TYPES,

+ 1 - 1
packages/excalidraw/colors.ts

@@ -1,5 +1,5 @@
 import oc from "open-color";
-import { Merge } from "./utility-types";
+import type { Merge } from "./utility-types";
 
 // FIXME can't put to utils.ts rn because of circular dependency
 const pick = <R extends Record<string, any>, K extends readonly (keyof R)[]>(

+ 17 - 7
packages/excalidraw/components/Actions.tsx

@@ -1,6 +1,6 @@
 import { useState } from "react";
-import { ActionManager } from "../actions/manager";
-import {
+import type { ActionManager } from "../actions/manager";
+import type {
   ExcalidrawElement,
   ExcalidrawElementType,
   NonDeletedElementsMap,
@@ -17,13 +17,17 @@ import {
   hasStrokeWidth,
 } from "../scene";
 import { SHAPES } from "../shapes";
-import { AppClassProperties, AppProps, UIAppState, Zoom } from "../types";
+import type { AppClassProperties, AppProps, UIAppState, Zoom } from "../types";
 import { capitalizeString, isTransparent } from "../utils";
 import Stack from "./Stack";
 import { ToolButton } from "./ToolButton";
 import { hasStrokeColor } from "../scene/comparisons";
 import { trackEvent } from "../analytics";
-import { hasBoundTextElement, isTextElement } from "../element/typeChecks";
+import {
+  hasBoundTextElement,
+  isLinearElement,
+  isTextElement,
+} from "../element/typeChecks";
 import clsx from "clsx";
 import { actionToggleZenMode } from "../actions";
 import { Tooltip } from "./Tooltip";
@@ -114,6 +118,11 @@ export const SelectedShapeActions = ({
   const showLinkIcon =
     targetElements.length === 1 || isSingleElementBoundContainer;
 
+  const showLineEditorAction =
+    !appState.editingLinearElement &&
+    targetElements.length === 1 &&
+    isLinearElement(targetElements[0]);
+
   return (
     <div className="panelColumn">
       <div>
@@ -173,8 +182,8 @@ export const SelectedShapeActions = ({
         <div className="buttonList">
           {renderAction("sendToBack")}
           {renderAction("sendBackward")}
-          {renderAction("bringToFront")}
           {renderAction("bringForward")}
+          {renderAction("bringToFront")}
         </div>
       </fieldset>
 
@@ -229,6 +238,7 @@ export const SelectedShapeActions = ({
             {renderAction("group")}
             {renderAction("ungroup")}
             {showLinkIcon && renderAction("hyperlink")}
+            {showLineEditorAction && renderAction("toggleLinearEditor")}
           </div>
         </fieldset>
       )}
@@ -333,8 +343,8 @@ export const ShapesSwitcher = ({
                 fontSize: 8,
                 fontFamily: "Cascadia, monospace",
                 position: "absolute",
-                background: "pink",
-                color: "black",
+                background: "var(--color-promo)",
+                color: "var(--color-surface-lowest)",
                 bottom: 3,
                 right: 4,
               }}

+ 24 - 26
packages/excalidraw/components/App.tsx

@@ -1,7 +1,7 @@
 import React, { useContext } from "react";
 import { flushSync } from "react-dom";
 
-import { RoughCanvas } from "roughjs/bin/canvas";
+import type { RoughCanvas } from "roughjs/bin/canvas";
 import rough from "roughjs/bin/rough";
 import clsx from "clsx";
 import { nanoid } from "nanoid";
@@ -39,18 +39,16 @@ import {
 import { createRedoAction, createUndoAction } from "../actions/actionHistory";
 import { ActionManager } from "../actions/manager";
 import { actions } from "../actions/register";
-import { Action, ActionResult } from "../actions/types";
+import type { Action, ActionResult } from "../actions/types";
 import { trackEvent } from "../analytics";
 import {
   getDefaultAppState,
   isEraserActive,
   isHandToolActive,
 } from "../appState";
-import {
-  PastedMixedContent,
-  copyTextToSystemClipboard,
-  parseClipboard,
-} from "../clipboard";
+import type { PastedMixedContent } from "../clipboard";
+import { copyTextToSystemClipboard, parseClipboard } from "../clipboard";
+import type { EXPORT_IMAGE_TYPES } from "../constants";
 import {
   APP_NAME,
   CURSOR_TYPE,
@@ -62,7 +60,6 @@ import {
   ENV,
   EVENT,
   FRAME_STYLE,
-  EXPORT_IMAGE_TYPES,
   GRID_SIZE,
   IMAGE_MIME_TYPES,
   IMAGE_RENDER_TIMEOUT,
@@ -92,7 +89,8 @@ import {
   supportsResizeObserver,
   DEFAULT_COLLISION_THRESHOLD,
 } from "../constants";
-import { ExportedElements, exportCanvas, loadFromBlob } from "../data";
+import type { ExportedElements } from "../data";
+import { exportCanvas, loadFromBlob } from "../data";
 import Library, { distributeLibraryItemsOnSquareGrid } from "../data/library";
 import { restore, restoreElements } from "../data/restore";
 import {
@@ -163,7 +161,7 @@ import {
   isMagicFrameElement,
   isTextBindableContainer,
 } from "../element/typeChecks";
-import {
+import type {
   ExcalidrawBindableElement,
   ExcalidrawElement,
   ExcalidrawFreeDrawElement,
@@ -220,20 +218,23 @@ import {
   isSomeElementSelected,
 } from "../scene";
 import Scene from "../scene/Scene";
-import { RenderInteractiveSceneCallback, ScrollBars } from "../scene/types";
+import type {
+  RenderInteractiveSceneCallback,
+  ScrollBars,
+} from "../scene/types";
 import { getStateForZoom } from "../scene/zoom";
 import { findShapeByKey } from "../shapes";
+import type { GeometricShape } from "@excalidraw/utils";
 import {
-  GeometricShape,
   getClosedCurveShape,
   getCurveShape,
   getEllipseShape,
   getFreedrawShape,
   getPolygonShape,
   getSelectionBoxShape,
+  isPointInShape,
 } from "@excalidraw/utils";
-import { isPointInShape } from "@excalidraw/utils";
-import {
+import type {
   AppClassProperties,
   AppProps,
   AppState,
@@ -291,11 +292,8 @@ import {
   maybeParseEmbedSrc,
   getEmbedLink,
 } from "../element/embeddable";
-import {
-  ContextMenu,
-  ContextMenuItems,
-  CONTEXT_MENU_SEPARATOR,
-} from "./ContextMenu";
+import type { ContextMenuItems } from "./ContextMenu";
+import { ContextMenu, CONTEXT_MENU_SEPARATOR } from "./ContextMenu";
 import LayerUI from "./LayerUI";
 import { Toast } from "./Toast";
 import { actionToggleViewMode } from "../actions/actionToggleViewMode";
@@ -320,7 +318,8 @@ import {
   updateImageCache as _updateImageCache,
 } from "../element/image";
 import throttle from "lodash.throttle";
-import { fileOpen, FileSystemHandle } from "../data/filesystem";
+import type { FileSystemHandle } from "../data/filesystem";
+import { fileOpen } from "../data/filesystem";
 import {
   bindTextToShapeAfterDuplication,
   getApproxMinLineHeight,
@@ -386,11 +385,9 @@ import {
 import { actionWrapTextInContainer } from "../actions/actionBoundText";
 import BraveMeasureTextError from "./BraveMeasureTextError";
 import { activeEyeDropperAtom } from "./EyeDropper";
-import {
-  ExcalidrawElementSkeleton,
-  convertToExcalidrawElements,
-} from "../data/transform";
-import { ValueOf } from "../utility-types";
+import type { ExcalidrawElementSkeleton } from "../data/transform";
+import { convertToExcalidrawElements } from "../data/transform";
+import type { ValueOf } from "../utility-types";
 import { isSidebarDockedAtom } from "./Sidebar/Sidebar";
 import { StaticCanvas, InteractiveCanvas } from "./canvases";
 import { Renderer } from "../scene/Renderer";
@@ -404,7 +401,8 @@ import {
 } from "../cursor";
 import { Emitter } from "../emitter";
 import { ElementCanvasButtons } from "../element/ElementCanvasButtons";
-import { MagicCacheData, diagramToHTML } from "../data/magic";
+import type { MagicCacheData } from "../data/magic";
+import { diagramToHTML } from "../data/magic";
 import { exportToBlob } from "@excalidraw/utils";
 import { COLOR_PALETTE } from "../colors";
 import { ElementCanvasButton } from "./MagicButton";

+ 2 - 4
packages/excalidraw/components/ColorPicker/ColorInput.tsx

@@ -1,10 +1,8 @@
 import { useCallback, useEffect, useRef, useState } from "react";
 import { getColor } from "./ColorPicker";
 import { useAtom } from "jotai";
-import {
-  ColorPickerType,
-  activeColorPickerSectionAtom,
-} from "./colorPickerUtils";
+import type { ColorPickerType } from "./colorPickerUtils";
+import { activeColorPickerSectionAtom } from "./colorPickerUtils";
 import { eyeDropperIcon } from "../icons";
 import { jotaiScope } from "../../jotai";
 import { KEYS } from "../../keys";

+ 6 - 7
packages/excalidraw/components/ColorPicker/ColorPicker.tsx

@@ -1,16 +1,15 @@
 import { isInteractive, isTransparent, isWritableElement } from "../../utils";
-import { ExcalidrawElement } from "../../element/types";
-import { AppState } from "../../types";
+import type { ExcalidrawElement } from "../../element/types";
+import type { AppState } from "../../types";
 import { TopPicks } from "./TopPicks";
 import { Picker } from "./Picker";
 import * as Popover from "@radix-ui/react-popover";
 import { useAtom } from "jotai";
-import {
-  activeColorPickerSectionAtom,
-  ColorPickerType,
-} from "./colorPickerUtils";
+import type { ColorPickerType } from "./colorPickerUtils";
+import { activeColorPickerSectionAtom } from "./colorPickerUtils";
 import { useDevice, useExcalidrawContainer } from "../App";
-import { ColorTuple, COLOR_PALETTE, ColorPaletteCustom } from "../../colors";
+import type { ColorTuple, ColorPaletteCustom } from "../../colors";
+import { COLOR_PALETTE } from "../../colors";
 import PickerHeading from "./PickerHeading";
 import { t } from "../../i18n";
 import clsx from "clsx";

+ 3 - 3
packages/excalidraw/components/ColorPicker/Picker.tsx

@@ -1,7 +1,7 @@
 import React, { useEffect, useState } from "react";
 import { t } from "../../i18n";
 
-import { ExcalidrawElement } from "../../element/types";
+import type { ExcalidrawElement } from "../../element/types";
 import { ShadeList } from "./ShadeList";
 
 import PickerColorList from "./PickerColorList";
@@ -9,15 +9,15 @@ import { useAtom } from "jotai";
 import { CustomColorList } from "./CustomColorList";
 import { colorPickerKeyNavHandler } from "./keyboardNavHandlers";
 import PickerHeading from "./PickerHeading";
+import type { ColorPickerType } from "./colorPickerUtils";
 import {
-  ColorPickerType,
   activeColorPickerSectionAtom,
   getColorNameAndShadeFromColor,
   getMostUsedCustomColors,
   isCustomColor,
 } from "./colorPickerUtils";
+import type { ColorPaletteCustom } from "../../colors";
 import {
-  ColorPaletteCustom,
   DEFAULT_ELEMENT_BACKGROUND_COLOR_INDEX,
   DEFAULT_ELEMENT_STROKE_COLOR_INDEX,
 } from "../../colors";

+ 3 - 2
packages/excalidraw/components/ColorPicker/PickerColorList.tsx

@@ -7,8 +7,9 @@ import {
   getColorNameAndShadeFromColor,
 } from "./colorPickerUtils";
 import HotkeyLabel from "./HotkeyLabel";
-import { ColorPaletteCustom } from "../../colors";
-import { TranslationKeys, t } from "../../i18n";
+import type { ColorPaletteCustom } from "../../colors";
+import type { TranslationKeys } from "../../i18n";
+import { t } from "../../i18n";
 
 interface PickerColorListProps {
   palette: ColorPaletteCustom;

+ 1 - 1
packages/excalidraw/components/ColorPicker/PickerHeading.tsx

@@ -1,4 +1,4 @@
-import { ReactNode } from "react";
+import type { ReactNode } from "react";
 
 const PickerHeading = ({ children }: { children: ReactNode }) => (
   <div className="color-picker__heading">{children}</div>

+ 1 - 1
packages/excalidraw/components/ColorPicker/ShadeList.tsx

@@ -7,7 +7,7 @@ import {
 } from "./colorPickerUtils";
 import HotkeyLabel from "./HotkeyLabel";
 import { t } from "../../i18n";
-import { ColorPaletteCustom } from "../../colors";
+import type { ColorPaletteCustom } from "../../colors";
 
 interface ShadeListProps {
   hex: string;

+ 1 - 1
packages/excalidraw/components/ColorPicker/TopPicks.tsx

@@ -1,5 +1,5 @@
 import clsx from "clsx";
-import { ColorPickerType } from "./colorPickerUtils";
+import type { ColorPickerType } from "./colorPickerUtils";
 import {
   DEFAULT_CANVAS_BACKGROUND_PICKS,
   DEFAULT_ELEMENT_BACKGROUND_PICKS,

+ 3 - 6
packages/excalidraw/components/ColorPicker/colorPickerUtils.ts

@@ -1,10 +1,7 @@
-import { ExcalidrawElement } from "../../element/types";
+import type { ExcalidrawElement } from "../../element/types";
 import { atom } from "jotai";
-import {
-  ColorPickerColor,
-  ColorPaletteCustom,
-  MAX_CUSTOM_COLORS_USED_IN_CANVAS,
-} from "../../colors";
+import type { ColorPickerColor, ColorPaletteCustom } from "../../colors";
+import { MAX_CUSTOM_COLORS_USED_IN_CANVAS } from "../../colors";
 
 export const getColorNameAndShadeFromColor = ({
   palette,

+ 4 - 5
packages/excalidraw/components/ColorPicker/keyboardNavHandlers.ts

@@ -1,14 +1,13 @@
 import { KEYS } from "../../keys";
-import {
+import type {
   ColorPickerColor,
   ColorPalette,
   ColorPaletteCustom,
-  COLORS_PER_ROW,
-  COLOR_PALETTE,
 } from "../../colors";
-import { ValueOf } from "../../utility-types";
+import { COLORS_PER_ROW, COLOR_PALETTE } from "../../colors";
+import type { ValueOf } from "../../utility-types";
+import type { ActiveColorPickerSectionAtomType } from "./colorPickerUtils";
 import {
-  ActiveColorPickerSectionAtomType,
   colorPickerHotkeyBindings,
   getColorNameAndShadeFromColor,
 } from "./colorPickerUtils";

+ 10 - 11
packages/excalidraw/components/CommandPalette/CommandPalette.tsx

@@ -10,12 +10,11 @@ import { Dialog } from "../Dialog";
 import { TextField } from "../TextField";
 import clsx from "clsx";
 import { getSelectedElements } from "../../scene";
-import { Action } from "../../actions/types";
-import { TranslationKeys, t } from "../../i18n";
-import {
-  ShortcutName,
-  getShortcutFromShortcutName,
-} from "../../actions/shortcuts";
+import type { Action } from "../../actions/types";
+import type { TranslationKeys } from "../../i18n";
+import { t } from "../../i18n";
+import type { ShortcutName } from "../../actions/shortcuts";
+import { getShortcutFromShortcutName } from "../../actions/shortcuts";
 import { DEFAULT_SIDEBAR, EVENT } from "../../constants";
 import {
   LockedIcon,
@@ -31,7 +30,7 @@ import {
 } from "../icons";
 import fuzzy from "fuzzy";
 import { useUIAppState } from "../../context/ui-appState";
-import { AppProps, AppState, UIAppState } from "../../types";
+import type { AppProps, AppState, UIAppState } from "../../types";
 import {
   capitalizeString,
   getShortcutKey,
@@ -39,7 +38,7 @@ import {
 } from "../../utils";
 import { atom, useAtom } from "jotai";
 import { deburr } from "../../deburr";
-import { MarkRequired } from "../../utility-types";
+import type { MarkRequired } from "../../utility-types";
 import { InlineIcon } from "../InlineIcon";
 import { SHAPES } from "../../shapes";
 import { canChangeBackgroundColor, canChangeStrokeColor } from "../Actions";
@@ -47,7 +46,7 @@ import { useStableCallback } from "../../hooks/useStableCallback";
 import { actionClearCanvas, actionLink } from "../../actions";
 import { jotaiStore } from "../../jotai";
 import { activeConfirmDialogAtom } from "../ActiveConfirmDialog";
-import { CommandPaletteItem } from "./types";
+import type { CommandPaletteItem } from "./types";
 import * as defaultItems from "./defaultCommandPaletteItems";
 import { trackEvent } from "../../analytics";
 import { useStable } from "../../hooks/useStable";
@@ -258,10 +257,10 @@ function CommandPaletteInner({
         actionManager.actions.deleteSelectedElements,
         actionManager.actions.copyStyles,
         actionManager.actions.pasteStyles,
+        actionManager.actions.bringToFront,
+        actionManager.actions.bringForward,
         actionManager.actions.sendBackward,
         actionManager.actions.sendToBack,
-        actionManager.actions.bringForward,
-        actionManager.actions.bringToFront,
         actionManager.actions.alignTop,
         actionManager.actions.alignBottom,
         actionManager.actions.alignLeft,

+ 1 - 1
packages/excalidraw/components/CommandPalette/defaultCommandPaletteItems.ts

@@ -1,5 +1,5 @@
 import { actionToggleTheme } from "../../actions";
-import { CommandPaletteItem } from "./types";
+import type { CommandPaletteItem } from "./types";
 
 export const toggleTheme: CommandPaletteItem = {
   ...actionToggleTheme,

+ 3 - 3
packages/excalidraw/components/CommandPalette/types.ts

@@ -1,6 +1,6 @@
-import { ActionManager } from "../../actions/manager";
-import { Action } from "../../actions/types";
-import { UIAppState } from "../../types";
+import type { ActionManager } from "../../actions/manager";
+import type { Action } from "../../actions/types";
+import type { UIAppState } from "../../types";
 
 export type CommandPaletteItem = {
   label: string;

+ 2 - 1
packages/excalidraw/components/ConfirmDialog.tsx

@@ -1,5 +1,6 @@
 import { t } from "../i18n";
-import { Dialog, DialogProps } from "./Dialog";
+import type { DialogProps } from "./Dialog";
+import { Dialog } from "./Dialog";
 
 import "./ConfirmDialog.scss";
 import DialogActionButton from "./DialogActionButton";

+ 6 - 7
packages/excalidraw/components/ContextMenu.tsx

@@ -1,14 +1,13 @@
 import clsx from "clsx";
 import { Popover } from "./Popover";
-import { t, TranslationKeys } from "../i18n";
+import type { TranslationKeys } from "../i18n";
+import { t } from "../i18n";
 
 import "./ContextMenu.scss";
-import {
-  getShortcutFromShortcutName,
-  ShortcutName,
-} from "../actions/shortcuts";
-import { Action } from "../actions/types";
-import { ActionManager } from "../actions/manager";
+import type { ShortcutName } from "../actions/shortcuts";
+import { getShortcutFromShortcutName } from "../actions/shortcuts";
+import type { Action } from "../actions/types";
+import type { ActionManager } from "../actions/manager";
 import { useExcalidrawAppState, useExcalidrawElements } from "./App";
 import React from "react";
 

+ 1 - 1
packages/excalidraw/components/DarkModeToggle.tsx

@@ -3,7 +3,7 @@ import "./ToolIcon.scss";
 import { t } from "../i18n";
 import { ToolButton } from "./ToolButton";
 import { THEME } from "../constants";
-import { Theme } from "../element/types";
+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.

+ 2 - 2
packages/excalidraw/components/DefaultSidebar.tsx

@@ -3,12 +3,12 @@ import { DEFAULT_SIDEBAR, LIBRARY_SIDEBAR_TAB } from "../constants";
 import { useTunnels } from "../context/tunnels";
 import { useUIAppState } from "../context/ui-appState";
 import { t } from "../i18n";
-import { MarkOptional, Merge } from "../utility-types";
+import type { MarkOptional, Merge } from "../utility-types";
 import { composeEventHandlers } from "../utils";
 import { useExcalidrawSetAppState } from "./App";
 import { withInternalFallback } from "./hoc/withInternalFallback";
 import { LibraryMenu } from "./LibraryMenu";
-import { SidebarProps, SidebarTriggerProps } from "./Sidebar/common";
+import type { SidebarProps, SidebarTriggerProps } from "./Sidebar/common";
 import { Sidebar } from "./Sidebar/Sidebar";
 
 const DefaultSidebarTrigger = withInternalFallback(

+ 1 - 1
packages/excalidraw/components/DialogActionButton.tsx

@@ -1,5 +1,5 @@
 import clsx from "clsx";
-import { ReactNode } from "react";
+import type { ReactNode } from "react";
 import "./DialogActionButton.scss";
 import Spinner from "./Spinner";
 

+ 2 - 2
packages/excalidraw/components/EyeDropper.tsx

@@ -12,8 +12,8 @@ import { useApp, useExcalidrawContainer, useExcalidrawElements } from "./App";
 import { useStable } from "../hooks/useStable";
 
 import "./EyeDropper.scss";
-import { ColorPickerType } from "./ColorPicker/colorPickerUtils";
-import { ExcalidrawElement } from "../element/types";
+import type { ColorPickerType } from "./ColorPicker/colorPickerUtils";
+import type { ExcalidrawElement } from "../element/types";
 
 export type EyeDropperProperties = {
   keepOpenOnAlt: boolean;

+ 1 - 1
packages/excalidraw/components/FollowMode/FollowMode.tsx

@@ -1,4 +1,4 @@
-import { UserToFollow } from "../../types";
+import type { UserToFollow } from "../../types";
 import { CloseIcon } from "../icons";
 import "./FollowMode.scss";
 

+ 1 - 1
packages/excalidraw/components/HintViewer.tsx

@@ -1,5 +1,5 @@
 import { t } from "../i18n";
-import { AppClassProperties, Device, UIAppState } from "../types";
+import type { AppClassProperties, Device, UIAppState } from "../types";
 import {
   isImageElement,
   isLinearElement,

+ 1 - 1
packages/excalidraw/components/ImageExportDialog.tsx

@@ -20,7 +20,7 @@ import {
 
 import { canvasToBlob } from "../data/blob";
 import { nativeFileSystemSupported } from "../data/filesystem";
-import { NonDeletedExcalidrawElement } from "../element/types";
+import type { NonDeletedExcalidrawElement } from "../element/types";
 import { t } from "../i18n";
 import { isSomeElementSelected } from "../scene";
 import { exportToCanvas } from "@excalidraw/utils";

+ 3 - 2
packages/excalidraw/components/InitializeApp.tsx

@@ -1,8 +1,9 @@
 import React, { useEffect, useState } from "react";
 
 import { LoadingMessage } from "./LoadingMessage";
-import { defaultLang, Language, languages, setLanguage } from "../i18n";
-import { Theme } from "../element/types";
+import type { Language } from "../i18n";
+import { defaultLang, languages, setLanguage } from "../i18n";
+import type { Theme } from "../element/types";
 
 interface Props {
   langCode: Language["code"];

+ 3 - 3
packages/excalidraw/components/JSONExportDialog.tsx

@@ -1,8 +1,8 @@
 import React from "react";
-import { NonDeletedExcalidrawElement } from "../element/types";
+import type { NonDeletedExcalidrawElement } from "../element/types";
 import { t } from "../i18n";
 
-import { ExportOpts, BinaryFiles, UIAppState } from "../types";
+import type { ExportOpts, BinaryFiles, UIAppState } from "../types";
 import { Dialog } from "./Dialog";
 import { exportToFileIcon, LinkIcon } from "./icons";
 import { ToolButton } from "./ToolButton";
@@ -12,7 +12,7 @@ import { Card } from "./Card";
 import "./ExportDialog.scss";
 import { nativeFileSystemSupported } from "../data/filesystem";
 import { trackEvent } from "../analytics";
-import { ActionManager } from "../actions/manager";
+import type { ActionManager } from "../actions/manager";
 import { getFrame } from "../utils";
 
 export type ExportCB = (

+ 1 - 1
packages/excalidraw/components/LaserPointerButton.tsx

@@ -1,7 +1,7 @@
 import "./ToolIcon.scss";
 
 import clsx from "clsx";
-import { ToolButtonSize } from "./ToolButton";
+import type { ToolButtonSize } from "./ToolButton";
 import { laserPointerToolIcon } from "./icons";
 
 type LaserPointerIconProps = {

+ 5 - 4
packages/excalidraw/components/LayerUI.tsx

@@ -1,6 +1,6 @@
 import clsx from "clsx";
 import React from "react";
-import { ActionManager } from "../actions/manager";
+import type { ActionManager } from "../actions/manager";
 import {
   CLASSES,
   DEFAULT_SIDEBAR,
@@ -8,10 +8,11 @@ import {
   TOOL_TYPE,
 } from "../constants";
 import { showSelectedShapeActions } from "../element";
-import { NonDeletedExcalidrawElement } from "../element/types";
-import { Language, t } from "../i18n";
+import type { NonDeletedExcalidrawElement } from "../element/types";
+import type { Language } from "../i18n";
+import { t } from "../i18n";
 import { calculateScrollCenter } from "../scene";
-import {
+import type {
   AppProps,
   AppState,
   ExcalidrawProps,

+ 4 - 3
packages/excalidraw/components/LibraryMenu.tsx

@@ -1,11 +1,12 @@
 import React, { useState, useCallback, useMemo, useRef } from "react";
-import Library, {
+import type Library from "../data/library";
+import {
   distributeLibraryItemsOnSquareGrid,
   libraryItemsAtom,
 } from "../data/library";
 import { t } from "../i18n";
 import { randomId } from "../random";
-import {
+import type {
   LibraryItems,
   LibraryItem,
   ExcalidrawProps,
@@ -28,7 +29,7 @@ import { useUIAppState } from "../context/ui-appState";
 import "./LibraryMenu.scss";
 import { LibraryMenuControlButtons } from "./LibraryMenuControlButtons";
 import { isShallowEqual } from "../utils";
-import { NonDeletedExcalidrawElement } from "../element/types";
+import type { NonDeletedExcalidrawElement } from "../element/types";
 import { LIBRARY_DISABLED_TYPES } from "../constants";
 
 export const isLibraryMenuOpenAtom = atom(false);

+ 1 - 1
packages/excalidraw/components/LibraryMenuBrowseButton.tsx

@@ -1,6 +1,6 @@
 import { VERSIONS } from "../constants";
 import { t } from "../i18n";
-import { ExcalidrawProps, UIAppState } from "../types";
+import type { ExcalidrawProps, UIAppState } from "../types";
 
 const LibraryMenuBrowseButton = ({
   theme,

+ 1 - 1
packages/excalidraw/components/LibraryMenuControlButtons.tsx

@@ -1,4 +1,4 @@
-import { ExcalidrawProps, UIAppState } from "../types";
+import type { ExcalidrawProps, UIAppState } from "../types";
 import LibraryMenuBrowseButton from "./LibraryMenuBrowseButton";
 import clsx from "clsx";
 

+ 3 - 2
packages/excalidraw/components/LibraryMenuHeaderContent.tsx

@@ -2,10 +2,11 @@ import { useCallback, useState } from "react";
 import { t } from "../i18n";
 import Trans from "./Trans";
 import { jotaiScope } from "../jotai";
-import { LibraryItem, LibraryItems, UIAppState } from "../types";
+import type { LibraryItem, LibraryItems, UIAppState } from "../types";
 import { useApp, useExcalidrawSetAppState } from "./App";
 import { saveLibraryAsJSON } from "../data/json";
-import Library, { libraryItemsAtom } from "../data/library";
+import type Library from "../data/library";
+import { libraryItemsAtom } from "../data/library";
 import {
   DotsIcon,
   ExportIcon,

+ 1 - 1
packages/excalidraw/components/LibraryMenuItems.tsx

@@ -7,7 +7,7 @@ import React, {
 } from "react";
 import { serializeLibraryAsJSON } from "../data/json";
 import { t } from "../i18n";
-import {
+import type {
   ExcalidrawProps,
   LibraryItem,
   LibraryItems,

+ 5 - 4
packages/excalidraw/components/LibraryMenuSection.tsx

@@ -1,8 +1,9 @@
-import React, { memo, ReactNode, useEffect, useState } from "react";
+import type { ReactNode } from "react";
+import React, { memo, useEffect, useState } from "react";
 import { EmptyLibraryUnit, LibraryUnit } from "./LibraryUnit";
-import { LibraryItem } from "../types";
-import { ExcalidrawElement, NonDeleted } from "../element/types";
-import { SvgCache } from "../hooks/useLibraryItemSvg";
+import type { LibraryItem } from "../types";
+import type { ExcalidrawElement, NonDeleted } from "../element/types";
+import type { SvgCache } from "../hooks/useLibraryItemSvg";
 import { useTransition } from "../hooks/useTransition";
 
 type LibraryOrPendingItem = (

+ 3 - 2
packages/excalidraw/components/LibraryUnit.tsx

@@ -1,11 +1,12 @@
 import clsx from "clsx";
 import { memo, useEffect, useRef, useState } from "react";
 import { useDevice } from "./App";
-import { LibraryItem } from "../types";
+import type { LibraryItem } from "../types";
 import "./LibraryUnit.scss";
 import { CheckboxItem } from "./CheckboxItem";
 import { PlusIcon } from "./icons";
-import { SvgCache, useLibraryItemSvg } from "../hooks/useLibraryItemSvg";
+import type { SvgCache } from "../hooks/useLibraryItemSvg";
+import { useLibraryItemSvg } from "../hooks/useLibraryItemSvg";
 
 export const LibraryUnit = memo(
   ({

+ 1 - 1
packages/excalidraw/components/LoadingMessage.tsx

@@ -3,7 +3,7 @@ import { useState, useEffect } from "react";
 import Spinner from "./Spinner";
 import clsx from "clsx";
 import { THEME } from "../constants";
-import { Theme } from "../element/types";
+import type { Theme } from "../element/types";
 
 export const LoadingMessage: React.FC<{ delay?: number; theme?: Theme }> = ({
   delay,

+ 1 - 1
packages/excalidraw/components/LockButton.tsx

@@ -1,7 +1,7 @@
 import "./ToolIcon.scss";
 
 import clsx from "clsx";
-import { ToolButtonSize } from "./ToolButton";
+import type { ToolButtonSize } from "./ToolButton";
 import { LockedIcon, UnlockedIcon } from "./icons";
 
 type LockIconProps = {

+ 1 - 1
packages/excalidraw/components/MagicButton.tsx

@@ -1,7 +1,7 @@
 import "./ToolIcon.scss";
 
 import clsx from "clsx";
-import { ToolButtonSize } from "./ToolButton";
+import type { ToolButtonSize } from "./ToolButton";
 
 const DEFAULT_SIZE: ToolButtonSize = "small";
 

+ 2 - 2
packages/excalidraw/components/MagicSettings.tsx

@@ -53,8 +53,8 @@ export const MagicSettings = (props: {
               marginLeft: "1rem",
               fontSize: 14,
               borderRadius: "12px",
-              color: "#000",
-              background: "pink",
+              background: "var(--color-promo)",
+              color: "var(--color-surface-lowest)",
             }}
           >
             Experimental

+ 3 - 3
packages/excalidraw/components/MobileMenu.tsx

@@ -1,5 +1,5 @@
 import React from "react";
-import {
+import type {
   AppClassProperties,
   AppProps,
   AppState,
@@ -7,11 +7,11 @@ import {
   ExcalidrawProps,
   UIAppState,
 } from "../types";
-import { ActionManager } from "../actions/manager";
+import type { ActionManager } from "../actions/manager";
 import { t } from "../i18n";
 import Stack from "./Stack";
 import { showSelectedShapeActions } from "../element";
-import { NonDeletedExcalidrawElement } from "../element/types";
+import type { NonDeletedExcalidrawElement } from "../element/types";
 import { FixedSideContainer } from "./FixedSideContainer";
 import { Island } from "./Island";
 import { HintViewer } from "./HintViewer";

+ 1 - 1
packages/excalidraw/components/Modal.tsx

@@ -3,7 +3,7 @@ import "./Modal.scss";
 import { createPortal } from "react-dom";
 import clsx from "clsx";
 import { KEYS } from "../keys";
-import { AppState } from "../types";
+import type { AppState } from "../types";
 import { useCreatePortalContainer } from "../hooks/useCreatePortalContainer";
 import { useRef } from "react";
 

+ 1 - 1
packages/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.ts

@@ -1,6 +1,6 @@
 import { atom } from "jotai";
 import { jotaiStore } from "../../jotai";
-import React from "react";
+import type React from "react";
 
 export type OverwriteConfirmState =
   | {

+ 4 - 3
packages/excalidraw/components/PasteChartDialog.tsx

@@ -1,11 +1,12 @@
 import oc from "open-color";
 import React, { useLayoutEffect, useRef, useState } from "react";
 import { trackEvent } from "../analytics";
-import { ChartElements, renderSpreadsheet, Spreadsheet } from "../charts";
-import { ChartType } from "../element/types";
+import type { ChartElements, Spreadsheet } from "../charts";
+import { renderSpreadsheet } from "../charts";
+import type { ChartType } from "../element/types";
 import { t } from "../i18n";
 import { exportToSvg } from "../scene/export";
-import { UIAppState } from "../types";
+import type { UIAppState } from "../types";
 import { useApp } from "./App";
 import { Dialog } from "./Dialog";
 

+ 1 - 1
packages/excalidraw/components/PenModeButton.tsx

@@ -1,7 +1,7 @@
 import "./ToolIcon.scss";
 
 import clsx from "clsx";
-import { ToolButtonSize } from "./ToolButton";
+import type { ToolButtonSize } from "./ToolButton";
 import { PenModeIcon } from "./icons";
 
 type PenModeIconProps = {

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels