@dwelle/excalidraw 0.5.0-ef89e88 → 0.5.0-efddbb7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +111 -14
  3. package/dist/dev/{chunk-UPL5GSGP.js → chunk-AVAC6BVM.js} +11 -2
  4. package/dist/dev/chunk-AVAC6BVM.js.map +7 -0
  5. package/dist/dev/{chunk-VLJRILK3.js → chunk-OKDHCI5V.js} +1844 -1440
  6. package/dist/dev/chunk-OKDHCI5V.js.map +7 -0
  7. package/dist/dev/{chunk-H5SL5I5R.js → chunk-UEBEBUE2.js} +2 -2
  8. package/dist/dev/components/TTDDialog/{CodeMirrorEditor-65RQRK4A.js → CodeMirrorEditor-2YIEAZU7.js} +2 -2
  9. package/dist/dev/data/{image-JR54FB4B.js → image-O7OJXMIJ.js} +3 -3
  10. package/dist/dev/index.css +85 -43
  11. package/dist/dev/index.css.map +3 -3
  12. package/dist/dev/index.js +2939 -2010
  13. package/dist/dev/index.js.map +4 -4
  14. package/dist/dev/locales/{en-IZ5JJCQN.js → en-XVKSJYG2.js} +4 -2
  15. package/dist/dev/subset-shared.chunk.js +1 -1
  16. package/dist/dev/subset-worker.chunk.js +1 -1
  17. package/dist/prod/chunk-5EYFVTC7.js +34 -0
  18. package/dist/prod/{chunk-MYTKOPOQ.js → chunk-T6UH5ZKV.js} +5 -5
  19. package/dist/prod/{chunk-B47HEJUH.js → chunk-Y6NXDCR7.js} +1 -1
  20. package/dist/prod/components/TTDDialog/{CodeMirrorEditor-B64TEOC3.js → CodeMirrorEditor-JV2LT6ZS.js} +1 -1
  21. package/dist/prod/data/image-XRO5552B.js +1 -0
  22. package/dist/prod/index.css +1 -1
  23. package/dist/prod/index.js +28 -28
  24. package/dist/prod/locales/en-BNQNBQ43.js +1 -0
  25. package/dist/prod/subset-shared.chunk.js +1 -1
  26. package/dist/prod/subset-worker.chunk.js +1 -1
  27. package/dist/types/common/src/appEventBus.d.ts +27 -0
  28. package/dist/types/common/src/index.d.ts +2 -0
  29. package/dist/types/common/src/utils.d.ts +1 -3
  30. package/dist/types/common/src/versionedSnapshotStore.d.ts +17 -0
  31. package/dist/types/element/src/Scene.d.ts +5 -3
  32. package/dist/types/element/src/bounds.d.ts +4 -2
  33. package/dist/types/element/src/duplicate.d.ts +1 -0
  34. package/dist/types/element/src/frame.d.ts +7 -6
  35. package/dist/types/element/src/linearElementEditor.d.ts +2 -2
  36. package/dist/types/element/src/selection.d.ts +2 -2
  37. package/dist/types/element/src/shape.d.ts +1 -1
  38. package/dist/types/element/src/typeChecks.d.ts +1 -0
  39. package/dist/types/element/src/utils.d.ts +1 -1
  40. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +8 -8
  41. package/dist/types/excalidraw/actions/actionBoundText.d.ts +6 -6
  42. package/dist/types/excalidraw/actions/actionCanvas.d.ts +30 -30
  43. package/dist/types/excalidraw/actions/actionClipboard.d.ts +6 -6
  44. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +3 -3
  45. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +9 -9
  46. package/dist/types/excalidraw/actions/actionDeselect.d.ts +160 -0
  47. package/dist/types/excalidraw/actions/actionElementLink.d.ts +3 -3
  48. package/dist/types/excalidraw/actions/actionElementLock.d.ts +6 -6
  49. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +3 -3
  50. package/dist/types/excalidraw/actions/actionExport.d.ts +48 -323
  51. package/dist/types/excalidraw/actions/actionFrame.d.ts +12 -12
  52. package/dist/types/excalidraw/actions/actionGroup.d.ts +6 -6
  53. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +3 -3
  54. package/dist/types/excalidraw/actions/actionLink.d.ts +3 -3
  55. package/dist/types/excalidraw/actions/actionMenu.d.ts +3 -3
  56. package/dist/types/excalidraw/actions/actionProperties.d.ts +6 -6
  57. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +3 -3
  58. package/dist/types/excalidraw/actions/actionStyles.d.ts +2 -2
  59. package/dist/types/excalidraw/actions/actionToggleArrowBinding.d.ts +3 -3
  60. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +3 -3
  61. package/dist/types/excalidraw/actions/actionToggleMidpointSnapping.d.ts +3 -3
  62. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +3 -3
  63. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +3 -3
  64. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +3 -3
  65. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +3 -3
  66. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +3 -3
  67. package/dist/types/excalidraw/actions/index.d.ts +1 -0
  68. package/dist/types/excalidraw/actions/types.d.ts +1 -1
  69. package/dist/types/excalidraw/appState.d.ts +1 -0
  70. package/dist/types/excalidraw/clipboard.d.ts +2 -3
  71. package/dist/types/excalidraw/components/App.d.ts +41 -10
  72. package/dist/types/excalidraw/components/AppStateObserver.d.ts +37 -0
  73. package/dist/types/excalidraw/components/TTDDialog/utils/TTDStreamFetch.d.ts +1 -1
  74. package/dist/types/excalidraw/components/Toast.d.ts +8 -4
  75. package/dist/types/excalidraw/components/canvases/InteractiveCanvas.d.ts +1 -1
  76. package/dist/types/excalidraw/components/canvases/NewElementCanvas.d.ts +1 -0
  77. package/dist/types/excalidraw/components/canvases/StaticCanvas.d.ts +1 -1
  78. package/dist/types/excalidraw/components/dropdownMenu/DropdownMenuItemContentRadio.d.ts +2 -1
  79. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +1 -0
  80. package/dist/types/excalidraw/components/shapes.d.ts +7 -0
  81. package/dist/types/excalidraw/data/blob.d.ts +13 -14
  82. package/dist/types/excalidraw/data/filesystem.d.ts +3 -5
  83. package/dist/types/excalidraw/data/index.d.ts +2 -3
  84. package/dist/types/excalidraw/data/json.d.ts +21 -13
  85. package/dist/types/excalidraw/data/resave.d.ts +7 -2
  86. package/dist/types/excalidraw/hooks/useAppStateValue.d.ts +29 -0
  87. package/dist/types/excalidraw/index.d.ts +23 -3
  88. package/dist/types/excalidraw/scene/Renderer.d.ts +425 -19
  89. package/dist/types/excalidraw/types.d.ts +76 -5
  90. package/dist/types/fractional-indexing/src/index.d.ts +29 -0
  91. package/dist/types/math/src/constants.d.ts +0 -1
  92. package/dist/types/math/src/curve.d.ts +4 -1
  93. package/package.json +4 -5
  94. package/dist/dev/chunk-UPL5GSGP.js.map +0 -7
  95. package/dist/dev/chunk-VLJRILK3.js.map +0 -7
  96. package/dist/prod/chunk-ZTGTHG3M.js +0 -34
  97. package/dist/prod/data/image-I4FBW6ZT.js +0 -1
  98. package/dist/prod/locales/en-4R6EP6SP.js +0 -1
  99. package/dist/types/utils/src/index.d.ts +0 -4
  100. /package/dist/dev/{chunk-H5SL5I5R.js.map → chunk-UEBEBUE2.js.map} +0 -0
  101. /package/dist/dev/components/TTDDialog/{CodeMirrorEditor-65RQRK4A.js.map → CodeMirrorEditor-2YIEAZU7.js.map} +0 -0
  102. /package/dist/dev/data/{image-JR54FB4B.js.map → image-O7OJXMIJ.js.map} +0 -0
  103. /package/dist/dev/locales/{en-IZ5JJCQN.js.map → en-XVKSJYG2.js.map} +0 -0
