@dwelle/excalidraw 0.3.63 → 0.3.66

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 (42) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README_NEXT.md +246 -35
  3. package/dist/excalidraw.development.js +52 -52
  4. package/dist/excalidraw.production.min.js +1 -1
  5. package/package.json +8 -8
  6. package/types/actions/actionAddToLibrary.d.ts +21 -3
  7. package/types/actions/actionBoundText.d.ts +7 -1
  8. package/types/actions/actionCanvas.d.ts +57 -9
  9. package/types/actions/actionClipboard.d.ts +36 -6
  10. package/types/actions/actionDeleteSelected.d.ts +22 -4
  11. package/types/actions/actionDuplicateSelection.d.ts +1 -1
  12. package/types/actions/actionExport.d.ts +64 -10
  13. package/types/actions/actionFinalize.d.ts +18 -5
  14. package/types/actions/actionMenu.d.ts +21 -3
  15. package/types/actions/actionProperties.d.ts +91 -13
  16. package/types/actions/actionStyles.d.ts +7 -1
  17. package/types/actions/actionToggleGridMode.d.ts +7 -1
  18. package/types/actions/actionToggleStats.d.ts +7 -1
  19. package/types/actions/actionToggleViewMode.d.ts +7 -1
  20. package/types/actions/actionToggleZenMode.d.ts +7 -1
  21. package/types/appState.d.ts +8 -2
  22. package/types/charts.d.ts +8 -0
  23. package/types/clipboard.d.ts +1 -1
  24. package/types/components/App.d.ts +9 -3
  25. package/types/components/Avatar.d.ts +3 -2
  26. package/types/components/LibraryMenu.d.ts +3 -3
  27. package/types/components/LibraryMenuItems.d.ts +5 -4
  28. package/types/components/LibraryUnit.d.ts +2 -1
  29. package/types/constants.d.ts +3 -0
  30. package/types/data/blob.d.ts +21 -1
  31. package/types/data/json.d.ts +0 -2
  32. package/types/data/library.d.ts +50 -51
  33. package/types/data/types.d.ts +2 -2
  34. package/types/distribute.d.ts +6 -0
  35. package/types/element/Hyperlink.d.ts +7 -1
  36. package/types/element/linearElementEditor.d.ts +11 -2
  37. package/types/packages/excalidraw/dist/excalidraw.production.min.d.ts +1 -3
  38. package/types/packages/excalidraw/index.d.ts +5 -5
  39. package/types/packages/utils.d.ts +7 -3
  40. package/types/scene/Scene.d.ts +1 -2
  41. package/types/types.d.ts +23 -5
  42. package/types/utils.d.ts +10 -1
@@ -1,12 +1,9 @@
1
- import { LibraryItems, LibraryItem } from "../types";
1
+ import { LibraryItems, ExcalidrawImperativeAPI, LibraryItemsSource } from "../types";
2
2
  import type App from "../components/App";