@@ -10,6 +10,7 @@ export declare const clearAppStateForLocalStorage: (appState: Partial<AppState>)
10
10
  }> | undefined;
11
11
  showWelcomeScreen?: boolean | undefined;
12
12
  isBindingEnabled?: boolean | undefined;
13
+ boxSelectionMode?: import("./types").BoxSelectionMode | undefined;
13
14
  bindingPreference?: "enabled" | "disabled" | undefined;
14
15
  isMidpointSnappingEnabled?: boolean | undefined;
15
16
  activeTool?: ({
@@ -2,7 +2,6 @@ import { ALLOWED_PASTE_MIME_TYPES } from "@excalidraw/common";
2
2
  import type { ValueOf } from "@excalidraw/common/utility-types";
3
3
  import type { IMAGE_MIME_TYPES, STRING_MIME_TYPES } from "@excalidraw/common";
4
4
  import type { ExcalidrawElement, NonDeletedExcalidrawElement } from "@excalidraw/element/types";
5
- import type { FileSystemHandle } from "./data/filesystem";
6
5
  import type { BinaryFiles } from "./types";
7
6
  export type PastedMixedContent = {
8
7
  type: "text" | "imageUrl";
@@ -52,7 +51,7 @@ type AllowedParsedDataTransferItem = {
52
51
  type: ValueOf<typeof IMAGE_MIME_TYPES>;
53
52
  kind: "file";
54
53
  file: File;
55
- fileHandle: FileSystemHandle | null;
54
+ fileHandle: FileSystemFileHandle | null;
56
55
  } | {
57
56
  type: ValueOf<typeof STRING_MIME_TYPES>;
58
57
  kind: "string";
@@ -62,7 +61,7 @@ type ParsedDataTransferItem = {
62
61
  type: string;
63
62
  kind: "file";
64
63
  file: File;
65
- fileHandle: FileSystemHandle | null;
64
+ fileHandle: FileSystemFileHandle | null;
66
65
  } | {
67
66
  type: string;
68
67
  kind: "string";
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { type EXPORT_IMAGE_TYPES, Emitter, type EditorInterface, type StylesPanelMode } from "@excalidraw/common";
2
+ import { AppEventBus, type EXPORT_IMAGE_TYPES, Emitter, type EditorInterface, type StylesPanelMode } from "@excalidraw/common";
3
3
  import { LinearElementEditor, FlowChartCreator } from "@excalidraw/element";
4
4
  import { Scene, Store, type ElementUpdate, StoreDelta, type ApplyToOptions } from "@excalidraw/element";
5
5
  import type { ExcalidrawElement, NonDeleted, NonDeletedExcalidrawElement, ExcalidrawFrameLikeElement, ExcalidrawIframeElement, ExcalidrawEmbeddableElement, Ordered, SceneElementsMap } from "@excalidraw/element/types";
@@ -14,15 +14,31 @@ import { LaserTrails } from "../laser-trails";
14
14
  import { isOverScrollBars } from "../scene/scrollbars";
15
15
  import { LassoTrail } from "../lasso";
16
16
  import { EraserTrail } from "../eraser";
17
+ import { type OnStateChange } from "./AppStateObserver";
17
18
  import type { ExportedElements } from "../data";
18
- import type { FileSystemHandle } from "../data/filesystem";
19
- import type { AppClassProperties, AppProps, AppState, ExcalidrawImperativeAPI, BinaryFiles, LibraryItems, SceneData, FrameNameBoundsCache, SidebarName, SidebarTabName, ScrollConstraints, ToolType, OnUserFollowedPayload, GenerateDiagramToCode, NullableGridSize, Offsets } from "../types";
19
+ import type { AppClassProperties, AppProps, AppState, ExcalidrawImperativeAPI, BinaryFiles, LibraryItems, SceneData, FrameNameBoundsCache, SidebarName, SidebarTabName, ScrollConstraints, ToolType, OnUserFollowedPayload, ExcalidrawImperativeAPIEventMap, GenerateDiagramToCode, NullableGridSize, Offsets } from "../types";
20
20
  import type { RoughCanvas } from "roughjs/bin/canvas";
21
21
  import type { ActionResult } from "../actions/types";
22
+ declare const editorLifecycleEventBehavior: {
23
+ readonly "editor:mount": {
24
+ readonly cardinality: "once";
25
+ readonly replay: "last";
26
+ };
27
+ readonly "editor:initialize": {
28
+ readonly cardinality: "once";
29
+ readonly replay: "last";
30
+ };
31
+ readonly "editor:unmount": {
32
+ readonly cardinality: "once";
33
+ readonly replay: "last";
34
+ };
35
+ };
22
36
  export declare const ExcalidrawContainerContext: React.Context<{
23
37
  container: HTMLDivElement | null;
24
38
  id?: string | null;
25
39
  }>;
40
+ export declare const ExcalidrawAPIContext: React.Context<ExcalidrawImperativeAPI | null>;
41
+ export declare const ExcalidrawAPISetContext: React.Context<((api: ExcalidrawImperativeAPI | null) => void) | null>;
26
42
  export declare const useApp: () => AppClassProperties;
27
43
  export declare const useAppProps: () => AppProps;
28
44
  export declare const useEditorInterface: () => Readonly<{
@@ -45,6 +61,10 @@ export declare const useExcalidrawElements: () => readonly NonDeletedExcalidrawE
45
61
  export declare const useExcalidrawAppState: () => AppState;
46
62
  export declare const useExcalidrawSetAppState: () => <K extends keyof AppState>(state: AppState | ((prevState: Readonly<AppState>, props: Readonly<any>) => AppState | Pick<AppState, K> | null) | Pick<AppState, K> | null, callback?: (() => void) | undefined) => void;
47
63
  export declare const useExcalidrawActionManager: () => ActionManager;
64
+ /**
65
+ * Requires wrapping your component in <ExcalidrawAPIContext.Provider>
66
+ */
67
+ export declare const useExcalidrawAPI: () => ExcalidrawImperativeAPI | null;
48
68
  declare class App extends React.Component<AppProps, AppState> {
49
69
  canvas: AppClassProperties["canvas"];
50
70
  interactiveCanvas: AppClassProperties["interactiveCanvas"];
@@ -81,8 +101,12 @@ declare class App extends React.Component<AppProps, AppState> {
81
101
  /** embeds that have been inserted to DOM (as a perf optim, we don't want to
82
102
  * insert to DOM before user initially scrolls to them) */
83
103
  private initializedEmbeds;
84
- private handleToastClose;
85
104
  private elementsPendingErasure;
105
+ private _initialized;
106
+ private readonly editorLifecycleEvents;
107
+ onEvent: AppEventBus<ExcalidrawImperativeAPIEventMap, typeof editorLifecycleEventBehavior>["on"];
108
+ private appStateObserver;
109
+ onStateChange: OnStateChange;
86
110
  flowChartCreator: FlowChartCreator;
87
111
  private flowChartNavigator;
88
112
  bindModeHandler: ReturnType<typeof setTimeout> | null;
@@ -241,6 +265,8 @@ declare class App extends React.Component<AppProps, AppState> {
241
265
  }>]>;
242
266
  missingPointerEventCleanupEmitter: Emitter<[event: PointerEvent | null]>;
243
267
  onRemoveEventListenersEmitter: Emitter<[]>;
268
+ api: ExcalidrawImperativeAPI;
269
+ private createExcalidrawAPI;
244
270
  constructor(props: AppProps);
245
271
  updateEditorAtom: <Value, Args extends unknown[], Result>(atom: WritableAtom<Value, Args, Result>, ...args: Args) => Result;
246
272
  setSessionExportThemeOverride(theme: AppState["theme"]): void;
@@ -336,6 +362,7 @@ declare class App extends React.Component<AppProps, AppState> {
336
362
  } | "cursor" | "center";
337
363
  retainSeed?: boolean;
338
364
  fitToContent?: boolean;
365
+ preserveFrameChildrenOrder?: boolean;
339
366
  }) => void;
340
367
  private addElementsFromMixedContentPaste;
341
368
  private addTextFromPaste;
@@ -388,11 +415,7 @@ declare class App extends React.Component<AppProps, AppState> {
388
415
  private debounceConstrainScrollState;
389
416
  private animateToConstrainedArea;
390
417
  private animateTranslateCanvas;
391
- setToast: (toast: {
392
- message: string;
393
- closable?: boolean;
394
- duration?: number;
395
- } | null) => void;
418
+ setToast: (toast: AppState["toast"]) => void;
396
419
  restoreFileFromShare: () => Promise<void>;
397
420
  /**
398
421
  * adds supplied files to existing files in the appState.
@@ -476,7 +499,15 @@ declare class App extends React.Component<AppProps, AppState> {
476
499
  private handleCanvasClick;
477
500
  private getElementLinkAtPosition;
478
501
  private handleElementLinkClick;
502
+ /**
503
+ * finds candidate frame under cursor (when dragging frame children/elements
504
+ * inside frames)
505
+ */
479
506
  private getTopLayerFrameAtSceneCoords;
507
+ private updateFrameToHighlight;
508
+ private maybeUpdateFrameToHighlightOnPointerMove;
509
+ private insertNewElements;
510
+ private insertNewElement;
480
511
  private handleCanvasPointerMove;
481
512
  private handleEraser;
482
513
  private handleTouchMove;
@@ -550,7 +581,7 @@ declare class App extends React.Component<AppProps, AppState> {
550
581
  private handleInteractiveCanvasRef;
551
582
  private insertImages;
552
583
  private handleAppOnDrop;
553
- loadFileToCanvas: (file: File, fileHandle: FileSystemHandle | null) => Promise<void>;
584
+ loadFileToCanvas: (file: File, fileHandle: FileSystemFileHandle | null) => Promise<void>;
554
585
  private handleCanvasContextMenu;
555
586
  private maybeDragNewGenericElement;
556
587
  private maybeHandleCrop;
@@ -0,0 +1,37 @@
1
+ import type { AppState, UnsubscribeCallback } from "../types";
2
+ type StateChangeSelector = keyof AppState | (keyof AppState)[] | ((appState: AppState) => unknown);
3
+ export type OnStateChange = {
4
+ <K extends keyof AppState>(prop: K, callback: (value: AppState[K], appState: AppState) => void, opts?: {
5
+ once: boolean;
6
+ }): UnsubscribeCallback;
7
+ <K extends keyof AppState>(prop: K): Promise<AppState[K]>;
8
+ (prop: (keyof AppState)[], callback: (appState: AppState, appState2: AppState) => void, opts?: {
9
+ once: boolean;
10
+ }): UnsubscribeCallback;
11
+ (prop: (keyof AppState)[]): Promise<AppState>;
12
+ <T>(prop: (appState: AppState) => T, callback: (value: T, appState: AppState) => void, opts?: {
13
+ once: boolean;
14
+ }): UnsubscribeCallback;
15
+ <T>(prop: (appState: AppState) => T): Promise<T>;
16
+ (opts: {
17
+ predicate: (appState: AppState) => boolean;
18
+ callback: (appState: AppState) => void;
19
+ once?: boolean;
20
+ }): UnsubscribeCallback;
21
+ (opts: {
22
+ predicate: (appState: AppState) => boolean;
23
+ }): Promise<AppState>;
24
+ (selector: StateChangeSelector, callback: (value: any, appState: AppState) => void): any;
25
+ };
26
+ export declare class AppStateObserver {
27
+ private readonly getState;
28
+ private listeners;
29
+ constructor(getState: () => AppState);
30
+ private isStateChangePredicateOptions;
31
+ private subscribe;
32
+ private normalize;
33
+ onStateChange: OnStateChange;
34
+ flush(prevState: AppState): void;
35
+ clear(): void;
36
+ }
37
+ export {};
@@ -1,4 +1,4 @@
1
- import type { LLMMessage, TTTDDialog } from "@excalidraw/excalidraw/components/TTDDialog/types";
1
+ import type { LLMMessage, TTTDDialog } from "../types";
2
2
  interface StreamingOptions {
3
3
  url: string;
4
4
  messages: readonly LLMMessage[];
@@ -1,9 +1,13 @@
1
1
  import "./Toast.scss";
2
- import type { CSSProperties } from "react";
3
- export declare const Toast: ({ message, onClose, closable, duration, style, }: {
4
- message: string;
2
+ import type { CSSProperties, ReactNode } from "react";
3
+ export declare const Toast: (({ message, onClose, closable, duration, style, }: {
4
+ message: ReactNode;
5
5
  onClose: () => void;
6
6
  closable?: boolean;
7
7
  duration?: number;
8
8
  style?: CSSProperties;
9
- }) => import("react/jsx-runtime").JSX.Element;
9
+ }) => import("react/jsx-runtime").JSX.Element) & {
10
+ ProgressBar: ({ progress }: {
11
+ progress: number;
12
+ }) => import("react/jsx-runtime").JSX.Element;
13
+ };
@@ -11,7 +11,7 @@ type InteractiveCanvasProps = {
11
11
  visibleElements: readonly NonDeletedExcalidrawElement[];
12
12
  selectedElements: readonly NonDeletedExcalidrawElement[];
13
13
  allElementsMap: NonDeletedSceneElementsMap;
14
- sceneNonce: number | undefined;
14
+ canvasNonce: string;
15
15
  selectionNonce: number | undefined;
16
16
  scale: number;
17
17
  appState: InteractiveCanvasAppState;
@@ -4,6 +4,7 @@ import type { AppState } from "../../types";
4
4
  import type { RoughCanvas } from "roughjs/bin/canvas";
5
5
  interface NewElementCanvasProps {
6
6
  appState: AppState;
7
+ newElement: NonNullable<AppState["newElement"]>;
7
8
  elementsMap: RenderableElementsMap;
8
9
  allElementsMap: NonDeletedSceneElementsMap;
9
10
  scale: number;
@@ -9,7 +9,7 @@ type StaticCanvasProps = {
9
9
  elementsMap: RenderableElementsMap;
10
10
  allElementsMap: NonDeletedSceneElementsMap;
11
11
  visibleElements: readonly NonDeletedExcalidrawElement[];
12
- sceneNonce: number | undefined;
12
+ canvasNonce: string;
13
13
  selectionNonce: number | undefined;
14
14
  scale: number;
15
15
  appState: StaticCanvasAppState;
@@ -9,9 +9,10 @@ type Props<T> = {
9
9
  onChange: (value: T) => void;
10
10
  children: React.ReactNode;
11
11
  name: string;
12
+ icon?: React.ReactNode;
12
13
  };
13
14
  declare const DropdownMenuItemContentRadio: {
14
- <T>({ value, shortcut, onChange, choices, children, name, }: Props<T>): import("react/jsx-runtime").JSX.Element;
15
+ <T>({ value, shortcut, onChange, choices, children, name, icon, }: Props<T>): import("react/jsx-runtime").JSX.Element;
15
16
  displayName: string;
16
17
  };
17
18
  export default DropdownMenuItemContentRadio;
@@ -70,6 +70,7 @@ export declare const Preferences: {
70
70
  additionalItems?: React.ReactNode;
71
71
  }): import("react/jsx-runtime").JSX.Element;
72
72
  ToggleToolLock: () => import("react/jsx-runtime").JSX.Element;
73
+ BoxSelectionMode: () => import("react/jsx-runtime").JSX.Element;
73
74
  ToggleSnapMode: () => import("react/jsx-runtime").JSX.Element;
74
75
  ToggleArrowBinding: () => import("react/jsx-runtime").JSX.Element;
75
76
  ToggleMidpointSnapping: () => import("react/jsx-runtime").JSX.Element;
@@ -169,6 +169,13 @@ export declare const getToolbarTools: (app: AppClassProperties) => readonly [{
169
169
  readonly fillable: false;
170
170
  readonly toolbar: false;
171
171
  }] | readonly [{
172
+ readonly icon: import("react/jsx-runtime").JSX.Element;
173
+ readonly value: "hand";
174
+ readonly key: "h";
175
+ readonly numericKey: null;
176
+ readonly fillable: false;
177
+ readonly toolbar: true;
178
+ }, {
172
179
  readonly value: "lasso";
173
180
  readonly icon: import("react/jsx-runtime").JSX.Element;
174
181
  readonly key: "v";
@@ -2,12 +2,11 @@ import { IMAGE_MIME_TYPES, MIME_TYPES } from "@excalidraw/common";
2
2
  import type { ValueOf } from "@excalidraw/common/utility-types";
3
3
  import type { ExcalidrawElement, FileId } from "@excalidraw/element/types";
4
4
  import type { AppState, DataURL, LibraryItem } from "../types";
5
- import type { FileSystemHandle } from "browser-fs-access";
6
5
  import type { ImportedLibraryData } from "./types";
7
6
  export declare const getMimeType: (blob: Blob | string) => string;
8
- export declare const getFileHandleType: (handle: FileSystemHandle | null) => string | null;
7
+ export declare const getFileHandleType: (handle: FileSystemFileHandle | null) => string | null;
9
8
  export declare const isImageFileHandleType: (type: string | null) => type is "png" | "svg";
10
- export declare const isImageFileHandle: (handle: FileSystemHandle | null) => boolean;
9
+ export declare const isImageFileHandle: (handle: FileSystemFileHandle | null) => handle is FileSystemFileHandle;
11
10
  export declare const isSupportedImageFileType: (type: string | null | undefined) => boolean;
12
11
  export declare const isSupportedImageFile: (blob: Blob | null | undefined) => blob is Blob & {
13
12
  type: ValueOf<typeof IMAGE_MIME_TYPES>;
@@ -15,8 +14,8 @@ export declare const isSupportedImageFile: (blob: Blob | null | undefined) => bl
15
14
  export declare const loadSceneOrLibraryFromBlob: (blob: Blob | File,
16
15
  /** @see restore.localAppState */
17
16
  localAppState: AppState | null, localElements: readonly ExcalidrawElement[] | null,
18
- /** FileSystemHandle. Defaults to `blob.handle` if defined, otherwise null. */
19
- fileHandle?: FileSystemHandle | null) => Promise<{
17
+ /** FileSystemFileHandle. Defaults to `blob.handle` if defined, otherwise null. */
18
+ fileHandle?: FileSystemFileHandle | null) => Promise<{
20
19
  type: "application/vnd.excalidraw+json";
21
20
  data: {
22
21
  elements: import("@excalidraw/element/types").OrderedExcalidrawElement[];
@@ -49,9 +48,9 @@ fileHandle?: FileSystemHandle | null) => Promise<{
49
48
  multiElement: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawLinearElement> | null;
50
49
  selectionElement: import("@excalidraw/element/types").NonDeletedExcalidrawElement | null;
51
50
  isBindingEnabled: boolean;
51
+ boxSelectionMode: import("../types").BoxSelectionMode;
52
52
  bindingPreference: "enabled" | "disabled";
53
53
  isMidpointSnappingEnabled: boolean;
54
- startBoundElement: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawBindableElement> | null;
55
54
  suggestedBinding: {
56
55
  element: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawBindableElement>;
57
56
  midPoint?: import("@excalidraw/math").GlobalPoint;
@@ -132,7 +131,7 @@ fileHandle?: FileSystemHandle | null) => Promise<{
132
131
  selectedElementsAreBeingDragged: boolean;
133
132
  shouldCacheIgnoreZoom: boolean;
134
133
  toast: {
135
- message: string;
134
+ message: React.ReactNode;
136
135
  closable?: boolean;
137
136
  duration?: number;
138
137
  } | null;
@@ -145,7 +144,7 @@ fileHandle?: FileSystemHandle | null) => Promise<{
145
144
  [groupId: string]: boolean;
146
145
  };
147
146
  editingGroupId: import("@excalidraw/element/types").GroupId | null;
148
- fileHandle: FileSystemHandle | null;
147
+ fileHandle: FileSystemFileHandle | null;
149
148
  collaborators: Map<import("../types").SocketId, import("../types").Collaborator>;
150
149
  stats: {
151
150
  open: boolean;
@@ -182,8 +181,8 @@ fileHandle?: FileSystemHandle | null) => Promise<{
182
181
  export declare const loadFromBlob: (blob: Blob,
183
182
  /** @see restore.localAppState */
184
183
  localAppState: AppState | null, localElements: readonly ExcalidrawElement[] | null,
185
- /** FileSystemHandle. Defaults to `blob.handle` if defined, otherwise null. */
186
- fileHandle?: FileSystemHandle | null) => Promise<{
184
+ /** FileSystemFileHandle. Defaults to `blob.handle` if defined, otherwise null. */
185
+ fileHandle?: FileSystemFileHandle | null) => Promise<{
187
186
  elements: import("@excalidraw/element/types").OrderedExcalidrawElement[];
188
187
  appState: {
189
188
  theme: import("@excalidraw/element/types").Theme;
@@ -214,9 +213,9 @@ fileHandle?: FileSystemHandle | null) => Promise<{
214
213
  multiElement: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawLinearElement> | null;
215
214
  selectionElement: import("@excalidraw/element/types").NonDeletedExcalidrawElement | null;
216
215
  isBindingEnabled: boolean;
216
+ boxSelectionMode: import("../types").BoxSelectionMode;
217
217
  bindingPreference: "enabled" | "disabled";
218
218
  isMidpointSnappingEnabled: boolean;
219
- startBoundElement: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawBindableElement> | null;
220
219
  suggestedBinding: {
221
220
  element: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawBindableElement>;
222
221
  midPoint?: import("@excalidraw/math").GlobalPoint;
@@ -297,7 +296,7 @@ fileHandle?: FileSystemHandle | null) => Promise<{
297
296
  selectedElementsAreBeingDragged: boolean;
298
297
  shouldCacheIgnoreZoom: boolean;
299
298
  toast: {
300
- message: string;
299
+ message: React.ReactNode;
301
300
  closable?: boolean;
302
301
  duration?: number;
303
302
  } | null;
@@ -310,7 +309,7 @@ fileHandle?: FileSystemHandle | null) => Promise<{
310
309
  [groupId: string]: boolean;
311
310
  };
312
311
  editingGroupId: import("@excalidraw/element/types").GroupId | null;
313
- fileHandle: FileSystemHandle | null;
312
+ fileHandle: FileSystemFileHandle | null;
314
313
  collaborators: Map<import("../types").SocketId, import("../types").Collaborator>;
315
314
  stats: {
316
315
  open: boolean;
@@ -360,7 +359,7 @@ export declare const SVGStringToFile: (SVGString: string, filename?: string) =>
360
359
  type: typeof MIME_TYPES.svg;
361
360
  };
362
361
  export declare const ImageURLToFile: (imageUrl: string, filename?: string) => Promise<File | undefined>;
363
- export declare const getFileHandle: (event: DragEvent | React.DragEvent | DataTransferItem) => Promise<FileSystemHandle | null>;
362
+ export declare const getFileHandle: (event: DragEvent | React.DragEvent | DataTransferItem) => Promise<FileSystemFileHandle | null>;
364
363
  export declare const createFile: (blob: File | Blob | ArrayBuffer, mimeType: string, name: string | undefined) => File;
365
364
  /** attempts to detect correct mimeType if none is set, or if an image
366
365
  * has an incorrect extension.
@@ -1,6 +1,5 @@
1
1
  import { supported as nativeFileSystemSupported } from "browser-fs-access";
2
2
  import { MIME_TYPES } from "@excalidraw/common";
3
- import type { FileSystemHandle } from "browser-fs-access";
4
3
  type FILE_EXTENSION = Exclude<keyof typeof MIME_TYPES, "binary">;
5
4
  export declare const fileOpen: <M extends boolean | undefined = false>(opts: {
6
5
  extensions?: FILE_EXTENSION[];
@@ -14,8 +13,7 @@ export declare const fileSave: (blob: Blob | Promise<Blob>, opts: {
14
13
  extension: FILE_EXTENSION;
15
14
  mimeTypes?: string[];
16
15
  description: string;
17
- /** existing FileSystemHandle */
18
- fileHandle?: FileSystemHandle | null;
19
- }) => Promise<FileSystemHandle | null>;
16
+ /** existing FileSystemFileHandle */
17
+ fileHandle?: FileSystemFileHandle | null;
18
+ }) => Promise<FileSystemFileHandle | null>;
20
19
  export { nativeFileSystemSupported };
21
- export type { FileSystemHandle };
@@ -1,5 +1,4 @@
1
1
  import type { ExcalidrawElement, ExcalidrawFrameLikeElement, NonDeletedExcalidrawElement } from "@excalidraw/element/types";
2
- import type { FileSystemHandle } from "./filesystem";
3
2
  import type { ExportType } from "../scene/types";
4
3
  import type { AppState, BinaryFiles } from "../types";
5
4
  export { loadFromBlob } from "./blob";
@@ -24,7 +23,7 @@ export declare const exportAsImage: ({ type, data, config, }: {
24
23
  viewBackgroundColor: string;
25
24
  /** filename, if applicable */
26
25
  name?: string;
27
- fileHandle?: FileSystemHandle | null;
26
+ fileHandle?: FileSystemFileHandle | null;
28
27
  exportingFrame: ExcalidrawFrameLikeElement | null;
29
28
  };
30
- }) => Promise<FileSystemHandle | null | undefined>;
29
+ }) => Promise<FileSystemFileHandle | null | undefined>;
@@ -1,11 +1,19 @@
1
- import type { ExcalidrawElement } from "@excalidraw/element/types";
1
+ import type { ExcalidrawElement, NonDeleted } from "@excalidraw/element/types";
2
+ import type { MaybePromise } from "@excalidraw/common/utility-types";
2
3
  import type { AppState, BinaryFiles, LibraryItems } from "../types";
3
4
  import type { ImportedDataState, ImportedLibraryData } from "./types";
5
+ export type JSONExportData = {
6
+ elements: readonly NonDeleted<ExcalidrawElement>[];
7
+ appState: AppState;
8
+ files: BinaryFiles;
9
+ };
4
10
  export declare const serializeAsJSON: (elements: readonly ExcalidrawElement[], appState: Partial<AppState>, files: BinaryFiles, type: "local" | "database") => string;
5
- export declare const saveAsJSON: (elements: readonly ExcalidrawElement[], appState: AppState, files: BinaryFiles,
6
- /** filename */
7
- name?: string) => Promise<{
8
- fileHandle: import("browser-fs-access").FileSystemHandle | null;
11
+ export declare const saveAsJSON: ({ data, filename, fileHandle, }: {
12
+ data: MaybePromise<JSONExportData>;
13
+ filename: string;
14
+ fileHandle: AppState["fileHandle"];
15
+ }) => Promise<{
16
+ fileHandle: FileSystemFileHandle | null;
9
17
  }>;
10
18
  export declare const loadFromJSON: (localAppState: AppState, localElements: readonly ExcalidrawElement[] | null) => Promise<{
11
19
  elements: import("@excalidraw/element/types").OrderedExcalidrawElement[];
@@ -33,21 +41,21 @@ export declare const loadFromJSON: (localAppState: AppState, localElements: read
33
41
  element: import("@excalidraw/element/types").NonDeletedExcalidrawElement;
34
42
  state: "hover" | "active";
35
43
  } | null;
36
- newElement: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawNonSelectionElement> | null;
44
+ newElement: NonDeleted<import("@excalidraw/element/types").ExcalidrawNonSelectionElement> | null;
37
45
  resizingElement: import("@excalidraw/element/types").NonDeletedExcalidrawElement | null;
38
- multiElement: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawLinearElement> | null;
46
+ multiElement: NonDeleted<import("@excalidraw/element/types").ExcalidrawLinearElement> | null;
39
47
  selectionElement: import("@excalidraw/element/types").NonDeletedExcalidrawElement | null;
40
48
  isBindingEnabled: boolean;
49
+ boxSelectionMode: import("../types").BoxSelectionMode;
41
50
  bindingPreference: "enabled" | "disabled";
42
51
  isMidpointSnappingEnabled: boolean;
43
- startBoundElement: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawBindableElement> | null;
44
52
  suggestedBinding: {
45
- element: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawBindableElement>;
53
+ element: NonDeleted<import("@excalidraw/element/types").ExcalidrawBindableElement>;
46
54
  midPoint?: import("@excalidraw/math").GlobalPoint;
47
55
  } | null;
48
- frameToHighlight: import("@excalidraw/element/types").NonDeleted<import("@excalidraw/element/types").ExcalidrawFrameLikeElement> | null;
56
+ frameToHighlight: NonDeleted<import("@excalidraw/element/types").ExcalidrawFrameLikeElement> | null;
49
57
  editingFrame: string | null;
50
- elementsToHighlight: import("@excalidraw/element/types").NonDeleted<ExcalidrawElement>[] | null;
58
+ elementsToHighlight: NonDeleted<ExcalidrawElement>[] | null;
51
59
  editingTextElement: import("@excalidraw/element/types").ExcalidrawTextElement | null;
52
60
  activeTool: {
53
61
  lastActiveTool: import("../types").ActiveTool | null;
@@ -121,7 +129,7 @@ export declare const loadFromJSON: (localAppState: AppState, localElements: read
121
129
  selectedElementsAreBeingDragged: boolean;
122
130
  shouldCacheIgnoreZoom: boolean;
123
131
  toast: {
124
- message: string;
132
+ message: React.ReactNode;
125
133
  closable?: boolean;
126
134
  duration?: number;
127
135
  } | null;
@@ -134,7 +142,7 @@ export declare const loadFromJSON: (localAppState: AppState, localElements: read
134
142
  [groupId: string]: boolean;
135
143
  };
136
144
  editingGroupId: import("@excalidraw/element/types").GroupId | null;
137
- fileHandle: import("browser-fs-access").FileSystemHandle | null;
145
+ fileHandle: FileSystemFileHandle | null;
138
146
  collaborators: Map<import("../types").SocketId, import("../types").Collaborator>;
139
147
  stats: {
140
148
  open: boolean;
@@ -1,5 +1,10 @@
1
+ import type { MaybePromise } from "@excalidraw/common/utility-types";
1
2
  import type { ExcalidrawElement } from "@excalidraw/element/types";
2
3
  import type { AppState, BinaryFiles } from "../types";
3
- export declare const resaveAsImageWithScene: (elements: readonly ExcalidrawElement[], appState: AppState, files: BinaryFiles, name: string) => Promise<{
4
- fileHandle: import("browser-fs-access").FileSystemHandle;
4
+ export declare const resaveAsImageWithScene: (data: MaybePromise<{
5
+ elements: readonly ExcalidrawElement[];
6
+ appState: AppState;
7
+ files: BinaryFiles;
8
+ }>, fileHandle: FileSystemFileHandle, filename: string) => Promise<{
9
+ fileHandle: FileSystemFileHandle;
5
10
  }>;
@@ -0,0 +1,29 @@
1
+ import type { AppState } from "../types";
2
+ /**
3
+ * Subscribes to specific appState changes. The component re-renders
4
+ * only when the specified prop(s) change — not on every appState update.
5
+ *
6
+ * Works both inside and outside the <Excalidraw> tree, as long as
7
+ * ExcalidrawAPIContext.Provider is an ancestor (automatically provided
8
+ * inside <Excalidraw>, or manually by the host app).
9
+ *
10
+ * Returns the narrowed value depending on prop form:
11
+ * - `keyof AppState` → `AppState[K]`
12
+ * - `(keyof AppState)[]` → whole `AppState`
13
+ * - selector function → selector's return type `T`
14
+ *
15
+ * If excalidrawAPI is not ready yet (host apps), hook is rerendered with latest
16
+ * value once available.
17
+ */
18
+ export declare function useAppStateValue<K extends keyof AppState>(prop: K, _internal?: boolean): AppState[K];
19
+ export declare function useAppStateValue(props: (keyof AppState)[], _internal?: boolean): AppState;
20
+ export declare function useAppStateValue<T>(selector: (appState: AppState) => T, _internal?: boolean): T;
21
+ /**
22
+ * Subscribes to specific appState changes without causing component rerenders.
23
+ *
24
+ * The callback is called on every matching change, but also on initial render
25
+ * so you can initialize your state.
26
+ */
27
+ export declare function useOnAppStateChange<K extends keyof AppState>(prop: K, callback: (value: AppState[K], appState: AppState) => void): undefined;
28
+ export declare function useOnAppStateChange(props: (keyof AppState)[], callback: (props: AppState, appState: AppState) => void): undefined;
29
+ export declare function useOnAppStateChange<T>(selector: (appState: AppState) => T, callback: (value: T, appState: AppState) => void): undefined;
@@ -3,10 +3,19 @@ import Footer from "./components/footer/FooterCenter";
3
3
  import LiveCollaborationTrigger from "./components/live-collaboration/LiveCollaborationTrigger";
4
4
  import MainMenu from "./components/main-menu/MainMenu";
5
5
  import WelcomeScreen from "./components/welcome-screen/WelcomeScreen";
6
+ import { useOnAppStateChange as _useOnAppStateChange } from "./hooks/useAppStateValue";
6
7
  import "./css/app.scss";
7
8
  import "./css/styles.scss";
8
9
  import "./fonts/fonts.css";
9
- import type { ExcalidrawProps } from "./types";
10
+ import type { AppState, ExcalidrawProps } from "./types";
11
+ /**
12
+ * Stateless provider that allows `useExcalidrawAPI()` (and hooks built
13
+ * on it, such as `useAppStateValue()` and `useOnAppStateChange()`) to work
14
+ * outside the <Excalidraw> component tree.
15
+ */
16
+ export declare const ExcalidrawAPIProvider: ({ children, }: {
17
+ children: React.ReactNode;
18
+ }) => import("react/jsx-runtime").JSX.Element;
10
19
  export declare const Excalidraw: React.MemoExoticComponent<(props: ExcalidrawProps) => import("react/jsx-runtime").JSX.Element>;
11
20
  export { getSceneVersion, hashElementsVersion, hashString, getNonDeletedElements, } from "@excalidraw/element";
12
21
  export { getTextFromElements } from "@excalidraw/element";
@@ -19,7 +28,7 @@ export { serializeAsJSON, serializeLibraryAsJSON } from "./data/json";
19
28
  export { loadFromBlob, loadSceneOrLibraryFromBlob, loadLibraryFromBlob, } from "./data/blob";
20
29
  export { mergeLibraryItems, getLibraryItemsHash } from "./data/library";
21
30
  export { isLinearElement } from "@excalidraw/element";
22
- export { FONT_FAMILY, THEME, MIME_TYPES, ROUNDNESS, DEFAULT_LASER_COLOR, UserIdleState, normalizeLink, sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, getFormFactor, } from "@excalidraw/common";
31
+ export { FONT_FAMILY, THEME, MIME_TYPES, ROUNDNESS, DEFAULT_LASER_COLOR, UserIdleState, normalizeLink, sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, getFormFactor, throttleRAF, } from "@excalidraw/common";
23
32
  export { mutateElement, newElementWith, bumpVersion, } from "@excalidraw/element";
24
33
  export { CaptureUpdateAction } from "@excalidraw/element";
25
34
  export { parseLibraryTokensFromUrl, useHandleLibrary } from "./data/library";
@@ -28,7 +37,7 @@ export { Button } from "./components/Button";
28
37
  export { Footer };
29
38
  export { MainMenu };
30
39
  export { Ellipsify } from "./components/Ellipsify";
31
- export { useEditorInterface, useStylesPanelMode } from "./components/App";
40
+ export { useEditorInterface, useStylesPanelMode, useExcalidrawAPI, ExcalidrawAPIContext, } from "./components/App";
32
41
  export { WelcomeScreen };
33
42
  export { LiveCollaborationTrigger };
34
43
  export { Stats } from "./components/Stats";
@@ -44,9 +53,20 @@ export { elementsOverlappingBBox, isElementInsideBBox, elementPartiallyOverlapsW
44
53
  export { DiagramToCodePlugin } from "./components/DiagramToCodePlugin/DiagramToCodePlugin";
45
54
  export { getDataURL } from "./data/blob";
46
55
  export { isElementLink } from "@excalidraw/element";
56
+ export { Fonts } from "./fonts/Fonts";
47
57
  export { setCustomTextMetricsProvider } from "@excalidraw/element";
48
58
  export { CommandPalette } from "./components/CommandPalette/CommandPalette";
49
59
  export { renderSpreadsheet, tryParseSpreadsheet, isSpreadsheetValidForChartType, } from "./charts/index";
60
+ /**
61
+ * hook that subscribes to specific appState prop(s)
62
+ *
63
+ * @param prop - appState prop(s) to subscribe to, or a selector function.
64
+ * NOTE `prop/selector` is memoized and will not change after initial render
65
+ */
66
+ export declare function useExcalidrawStateValue<K extends keyof AppState>(prop: K): AppState[K] | undefined;
67
+ export declare function useExcalidrawStateValue<T extends keyof AppState>(props: T[]): AppState | undefined;
68
+ export declare function useExcalidrawStateValue<T>(selector: (appState: AppState) => T): T | undefined;
69
+ export { _useOnAppStateChange as useOnExcalidrawStateChange };
50
70
  export { getDefaultAppState, cleanAppStateForExport, clearAppStateForLocalStorage, } from "./appState";
51
71
  export { libraryItemsAtom } from "./data/library";
52
72
  export * as icons from "./components/icons";