3
- import { ImportedDataState } from "./types";
3
+ import { ExcalidrawElement } from "../element/types";
4
4
  export declare const libraryItemsAtom: import("jotai").Atom<{
5
- status: "loading";
6
- libraryItems: null;
7
- promise: Promise<LibraryItems>;
8
- } | {
9
- status: "loaded";
5
+ status: "loading" | "loaded";
6
+ isInitialized: boolean;
10
7
  libraryItems: LibraryItems;
11
8
  }> & {
12
9
  write: (get: {
@@ -27,71 +24,73 @@ export declare const libraryItemsAtom: import("jotai").Atom<{
27
24
  <Value_6, Result extends void | Promise<void>>(atom: import("jotai").WritableAtom<Value_6, undefined, Result>): Result;
28
25
  <Value_7, Update, Result_1 extends void | Promise<void>>(atom: import("jotai").WritableAtom<Value_7, Update, Result_1>, update: Update): Result_1;
29
26
  }, update: {
30
- status: "loading";
31
- libraryItems: null;
32
- promise: Promise<LibraryItems>;
33
- } | {
34
- status: "loaded";
27
+ status: "loading" | "loaded";
28
+ isInitialized: boolean;
35
29
  libraryItems: LibraryItems;
36
30
  } | ((prev: {
37
- status: "loading";
38
- libraryItems: null;
39
- promise: Promise<LibraryItems>;
40
- } | {
41
- status: "loaded";
31
+ status: "loading" | "loaded";
32
+ isInitialized: boolean;
42
33
  libraryItems: LibraryItems;
43
34
  }) => {
44
- status: "loading";
45
- libraryItems: null;
46
- promise: Promise<LibraryItems>;
47
- } | {
48
- status: "loaded";
35
+ status: "loading" | "loaded";
36
+ isInitialized: boolean;
49
37
  libraryItems: LibraryItems;
50
38
  })) => void;
51
39
  onMount?: (<S extends (update: {
52
- status: "loading";
53
- libraryItems: null;
54
- promise: Promise<LibraryItems>;
55
- } | {
56
- status: "loaded";
40
+ status: "loading" | "loaded";
41
+ isInitialized: boolean;
57
42
  libraryItems: LibraryItems;
58
43
  } | ((prev: {
59
- status: "loading";
60
- libraryItems: null;
61
- promise: Promise<LibraryItems>;
62
- } | {
63
- status: "loaded";
44
+ status: "loading" | "loaded";
45
+ isInitialized: boolean;
64
46
  libraryItems: LibraryItems;
65
47
  }) => {
66
- status: "loading";
67
- libraryItems: null;
68
- promise: Promise<LibraryItems>;
69
- } | {
70
- status: "loaded";
48
+ status: "loading" | "loaded";
49
+ isInitialized: boolean;
71
50
  libraryItems: LibraryItems;
72
51
  })) => void>(setAtom: S) => void | (() => void)) | undefined;
73
52
  } & {
74
53
  init: {
75
- status: "loading";
76
- libraryItems: null;
77
- promise: Promise<LibraryItems>;
78
- } | {
79
- status: "loaded";
54
+ status: "loading" | "loaded";
55
+ isInitialized: boolean;
80
56
  libraryItems: LibraryItems;
81
57
  };
82
58
  };
59
+ /** Merges otherItems into localItems. Unique items in otherItems array are
60
+ sorted first. */
61
+ export declare const mergeLibraryItems: (localItems: LibraryItems, otherItems: LibraryItems) => LibraryItems;
83
62
  declare class Library {
84
- /** cache for currently active promise when initializing/updating libaries
85
- asynchronously */
86
- private libraryItemsPromise;
87
- /** last resolved libraryItems */
63
+ /** latest libraryItems */
88
64
  private lastLibraryItems;
65
+ /** indicates whether library is initialized with library items (has gone
66
+ * though at least one update) */
67
+ private isInitialized;
89
68
  private app;
90
69
  constructor(app: App);
91
- resetLibrary: () => Promise<void>;
92
- /** imports library (currently merges, removing duplicates) */
93
- importLibrary(library: Blob | Required<ImportedDataState>["libraryItems"] | Promise<Required<ImportedDataState>["libraryItems"]>, defaultStatus?: LibraryItem["status"]): Promise<void>;
94
- loadLibrary: () => Promise<LibraryItems>;
95
- saveLibrary: (items: LibraryItems | Promise<LibraryItems>) => Promise<void>;
70
+ private updateQueue;
71
+ private getLastUpdateTask;
72
+ private notifyListeners;
73
+ resetLibrary: () => Promise<LibraryItems>;
74
+ /**
75
+ * @returns latest cloned libraryItems. Awaits all in-progress updates first.
76
+ */
77
+ getLatestLibrary: () => Promise<LibraryItems>;
78
+ updateLibrary: ({ libraryItems, prompt, merge, openLibraryMenu, defaultStatus, }: {
79
+ libraryItems: LibraryItemsSource;
80
+ merge?: boolean | undefined;
81
+ prompt?: boolean | undefined;
82
+ openLibraryMenu?: boolean | undefined;
83
+ defaultStatus?: "published" | "unpublished" | undefined;
84
+ }) => Promise<LibraryItems>;
85
+ setLibrary: (libraryItems: LibraryItems | Promise<LibraryItems> | ((latestLibraryItems: LibraryItems) => LibraryItems | Promise<LibraryItems>)) => Promise<LibraryItems>;
96
86
  }
97
87
  export default Library;
88
+ export declare const distributeLibraryItemsOnSquareGrid: (libraryItems: LibraryItems) => ExcalidrawElement[];
89
+ export declare const parseLibraryTokensFromUrl: () => {
90
+ libraryUrl: string;
91
+ idToken: string | null;
92
+ } | null;
93
+ export declare const useHandleLibrary: ({ excalidrawAPI, getInitialLibraryItems, }: {
94
+ excalidrawAPI: ExcalidrawImperativeAPI | null;
95
+ getInitialLibraryItems?: (() => LibraryItemsSource) | undefined;
96
+ }) => void;
@@ -1,5 +1,5 @@
1
1
  import { ExcalidrawElement } from "../element/types";
2
- import { AppState, BinaryFiles, LibraryItems, LibraryItems_v1 } from "../types";
2
+ import { AppState, BinaryFiles, LibraryItems, LibraryItems_anyVersion } from "../types";
3
3
  import type { cleanAppStateForExport } from "../appState";
4
4
  import { VERSIONS } from "../constants";
5
5
  export interface ExportedDataState {
@@ -17,7 +17,7 @@ export interface ImportedDataState {
17
17
  elements?: readonly ExcalidrawElement[] | null;
18
18
  appState?: Readonly<Partial<AppState>> | null;
19
19
  scrollToContent?: boolean;
20
- libraryItems?: LibraryItems | LibraryItems_v1;
20
+ libraryItems?: LibraryItems_anyVersion;
21
21
  files?: BinaryFiles;
22
22
  }
23
23
  export interface ExportedLibraryData {
@@ -0,0 +1,6 @@
1
+ import { ExcalidrawElement } from "./element/types";
2
+ export interface Distribution {
3
+ space: "between";
4
+ axis: "x" | "y";
5
+ }
6
+ export declare const distributeElements: (selectedElements: ExcalidrawElement[], distribution: Distribution) => ExcalidrawElement[];
@@ -32,7 +32,13 @@ export declare const actionLink: {
32
32
  editingLinearElement: import("./linearElementEditor").LinearElementEditor | null;
33
33
  activeTool: {
34
34
  type: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | "eraser";
35
- lastActiveToolBeforeEraser: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | null;
35
+ lastActiveToolBeforeEraser: import("../types").LastActiveToolBeforeEraser;
36
+ locked: boolean;
37
+ customType: null;
38
+ } | {
39
+ type: "custom";
40
+ customType: string;
41
+ lastActiveToolBeforeEraser: import("../types").LastActiveToolBeforeEraser;
36
42
  locked: boolean;
37
43
  };
38
44
  penMode: boolean;
@@ -86,7 +86,10 @@ export declare class LinearElementEditor {
86
86
  startBindingElement: ExcalidrawBindableElement | "keep" | null;
87
87
  endBindingElement: ExcalidrawBindableElement | "keep" | null;
88
88
  };
89
- isLoading: boolean;
89
+ isLoading: boolean; /**
90
+ * @param id the `elementId` from the instance of this class (so that we can
91
+ * statically guarantee this method returns an ExcalidrawLinearElement)
92
+ */
90
93
  errorMessage: string | null;
91
94
  draggingElement: import("./types").NonDeletedExcalidrawElement | null;
92
95
  resizingElement: import("./types").NonDeletedExcalidrawElement | null;
@@ -98,7 +101,13 @@ export declare class LinearElementEditor {
98
101
  editingElement: import("./types").NonDeletedExcalidrawElement | null;
99
102
  activeTool: {
100
103
  type: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | "eraser";
101
- lastActiveToolBeforeEraser: "line" | "arrow" | "text" | "selection" | "rectangle" | "diamond" | "ellipse" | "image" | "freedraw" | null;
104
+ lastActiveToolBeforeEraser: import("../types").LastActiveToolBeforeEraser;
105
+ locked: boolean;
106
+ customType: null;
107
+ } | {
108
+ type: "custom";
109
+ customType: string;
110
+ lastActiveToolBeforeEraser: import("../types").LastActiveToolBeforeEraser;
102
111
  locked: boolean;
103
112
  };
104
113
  penMode: boolean;
@@ -1,3 +1 @@
1
- declare const _exports: any;
2
- export = _exports;
3
- export var ExcalidrawLib: any;
1
+ export const ExcalidrawLib: {};
@@ -7,12 +7,12 @@ export declare const Excalidraw: React.MemoExoticComponent<React.ForwardRefExoti
7
7
  export { getSceneVersion, isInvisiblySmallElement, getNonDeletedElements, } from "../../element";
8
8
  export { defaultLang, languages } from "../../i18n";
9
9
  export { restore, restoreAppState, restoreElements, restoreLibraryItems, } from "../../data/restore";
10
- export { exportToBlob, exportToCanvas, exportToSvg, serializeAsJSON, serializeLibraryAsJSON, loadLibraryFromBlob, loadFromBlob, getFreeDrawSvgPath, } from "../../packages/utils";
10
+ export { exportToBlob, exportToCanvas, exportToSvg, serializeAsJSON, serializeLibraryAsJSON, loadLibraryFromBlob, loadFromBlob, loadSceneOrLibraryFromBlob, getFreeDrawSvgPath, exportToClipboard, mergeLibraryItems, } from "../../packages/utils";
11
11
  export { isLinearElement } from "../../element/typeChecks";
12
+ export { FONT_FAMILY, THEME, MIME_TYPES } from "../../constants";
12
13
  export { mutateElement, newElementWith, bumpVersion, } from "../../element/mutateElement";
13
- export { FONT_FAMILY, THEME } from "../../constants";
14
- export { exportToClipboard } from "../utils";
15
- export { getDefaultAppState } from "../../appState";
16
- export { cleanAppStateForExport, clearAppStateForLocalStorage, } from "../../appState";
14
+ export { parseLibraryTokensFromUrl, useHandleLibrary, } from "../../data/library";
15
+ export { sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, } from "../../utils";
16
+ export { getDefaultAppState, cleanAppStateForExport, clearAppStateForLocalStorage, } from "../../appState";
17
17
  export { jotaiScope, jotaiStore } from "../../jotai";
18
18
  export { libraryItemsAtom } from "../../data/library";
@@ -1,5 +1,7 @@
1
1
  import { AppState, BinaryFiles } from "../types";
2
2
  import { ExcalidrawElement, NonDeleted } from "../element/types";
3
+ import { MIME_TYPES } from "../constants";
4
+ export { MIME_TYPES };
3
5
  declare type ExportOpts = {
4
6
  elements: readonly NonDeleted<ExcalidrawElement>[];
5
7
  appState?: Partial<Omit<AppState, "offsetTop" | "offsetLeft">>;
@@ -15,14 +17,16 @@ export declare const exportToCanvas: ({ elements, appState, files, maxWidthOrHei
15
17
  export declare const exportToBlob: (opts: ExportOpts & {
16
18
  mimeType?: string;
17
19
  quality?: number;
18
- }) => Promise<Blob | null>;
20
+ }) => Promise<Blob>;
19
21
  export declare const exportToSvg: ({ elements, appState, files, exportPadding, }: Omit<ExportOpts, "getDimensions"> & {
20
22
  exportPadding?: number | undefined;
21
23
  }) => Promise<SVGSVGElement>;
22
- export { serializeAsJSON, serializeLibraryAsJSON } from "../data/json";
23
24
  export declare const exportToClipboard: (opts: ExportOpts & {
24
25
  mimeType?: string;
25
26
  quality?: number;
27
+ type: "png" | "svg" | "json";
26
28
  }) => Promise<void>;
27
- export { loadFromBlob, loadLibraryFromBlob } from "../data/blob";
29
+ export { serializeAsJSON, serializeLibraryAsJSON } from "../data/json";
30
+ export { loadFromBlob, loadSceneOrLibraryFromBlob, loadLibraryFromBlob, } from "../data/blob";
28
31
  export { getFreeDrawSvgPath } from "../renderer/renderElement";
32
+ export { mergeLibraryItems } from "../data/library";
@@ -14,10 +14,9 @@ declare class Scene {
14
14
  private elements;
15
15
  private elementsMap;
16
16
  getElementsIncludingDeleted(): readonly ExcalidrawElement[];
17
- getElements(): readonly NonDeletedExcalidrawElement[];
17
+ getNonDeletedElements(): readonly NonDeletedExcalidrawElement[];
18
18
  getElement<T extends ExcalidrawElement>(id: T["id"]): T | null;
19
19
  getNonDeletedElement(id: ExcalidrawElement["id"]): NonDeleted<ExcalidrawElement> | null;
20
- getNonDeletedElements(ids: readonly ExcalidrawElement["id"][]): NonDeleted<ExcalidrawElement>[];
21
20
  replaceAllElements(nextElements: readonly ExcalidrawElement[]): void;
22
21
  informMutation(): void;
23
22
  addCallback(cb: SceneStateCallback): SceneStateCallbackRemover;
package/types/types.d.ts CHANGED
@@ -29,7 +29,7 @@ export declare type Collaborator = {
29
29
  background: string;
30
30
  stroke: string;
31
31
  };
32
- picture?: string;
32
+ avatarUrl?: string;
33
33
  };
34
34
  export declare type DataURL = string & {
35
35
  _brand: "DataURL";
@@ -42,6 +42,13 @@ export declare type BinaryFileData = {
42
42
  };
43
43
  export declare type BinaryFileMetadata = Omit<BinaryFileData, "dataURL">;
44
44
  export declare type BinaryFiles = Record<ExcalidrawElement["id"], BinaryFileData>;
45
+ export declare type LastActiveToolBeforeEraser = {
46
+ type: typeof SHAPES[number]["value"] | "eraser";
47
+ customType: null;
48
+ } | {
49
+ type: "custom";
50
+ customType: string;
51
+ } | null;
45
52
  export declare type AppState = {
46
53
  isLoading: boolean;
47
54
  errorMessage: string | null;
@@ -56,7 +63,13 @@ export declare type AppState = {
56
63
  editingLinearElement: LinearElementEditor | null;
57
64
  activeTool: {
58
65
  type: typeof SHAPES[number]["value"] | "eraser";
59
- lastActiveToolBeforeEraser: typeof SHAPES[number]["value"] | null;
66
+ lastActiveToolBeforeEraser: LastActiveToolBeforeEraser;
67
+ locked: boolean;
68
+ customType: null;
69
+ } | {
70
+ type: "custom";
71
+ customType: string;
72
+ lastActiveToolBeforeEraser: LastActiveToolBeforeEraser;
60
73
  locked: boolean;
61
74
  };
62
75
  penMode: boolean;
@@ -157,7 +170,7 @@ export declare class GestureEvent extends UIEvent {
157
170
  /** @deprecated legacy: do not use outside of migration paths */
158
171
  export declare type LibraryItem_v1 = readonly NonDeleted<ExcalidrawElement>[];
159
172
  /** @deprecated legacy: do not use outside of migration paths */
160
- export declare type LibraryItems_v1 = readonly LibraryItem_v1[];
173
+ declare type LibraryItems_v1 = readonly LibraryItem_v1[];
161
174
  /** v2 library item */
162
175
  export declare type LibraryItem = {
163
176
  id: string;
@@ -169,6 +182,8 @@ export declare type LibraryItem = {
169
182
  error?: string;
170
183
  };
171
184
  export declare type LibraryItems = readonly LibraryItem[];
185
+ export declare type LibraryItems_anyVersion = LibraryItems | LibraryItems_v1;
186
+ export declare type LibraryItemsSource = ((currentLibraryItems: LibraryItems) => Blob | LibraryItems_anyVersion | Promise<LibraryItems_anyVersion | Blob>) | Blob | LibraryItems_anyVersion | Promise<LibraryItems_anyVersion | Blob>;
172
187
  export declare type ExcalidrawAPIRefValue = ExcalidrawImperativeAPI | {
173
188
  readyPromise?: ResolvablePromise<ExcalidrawImperativeAPI>;
174
189
  ready?: false;
@@ -217,13 +232,14 @@ export interface ExcalidrawProps {
217
232
  onLinkOpen?: (element: NonDeletedExcalidrawElement, event: CustomEvent<{
218
233
  nativeEvent: MouseEvent | React.PointerEvent<HTMLCanvasElement>;
219
234
  }>) => void;
235
+ onPointerDown?: (activeTool: AppState["activeTool"], pointerDownState: PointerDownState) => void;
236
+ onScrollChange?: (scrollX: number, scrollY: number) => void;
220
237
  }
221
238
  export declare type SceneData = {
222
239
  elements?: ImportedDataState["elements"];
223
240
  appState?: ImportedDataState["appState"];
224
241
  collaborators?: Map<string, Collaborator>;
225
242
  commitToHistory?: boolean;
226
- libraryItems?: LibraryItems | LibraryItems_v1;
227
243
  };
228
244
  export declare enum UserIdleState {
229
245
  ACTIVE = "active",
@@ -331,6 +347,7 @@ export declare type PointerDownState = Readonly<{
331
347
  }>;
332
348
  export declare type ExcalidrawImperativeAPI = {
333
349
  updateScene: InstanceType<typeof App>["updateScene"];
350
+ updateLibrary: InstanceType<typeof Library>["updateLibrary"];
334
351
  resetScene: InstanceType<typeof App>["resetScene"];
335
352
  getSceneElementsIncludingDeleted: InstanceType<typeof App>["getSceneElementsIncludingDeleted"];
336
353
  history: {
@@ -341,15 +358,16 @@ export declare type ExcalidrawImperativeAPI = {
341
358
  getAppState: () => InstanceType<typeof App>["state"];
342
359
  getFiles: () => InstanceType<typeof App>["files"];
343
360
  refresh: InstanceType<typeof App>["refresh"];
344
- importLibrary: InstanceType<typeof App>["importLibraryFromUrl"];
345
361
  setToastMessage: InstanceType<typeof App>["setToastMessage"];
346
362
  addFiles: (data: BinaryFileData[]) => void;
347
363
  readyPromise: ResolvablePromise<ExcalidrawImperativeAPI>;
348
364
  ready: true;
349
365
  id: string;
366
+ setActiveTool: InstanceType<typeof App>["setActiveTool"];
350
367
  app: InstanceType<typeof App>;
351
368
  };
352
369
  export declare type DeviceType = {
353
370
  isMobile: boolean;
354
371
  isTouchScreen: boolean;
355
372
  };
373
+ export {};
package/types/utils.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { EVENT } from "./constants";
2
2
  import { FontFamilyValues, FontString } from "./element/types";
3
- import { AppState, Zoom } from "./types";
3
+ import { AppState, LastActiveToolBeforeEraser, Zoom } from "./types";
4
+ import { SHAPES } from "./shapes";
4
5
  export declare const setDateTimeForTests: (dateTime: string) => void;
5
6
  export declare const getDateTime: () => string;
6
7
  export declare const capitalizeString: (str: string) => string;
@@ -29,6 +30,14 @@ export declare const chunk: <T extends unknown>(array: readonly T[], size: numbe
29
30
  export declare const selectNode: (node: Element) => void;
30
31
  export declare const removeSelection: () => void;
31
32
  export declare const distance: (x: number, y: number) => number;
33
+ export declare const updateActiveTool: (appState: Pick<AppState, "activeTool">, data: ({
34
+ type: typeof SHAPES[number]["value"] | "eraser";
35
+ } | {
36
+ type: "custom";
37
+ customType: string;
38
+ }) & {
39
+ lastActiveToolBeforeEraser?: LastActiveToolBeforeEraser;
40
+ }) => AppState["activeTool"];
32
41
  export declare const resetCursor: (canvas: HTMLCanvasElement | null) => void;
33
42
  export declare const setCursor: (canvas: HTMLCanvasElement | null, cursor: string) => void;
34
43
  export declare const setEraserCursor: (canvas: HTMLCanvasElement | null, theme: AppState["theme"]) => void;